An identity's permissions are one versioned config resource: AccessBinding, name = the identity (console: Users → "Permissions…"). Writing one needs system-admin, and for a reason stated plainly: saving a binding rewrites the RBAC tables in the same transaction — writing one is granting authority, and the document and enforcement can never drift.
The semantics you must internalize before granting anything:
- Scopes land in the JWT at the next login — an active session keeps its old scope until it re-authenticates.
- An identity without a binding is unrestricted (
*/*). Permissions tighten declaratively — so in production, give every identity a binding, and audit the ones without (Access binding is defaulton the identity list). - The
interfacesscope short-circuits: a credential granted specific interfaces is decided by the interface — the request must name one it holds, and the template and CA scopes are not consulted. An interface grant can therefore let a credential issue a template that is not in its owntemplateslist. That is the design: you hand a team an interface, and the interface document defines what that means, in one place. Want belt-and-braces? Leaveinterfaces: ["*"]and scope by template and CA.
Now I can grant template access — and say which scope actually decides an enrollment.