Skip to content

Platform Roles & Actions

RoleDescription
platform_adminFull access to all platform operations. Wildcard (*) permission.
platform_operatorTenant management, full impersonation (read + write), read access to users, keys, roles, policies, and the audit log.
platform_viewerRead-only access to all platform resources.

The three built-in platform roles are seeded by migration into org_platform. Custom platform roles can be created — see Platform RBAC.

Built-in platform roles cannot be deleted or renamed via the API. Attempts to do so return 400 cannot delete built-in role / 400 cannot update built-in role and emit a delete_blocked / update_blocked audit event.


ActionDescription
platform:users:readList and view platform users
platform:users:manageCreate, update, and delete platform users
platform:keys:readList and view platform API keys
platform:keys:manageCreate, rotate, and delete platform API keys
platform:roles:readList and view platform roles
platform:roles:manageCreate, update, and delete custom roles
platform:tenants:readList and view tenant organizations
platform:tenants:manageProvision and delete tenant organizations
platform:impersonate:readRead-only impersonation of tenant orgs (endpoints whose RBAC action is a read)
platform:impersonateWrite access to tenant orgs (every other endpoint)
platform:audit:readQuery the platform audit log
platform:policies:readList and view platform policies
platform:policies:manageCreate, update, and delete platform policies

ActionAdminOperatorViewer
platform:users:readYesYesYes
platform:users:manageYes
platform:keys:readYesYesYes
platform:keys:manageYes
platform:roles:readYesYesYes
platform:roles:manageYes
platform:tenants:readYesYesYes
platform:tenants:manageYesYes
platform:impersonate:readYesYesYes
platform:impersonateYesYes
platform:policies:readYesYesYes
platform:policies:manageYes
platform:audit:readYesYesYes

The platform middleware maps HTTP methods and paths to actions:

Path PatternGETPOST/PUT/DELETE
/api/v1/platform/users*platform:users:readplatform:users:manage
/api/v1/apikeys?platform=trueplatform:keys:readplatform:keys:manage
/api/v1/platform/roles*platform:roles:readplatform:roles:manage
/api/v1/platform/policies*platform:policies:readplatform:policies:manage
/api/v1/platform/tenants* (or /api/v1/platform/orgs*)platform:tenants:readplatform:tenants:manage
/api/v1/platform/audit*platform:audit:readplatform:audit:read
/api/v1/platform/auth*(public)(public)
/api/v1/platform/bootstrapn/a(no platform action; requires a tenant admin API key and refuses once any platform user exists)

Notes:

  • Platform API keys are listed/managed through the tenant /api/v1/apikeys route with ?platform=true; the action is selected inline by the apikey handler (platform:keys:read for GET, platform:keys:manage otherwise).
  • The audit path maps to platform:audit:read for any HTTP method. Only GET routes are registered today, so non-GET requests 404 before authz runs.

For impersonation (non-platform endpoints with X-Ironflow-Org header):

EndpointRequired Action
RBAC action is a read (:read, :list, :subscribe)platform:impersonate:read
Any other RBAC actionplatform:impersonate
No RBAC action, and the method is GET, HEAD or OPTIONSplatform:impersonate:read
No RBAC action, any other methodplatform:impersonate

The endpoint’s action decides, not the HTTP method. A ConnectRPC read is a POST and needs only read impersonation; GET /api/v1/export (org:export), GET /api/v1/workers and GET /api/v1/workers/{workerId}/jobs (functions:invoke), and GET /api/v1/debug/requests (orgs:manage) are writes and need the full action.

HEAD is a rough edge: the action map has no HEAD arm, so HEAD on most mapped read routes resolves to that resource’s write action and needs full impersonation. It fails closed, and it affects tenant roles through the same map.


ResourcePrefixExample
Platform userpuser_puser_a1b2c3d4
API key (all types)ak_ak_e5f6g7h8
Role (built-in)role_role_platform_admin
Role (custom platform)prole_prole_a1b2c3d4
Policy (unified)pol_pol_def456
Tenant (organization)org_org_x1y2z3w4
Platform key valueifplatform_ifplatform_a1b2... (43 chars)
Tenant key valueifkey_ifkey_a1b2... (38 chars)