01
Separate sign-in access from application permissions
Access to an application is decided by group membership. Every OIDC client and every SAML service provider has a set of attached groups, and a person may sign in only if they belong to at least one of them. The gate is default-closed in the strict sense: an application with no attached groups admits nobody, so a half-configured application fails safe instead of standing open to everyone.
What that person may then do inside your API is a separate model. A resource server represents one of your APIs and owns an immutable audience string, a permission is an action string belonging to one resource server, a role bundles permissions, and a role reaches a user either directly or through a group.
A third, independent system decides which profile data reaches a token: scopes over a typed attribute schema. Passing the access gate says nothing about which permissions you hold, and holding a permission says nothing about which profile claims are released.
The gate is checked at every stage
Membership is read four times in a single sign-in: at enrollment, again when the phone pulls the payload for the ceremony, again at the code exchange, and again on each refresh afterwards. Take a person out of a group and the next mint is where it lands, not the next expiry.
Use a consistent permission format
Lowercase segments separated by colons, such as read:invoices, with an asterisk allowed only as a whole trailing segment, such as write:billing:*. Values are immutable once created and capped at 200 characters.
Roles may span APIs, tokens do not
A role can bundle permissions from several resource servers, and a token still only carries the permissions for the single API it targets. A broad role therefore stays safe to hand out.
Combine direct and group assignments
A role given to a person directly and a role conferred on one of their groups both count, and the effective set is the union of the two. Managing people in groups and letting roles flow through membership usually scales better.
02
Authorization claims in the token
By default an access token is audienced to your own client and carries no permissions at all. To get a token for one of your APIs, the application requests that resource server's audience, using either the audience parameter or the resource parameter of RFC 8707; if both arrive, the resource form wins.
Two gates apply, and both fail closed. Your application must hold a grant to request that audience at all, and an unknown API is indistinguishable from an ungranted one. The token endpoint is the canonical enforcement point, because the audience rides through the authorize request as a forgeable query parameter and is re-validated at the exchange.
Whether a permissions claim appears at all depends on the resource server's enforcement flag. Turning it off gives you correctly audienced tokens with no permissions, which is what you want when your API does its own authorization but still needs to confirm that a token was meant for it.
An empty array is not the same as no claim
An empty permissions array means the person passed the access gate and holds nothing on that particular API. An absent claim means the resource server does not enforce RBAC at all. Handle the two differently in your code.
Recomputed on every mint, refresh included
Revoke a role or remove a group member and the next access token is smaller. Keep access token lifetimes short and that propagation stays short with them.
Distinguish protocol scope from API permissions
The permissions claim in an end-user token holds your API's action strings. A machine-to-machine token for the Management API also carries a permissions claim, holding console capabilities. Different audience, different vocabulary, different verifier: do not write one validator for both.
03
Who enforces what
SenseCrypt emits permissions and never enforces them. Your API verifies the token against the tenant's key set by kid, checks that the audience equals its own audience string, and authorizes each request against the permissions array. That is the whole contract, and it is the same contract any standards identity provider offers.
There are exactly two places SenseCrypt enforces authorization itself, and naming them stops anyone assuming a third. The first is the sign-in gate. The second is the admin console and Management API, which run a separate capability model of their own, unrelated to the roles you hand your end users, with its own tables and its own enforcement.
Reserved protocol claims are protected in both directions. A tenant administrator cannot define a custom attribute called sub, or scope, or permissions and have it overwrite a server-minted claim: reserved keys are rejected and stripped at the sink. What appears in the protocol claims came from SenseCrypt, not from tenant configuration.
04
Configure roles where you need them
You need this model only if you want SenseCrypt to tell your API what a person may do. If you only need to know who they are and which applications they may reach, the access gate is enough on its own and resource servers can wait until there is a reason for them.
When you do want it, the order is short: create the resource server with its audience, define the permissions your API understands, bundle them into roles, assign roles to people or to groups, then grant your application the right to request that audience. Every step is a console action or a Management API call, so the whole model can live in your infrastructure code.
Every definition in this model is scoped to a single tenant. The word administrator can therefore carry a completely different set of permissions in one customer's tenant than in the next, and no operator in either one can see or alter the other's version of it.
Membership calls replace, they do not merge
The Management API calls that set a role's permissions, a user's roles or an application's APIs each expect the complete desired set. Write automation that computes the whole set rather than a delta.
The audience is immutable
A resource server's audience string is fixed at creation, because it becomes the audience claim your API checks. Choose a URI you will still be content with in three years.
Group conferral scales better than direct assignment
Confer a role on a group and every member inherits it, including the members your directory adds later over SCIM. Direct assignment is for the exceptions.
05
Compare the details
| What your application requested | aud | azp | permissions |
|---|---|---|---|
| No audience, the default | Your client id | Absent | Absent |
| An API audience, RBAC enforcement off | The API audience | Your client id | Absent: audience binding only |
| An API audience, RBAC enforcement on | The API audience | Your client id | The user's effective permissions, possibly an empty array |
No audience, the default
- aud
- Your client id
- azp
- Absent
- permissions
- Absent
An API audience, RBAC enforcement off
- aud
- The API audience
- azp
- Your client id
- permissions
- Absent: audience binding only
An API audience, RBAC enforcement on
- aud
- The API audience
- azp
- Your client id
- permissions
- The user's effective permissions, possibly an empty array
06
Frequently asked questions
Does SenseCrypt enforce our permissions for us?
No. It computes each user's effective permissions for the API you targeted and puts them in the access token. Your API verifies the signature against the tenant's key set, checks that the audience is its own, and authorizes each request against the permissions array. Enforcement stays in the code that owns the data.
What does SenseCrypt enforce, then?
Two things. Sign-in access, through a default-closed group gate re-checked at every stage of the ceremony and on every refresh, and administration of SenseCrypt itself, through a separate console capability model. Everything else is emitted for you to act on.
How fast does a revoked role take effect?
On the next token, including the next refresh, because permissions are recomputed on every mint rather than cached for the life of a session. Short access token lifetimes keep that propagation short in practice.
Can one role cover several of our APIs?
Yes. A role may bundle permissions from more than one resource server, and a token still carries only the permissions for the single API it was audienced to, so a broad role does not over-grant in any individual token.
How do roles behave across tenants?
They do not cross. Roles, permissions, resource servers and groups each belong to exactly one tenant, so an administrator in one customer's tenant has no way to define or confer anything that takes effect in a different customer's tenant.
Where do group memberships come from?
From your directory over SCIM 2.0, from the admin console, or both. Groups provisioned over SCIM are read-only in the console so the directory stays the source of truth, and they gate sign-in and confer roles exactly like any other group.