[Platform API] Authorization Design M2: User configurable role definition and scope assignment #2136
Thushani-Jayasekera
started this conversation in
General
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Continue discussion : #2045 [1]
The current design supports two validation modes — scope and role — controlled via AUTH_IDP_VALIDATION_MODE. The scope mode is the default and is fully implemented. The role mode (deferred to post-M1) handles IDPs that issue role names in the token rather than fine-grained OAuth2 scopes.
This discussion addresses the design of that role mode: specifically, how operators configure the mapping between IDP roles and platform scopes, and what trade-offs exist between the proposed approaches.
Problem Statement
Not all IDPs issue tokens with a scope claim. Some enterprise IDPs — Keycloak being a common example — issue roles (realm_access.roles) rather than OAuth2 scopes. Others may support scopes but only populate them with coarse-grained role strings due to SSO constraints or organizational policy.
When this happens, the platform needs a way to derive the effective permission set from whatever the IDP puts in the token.
There are two points of configurability needed:
Multi-tenancy Constraint
As established in #2045, the platform supports only a single IDP per deployment. B2B / sub-organisation multi-tenancy is handled via the IDP's own organisation features (e.g. Asgardeo organisations). This means role definitions are inherently platform-wide (root org level), not per-tenant.
A single role config file is therefore the right scope there is no need for per-tenant role overrides at this layer.
Design Options
Option A: Hard coded role to scope mappings
The IDP role is mapped to one of five built-in platform roles (admin, developer, publisher, operator, viewer), each with a fixed, hardcoded permission set.
Pros:
Zero config files; easy to pass in via Kubernetes secrets or env injection
Forces operators into a well-understood, tested permission model
Cons:
The built-in roles are opinionated — operators may not agree with the bundled scope sets
No way to define a custom role (e.g. billing-admin that only touches subscription scopes)
Scope sets can only change with a platform release, not an operator config change
Key-value string is error-prone and doesn't scale beyond a few mappings
Option B: Role config file with direct scope assignment (proposed)
roles.yaml
AUTH_IDP_ROLES_CONFIG_PATH=/etc/platform/roles.yamlEach entry names a role as it appears in the IDP token and directly lists the platform scopes it grants. At request time, the middleware takes the union of all scopes across all roles present in the token.
Pros:
Fully operator-defined — no coupling to built-in role semantics
Works naturally for IDPs that have more or fewer than five roles
The YAML format scales and is reviewable/auditable in version control
Roles that carry no matching definition grant no scopes but don't reject the request — graceful degradation
Cons:
Operators must know the full scope vocabulary (mitigated by published scope reference)
Config errors (typos in scope names) silently grant no access rather than failing loudly — needs validation at startup with clear error output
More operator burden than the simple env-var mapping
Option C: Named platform roles + override file (hybrid)
The built-in platform roles remain as defaults. Operators can optionally provide a config file that either maps IDP roles to platform roles or maps IDP roles directly to scopes, with the file taking precedence.
Pros:
Operators who are happy with the built-in roles get a simple mapping (just like the env-var approach, but in YAML)
Operators who need custom roles can define them inline in the same file
Built-in roles remain a safe default and a useful reference
Cons:
Two modes of role definition in one file adds conceptual overhead
Built-in role scope sets still need to be published and kept in sync with actual platform scopes — the mapping is only as good as the platform role definition underneath it
Recommendation
Option B is the right long-term design, with one addition borrowed from Option C: ship a reference roles.yaml that encodes the five built-in platform roles as a starting point operators can copy and customise.
Behaviour Specifics
Scope union across roles. If a token carries multiple roles, the effective scope set is the union of all scopes granted by each role. A role with no matching definition in the config contributes nothing but does not cause the request to fail.
No hot-reload. Role config changes take effect on the next server restart. Operators should treat a role config change the same as any other configuration change: deploy it, restart.
Unknown scope names. The platform should validate all scope strings in the config against its own known scope registry at startup and refuse to start if any are unrecognised. This prevents a class of misconfiguration bugs where an operator believes a role grants access that it doesn't.
Beta Was this translation helpful? Give feedback.
All reactions