Background & Problem
Cello has roles, but does not use them for authorization.
src/api-engine/user/models.py already defines Role.ADMIN / Role.USER and the is_admin / is_common_user properties — but they are never used anywhere in the codebase.
- Every business ViewSet sets
permission_classes to just [IsAuthenticated], with no role-based checks at all.
As a result, any logged-in user can perform operations that should be admin-only. Confirmed privilege-escalation examples:
- Any authenticated user can delete any organization —
destroy in organization/views.py calls Organization.objects.get(id=pk).delete() directly, checking neither role nor ownership.
- The organization list / detail endpoints have no tenant isolation (
Organization.objects.all(), lookup by arbitrary pk).
Goal
Make role actually participate in authorization. Core principle: Organization = resource boundary, Role = operation permissions — keep the two checks separate.
- High-risk operations (create/delete users, delete organization, create/delete nodes, install/approve/commit chaincode, etc.) should be restricted to
ADMIN; USER should default to read-only or limited access.
- Start with the existing two roles
ADMIN / USER, then extend as needed with OPERATOR (ops: manage nodes/channels/chaincode) and VIEWER (read-only).
Background & Problem
Cello has roles, but does not use them for authorization.
src/api-engine/user/models.pyalready definesRole.ADMIN/Role.USERand theis_admin/is_common_userproperties — but they are never used anywhere in the codebase.permission_classesto just[IsAuthenticated], with no role-based checks at all.As a result, any logged-in user can perform operations that should be admin-only. Confirmed privilege-escalation examples:
destroyinorganization/views.pycallsOrganization.objects.get(id=pk).delete()directly, checking neither role nor ownership.Organization.objects.all(), lookup by arbitrarypk).Goal
Make
roleactually participate in authorization. Core principle:Organization= resource boundary,Role= operation permissions — keep the two checks separate.ADMIN;USERshould default to read-only or limited access.ADMIN/USER, then extend as needed withOPERATOR(ops: manage nodes/channels/chaincode) andVIEWER(read-only).