Tutorials›Operating Systems
Core CS

Capabilities

A capability in an operating system is an unforgeable, communicable token or ticket that grants a process specific access rights to a resource (such as a file, memory segment, or device). Instead of checking a central list to see if a user has permission (as in Access Control Lists), the OS simply checks whether the process holds the valid "ticket" for that resource, much like presenting a physical key to unlock a specific door.

<h3>Definition</h3><h2><!--StartFragment--><p>In operating system security, a <b>capability</b> is a secure pointer or descriptor that pairs an object's reference with a specific set of operations allowed on that object (such as <code data-path-to-node="4" data-index-in-node="176">read</code>, <code data-path-to-node="4" data-index-in-node="182">write</code>, or <code data-path-to-node="4" data-index-in-node="192">execute</code>).</p><p>A process can only access a resource if it holds a capability for it. To prevent tampering, capabilities are either maintained directly within kernel memory (and referenced by userspace using handles, similar to Unix file descriptors) or protected cryptographically so user programs cannot forge or alter their permissions.</p></h2><h3>Key Points</h3><h2><ul><li><p><b>Unforgeable Token:</b> Processes cannot fabricate or modify capabilities; only the operating system kernel can create or adjust them.</p></li><li><p><b>Possession-Based Access:</b> Authorization depends on <i>what token you hold</i>, not <i>who you are</i> (identity).</p></li><li><p><b>Transferable:</b> A process can pass a capability (or a restricted copy of it) to another process to delegate access.</p></li><li><p><b>Row-Based Access Matrix:</b> In the classic OS protection matrix (Domains × Objects), Access Control Lists represent columns (attached to objects), whereas capabilities represent rows (held by domains/processes).</p></li></ul></h2><h3>Significance</h3><h2><ul><li><p><b>Enforces the Principle of Least Privilege:</b> Programs can be granted the absolute minimum set of capabilities needed to execute, reducing the attack surface.</p></li><li><p><b>Solves the "Confused Deputy" Problem:</b> In traditional systems, a privileged service (deputy) might be tricked by a malicious user into misusing its broad identity-based permissions. With capabilities, the user must explicitly pass the specific capability along with the request, preventing the service from acting on permissions it wasn't handed.</p></li><li><p><b>Fine-Grained Sandboxing:</b> Provides the foundation for microkernels (like seL4) and modern browser sandboxes (such as Capsicum in FreeBSD or Web Assembly capabilities), allowing secure isolation of untrusted code.</p></li></ul></h2><h3>Advantages</h3><h2><ul><li><p><b>Fast Permission Checks:</b> The kernel verifies the token held by the caller directly, avoiding costly lookups across large identity-based access tables.</p></li><li><p><b>Flexible Delegation:</b> A process can create a child process and share an exact subset of its permissions without requiring root/administrative intervention.</p></li><li><p><b>Dynamic Access Control:</b> Rights can be created, partitioned, and destroyed on the fly as execution states change.</p></li><li><p><b>No Ambient Authority:</b> A process cannot accidentally perform unauthorized actions simply because the logged-in user has high system privileges.</p></li></ul></h2><h3>Disadvantages</h3><h2><ul><li><p><b>Difficult Revocation:</b> Once a capability is passed to multiple processes, cancelling access is complex because the kernel must track or invalidate all distributed copies.</p></li><li><p><b>State &amp; Memory Overhead:</b> Tracking capability tables for many running processes increases memory consumption in the kernel.</p></li><li><p><b>Complex Implementation:</b> Designing a pure capability-based OS requires rethinking common file systems, IPC, and standard API semantics (e.g., standard POSIX APIs assume identity-based permissions).</p></li><li><p><b>Confinement Issues:</b> It is challenging to strictly prevent a process from leaking a capability to an unauthorized third-party process without additional policy layers.</p></li></ul></h2>