6 Capability-Based Access Control
Unforgeable Tokens of Authority, Permission Flags, Delegation, and Revocation
capability-based access control, object capability, permission flags, capability bitmask, delegation, confused deputy, least authority, IoT authorization
6.2 Practitioner: Represent, Compose, and Choose
In practice, fine-grained rights are often represented as permission flags – independent bits, each standing for one capability such as read, write, execute, or audit. A composite “role-like” set is just several flags combined, and an access check confirms that all required bits are present, not merely some. The appeal is precision: you grant exactly the rights needed and nothing more, and on a constrained device the whole set fits in a couple of bytes.
6.2.1 Base, Ceiling, and Elevation
A robust design distinguishes a user’s or device’s base capabilities, granted by default, from its maximum capabilities, an absolute ceiling it can never exceed even when temporarily elevated. A canElevate flag controls whether elevation is allowed at all. When a sensitive action is needed – an emergency shutdown, a firmware write – the holder elevates specific capabilities for a short, time-boxed window, gated by extra authorization such as a supervisor’s approval. This is cleaner than swapping roles or minting a temporary admin account, because the audit trail shows exactly which extra rights were used, when, and under whose approval.
Shelly’s Access Ledger
- Who: the holder elevating specific capabilities for a short, time-boxed window.
- What: elevation can never exceed the maximum ceiling, even temporarily.
- Proof: the audit trail names exactly which extra rights were used and who approved them.
6.2.2 Choosing Among RBAC, Capabilities, and ABAC
| Model | Best When | Strength | Watch Out For |
|---|---|---|---|
| RBAC | Stable job categories with a small number of roles. | Simple to set up, reason about, and audit. | Role explosion when cases need many narrow roles. |
| Capability-based | Per-object custom rights, delegation, or tight memory. | Precise least authority; cheap flags; decentralized sharing. | Revocation of tokens already handed out. |
| ABAC | Decisions depend on context (time, location, state). | Expressive, policy-as-code, scales by attribute. | More complex to author and evaluate. |
6.2.3 Worked Example: Shift Reassignment Without Role Explosion
Picture an industrial control room where operators rotate across shifts and certification levels. With pure RBAC, every combination tends to spawn its own role – a day-shift level-three role, a night-shift level-three role, and so on – until the role list is unmanageable. With capabilities, you instead edit a single operator’s granted rights when their shift or certification changes, leaving the resource definitions untouched. The most sensitive action, an emergency shutdown, sits at the operator’s ceiling and is reachable only by elevation that requires a second person’s approval. The capability model captures “who may do exactly what, right now” without a combinatorial role table.
6.2.4 Capabilities in the Physical World
Digital vehicle keys are a familiar illustration. A shared or valet key is an attenuated capability: it can drive and park but cannot open the trunk or exceed a set speed, while the owner’s key carries the full set. The reason such systems must be built carefully is instructive: early keyless-entry systems relied on weak proprietary ciphers that security researchers were able to clone, which is exactly why a modern capability must be cryptographically strong as well as fine-grained. A capability that can be forged or copied is no capability at all.
6.2.5 Practitioner Knowledge Check
If you can represent rights as flags, gate elevation by a ceiling, and choose the model by need, you can stop here. Continue to Under the Hood for unforgeability, delegation, and the revocation trade-off.
6.3 Under the Hood: Unforgeability, Delegation, and Revocation
The deeper layer explains what makes a capability actually work and where the model breaks. Two properties carry the whole design: the token must be impossible to forge, and the system must have an answer for taking authority back.
6.3.1 The Bit Mechanics
When capabilities are represented as flags, each permission is an independent bit position, not a step in a ladder – setting the fourth bit does not imply the first three. Composite sets are built by OR-ing flags together. An access check is conjunctive: the granted set must contain every required bit, which is the bitwise test (granted & required) == required. This compactness is why the model fits microcontrollers, where a full permission set is a single small integer.
Shelly’s Access Ledger
- Who: whoever holds the granted bitmask presents it for every check.
- What: flags are independent bits, not a ladder – the fourth bit implies nothing about the first three.
- Proof: the check is conjunctive – every required bit must be present, not just one.
6.3.2 Unforgeability Is the Whole Game
Because possession grants authority, a capability is only safe if an untrusted holder cannot forge or alter it. There are two established ways to guarantee that. The first is a protected reference, where the runtime or kernel hands out and mediates the token so it can never be fabricated – Unix file descriptors and capability-based kernels such as seL4 work this way, and a process can pass a descriptor to another process as a genuine delegation. The second is a cryptographic token, where the capability is signed or authenticated (for example a macaroon or a pre-signed, time-limited URL) so the issuer can verify it was neither forged nor tampered with. A capability that is merely a plain string of flags, with nothing protecting it, is forgeable and therefore worthless.
6.3.3 Where the Rights Live, and the Revocation Trade-Off
A central design question is whether the rights travel with the client or stay on the server. If you place the permission flags in a client-held token, that token must be cryptographically signed – otherwise the client edits its own permissions – and even then it remains valid until it expires, so revoking it early requires extra server-side state such as a denylist or an introspection call. If instead you hand the client only an opaque reference (a session identifier) and keep the rights server-side, revocation becomes instant on the next request, but you have moved back toward an access-control-list lookup keyed by identity. This is the honest reading of the common warning against putting permission flags in client tokens: the issue is not that holder-borne authority is wrong – that is the essence of capabilities – but that bearer tokens must be unforgeable and are hard to revoke. Choose short lifetimes plus a revocation list when authority lives client-side; choose server-side rights when you need instant revocation.
6.3.5 Audit as Categorized Events
A capability system should record categorized audit events – access attempted versus granted, elevation requested, and denials – rather than flat log lines. Categorized events let monitoring raise alerts automatically (a burst of denied elevations is a probing signal) and make compliance forensics tractable.
6.3.6 Mechanisms and Failure Modes
| Mechanism | What It Guarantees | Evidence to Request | Failure Mode If Weak |
|---|---|---|---|
| Unforgeable token | Holders cannot fabricate authority. | Kernel-protected references or signed tokens. | Plain flag strings let a client forge permissions. |
| Conjunctive check | All required rights must be present. | A bitwise all-bits-match test, tested with negatives. | An any-bit match grants access on a partial right. |
| Attenuated delegation | Shared authority is never wider than the original. | Delegation that can only narrow, never widen, rights. | Unbounded delegation escalates privilege. |
| Revocation state | Authority can be withdrawn before expiry. | Short lifetimes plus a denylist, or server-side rights. | A bearer token stays valid until it expires. |
| Least ambient authority | Programs hold only the authority they were given. | Narrow explicit grants, no broad inherited capabilities. | Over-broad inherited rights enable confused-deputy abuse. |
6.3.7 Common Pitfalls
- Unsigned capability flags in client tokens. If the token is not cryptographically protected, the client simply forges its own rights.
- Assuming bearer tokens revoke instantly. A signed client-held capability lives until expiry unless you add a denylist or introspection.
- Over-broad ambient authority. Capabilities like near-root system privileges should never be inherited by default.
- Treating flags as a hierarchy. Bits are independent; one capability does not imply the ones below it.
- No revocation path at all. Without revocation, a capability system can be weaker than a simple list it could otherwise improve on.
6.3.8 Under-the-Hood Knowledge Check
At this depth, a capability is a precise, held authority that is only as good as its unforgeability and its revocation story. Represent rights as independent flags, protect the token by the runtime or by cryptography, delegate by narrowing, and decide deliberately whether authority lives with the client or the server. A trustworthy review checks that forged tokens are rejected, that delegation cannot widen rights, and that revocation actually works.
6.4 Summary
- A capability is an unforgeable, held token that designates a specific object and the operations allowed on it; possession is the permission, in contrast to an access-control list checked against identity.
- Fine-grained rights are commonly represented as independent permission flags, composed with bitwise OR and checked conjunctively so that all required bits must be present.
- Separate base capabilities from a maximum ceiling, and grant sensitive rights only through short, time-boxed elevation with extra authorization, which keeps a clean audit trail.
- Choose capabilities for per-object custom rights, delegation, and constrained memory; choose RBAC for stable categories and ABAC for context-dependent decisions.
- Unforgeability is essential: protect capabilities either as runtime or kernel-mediated references (like file descriptors) or as signed cryptographic tokens (like macaroons); plain flag strings are forgeable.
- The revocation trade-off is central: client-held signed capabilities stay valid until expiry unless you add a denylist or introspection, while server-side rights revoke instantly but resemble an ACL lookup.
- Capabilities support attenuated delegation and resist the confused-deputy problem, but over-broad ambient (inherited) authority undermines least authority.
- The fabricated metrics sometimes attached to vehicle examples are unnecessary; the durable lesson is that a capability must be cryptographically strong and fine-grained, since a forgeable capability is worthless.
6.5 Key Takeaway
Capability-based access control puts precise, least authority in the holder’s hands as an unforgeable token. Make the token impossible to forge, let delegation only narrow rights, and decide up front where authority lives: client-side for decentralized sharing with short lifetimes and a denylist, or server-side when you need instant revocation. A capability you cannot protect or revoke is not access control.
6.6 See Also
- Access Control for IoT: Compare capabilities with the RBAC, ABAC, and OAuth models and the least-privilege principle.
- Advanced Access Control: See capability flags put to work in sessions, token lifecycle, and privilege elevation.
- Auth & Authorization Basics: Ground the model in identity, authentication, authorization, and accounting.