Two layers, and they are not the same
The other layer is connection scopes, enforced by your Worker rather than by us — the credential model explains why that separation exists. Organizations and teams is where a role is assigned, and the audit trail is where its use shows up.
Roles in the dashboard decide what a member of your organization may do in the UI.
Scopes on the connection decide what the credential may do against your Worker.
Scopes name operations, not people
A credential that may read purchases cannot revoke an entitlement unless separately scoped, and anything unscoped is denied.
Matching is exact. No prefix rule, no wildcard — payments:entitlements does not confer payments:entitlements:revoke.
Two checks, against two different things
The connection row records what you granted.
The token carries the single scope the current call needs — not the whole grant.
Both must agree, which is why one call is never as dangerous as the most dangerous one you allowed.
Grant and revoke are two scopes for a reason
They have different blast radii.
Grant mints paid product out of nothing. Revoke takes paid access from a live customer.
A refund tool needs revoke and never grant. One admin flag would make each of them the other.
The three that are worth withholding deliberately
audit:events:read_detail — IP, user-agent and metadata one event at a time is a forensic read; the same fields across a hundred rows is bulk harvesting.
secrets:status:read — the list of which credentials a project holds, which are stale, and which no automation will ever rotate is a map of where to push. You must be able to grant a users pane without also granting that.
secrets:rotate — separate again, because matching is exact and a rotation behind the status scope would have handed credential replacement to everybody who ever wanted a status pane, retroactively and without being asked.
What no scope can grant
Reading a secret’s value. There is no route that does and no scope that could.
The reason a secret is encrypted under a key only your Worker holds is that no third party has a path to the plaintext — and a route here would be that path in every deployment, whether or not anybody granted it.
Impersonating a user. The most dangerous administrative capability there is, and it gets its own design and security review rather than riding in on a batch.
Writing to a balance ledger. Read-only, permanently.
Erasing an audit row. A credential that could would be able to erase the evidence of its own use.
Every administrative action is audited
In your trail, under the control-plane actor kind, carrying the connection id and the dashboard user’s own subject — so a shared team credential still distinguishes who acted.