Every application has an allowlist of scopes it's permitted to request. When the application asks /oauth2/authorize for openid profile email users:read, the platform checks each scope against the allowlist. Scopes outside the list are dropped (or refused, depending on policy).
The allowlist is your line of defence against an application requesting capabilities it shouldn't have — whether intentionally (developer mistake) or compromised (attacker controls the app's source).
Where to set it
Section titled “Where to set it”Application detail → Access tab → Capabilities → Allowed scopes.
The form shows two columns: scopes available in this tenant on the left; scopes currently allowed for this application on the right. Drag, select-and-arrow, or type the scope name; save.
What to put on the list
Section titled “What to put on the list”For each application, ask: what does this app's real work involve?
A typical browser SPA:
openid (always include — required for OIDC)profile (the user's name, picture)email (the user's email + email_verified)offline_access (silent refresh — almost always desired for browser apps)A typical backend API consumer (M2M):
users:readapplications:readaudit:readA specific admin tool:
users:readusers:writegroups:readgroups:writeDon't grant users:write to an application that only reads. Don't grant audit:read to an application that has nothing to do with audit. The least-privilege instinct is what makes the allowlist worth maintaining.
What "requests outside the list" actually does
Section titled “What "requests outside the list" actually does”When the OAuth flow includes a scope that's not on the allowlist:
- Strict mode (default) — the platform refuses with
invalid_scope. The user sees a sign-in error. - Permissive mode — the platform silently drops the disallowed scopes and issues a token with the rest. The application gets through but with less than it asked for.
Strict mode catches developer mistakes early. Permissive mode is forgiving but lets attacks fail silently. Default to strict.
Tenant-level scope registry
Section titled “Tenant-level scope registry”The available scopes in your tenant are defined in Roles & scopes → Scope reference. Standard OIDC scopes (openid, profile, email, offline_access) ship by default; IntelliAuth-API scopes are pre-registered (users:read, users:write, etc.). You can add custom scopes for your own APIs.
A custom scope you add to the tenant doesn't automatically appear on any application's allowlist — you have to grant it explicitly. This is by design.
When to use which scope
Section titled “When to use which scope”Conventions across the standard set:
openid— required for any OIDC flow. Always include.profile— name, given_name, family_name, picture. Most apps want this.email— email + email_verified. Most apps want this.offline_access— request a refresh token alongside the access token. Browser apps + native apps need this; pure M2M doesn't (M2M just re-requests).me:read— the signed-in user reads their own profile.me:write— the signed-in user updates their own profile, manages MFA, etc.users:read— admin-level read of any user record.users:write— admin-level write.applications:read— admin-level read of application configs.applications:write— admin-level write (including secret rotation).audit:read— admin-level read of the audit log.groups:read/groups:write— group management.resources:read/resources:write— ReBAC surface management.
Don't ship *:write if *:read would do.
Custom scopes for your own APIs
Section titled “Custom scopes for your own APIs”If your tenant has its own APIs (your backend behind https://api.cymmetri.com), you'll define custom scopes there:
payments:readpayments:approveinventory:readinventory:writeanalytics:exportRegister them in Roles & scopes → Scope reference → New scope. Once defined, grant them to the applications that legitimately need them.
Convention: <resource>:<verb>. Conventions are stronger if your team picks one and applies it everywhere — the platform doesn't enforce a specific shape.
Auditing scope usage
Section titled “Auditing scope usage”Audit log records every token issuance with the granted scopes. To find "which applications are requesting users:write", filter audit on oauth.token_issued and grep on the granted scopes.
This is how you find applications that no longer need a scope they're granted — clean candidates for tightening the allowlist.