Loading learning content...
In traditional access control systems, when a process wants to access a resource, the operating system asks a fundamental question: "Is this subject allowed to access this object?" The answer is typically determined by consulting an Access Control List (ACL) attached to the object. But what if we inverted this model entirely?\n\nInstead of objects knowing who can access them, what if subjects carried unforgeable tokens that directly granted them access rights? This is the essence of capability-based security—a profound reimagining of how operating systems protect resources.\n\nThe concept might seem subtle at first, but the implications are transformative: capabilities enable fine-grained, transferable access rights; they simplify the enforcement of the principle of least privilege; and they provide a foundation for secure, modular system design that has influenced everything from microkernels to web browsers.
By the end of this page, you will understand what capabilities are, how they differ fundamentally from ACL-based access control, the anatomy of a capability token, the distinction between hardware and software capability implementations, and why this concept remains influential in modern security architectures.
The capability concept emerged from some of the most intellectually rigorous research in computer science history. Understanding this heritage illuminates why capabilities matter and how they were designed to solve fundamental security problems.\n\nThe Capability Concept's Genesis (1966)\n\nThe term "capability" was coined by Jack Dennis and Earl Van Horn in their seminal 1966 paper "Programming Semantics for Multiprogrammed Computations." They were grappling with how to provide protected access to shared resources in multiprogrammed systems—computers that could run multiple programs concurrently.\n\nTheir insight was profound: rather than having the operating system maintain complex tables mapping subjects to objects, why not give each subject unforgeable tokens that directly embody access rights? A capability would be like a physical key—possessing it grants access, and you don't need to consult a central authority each time you use it.
Think of capabilities like physical keys to a building. When you possess a key, you can unlock the corresponding door—no guard needs to check your identity against a list. You can also give the key to someone else, enabling them to access the door. The key itself is the authorization.
Influential Capability Systems\n\nFollowing Dennis and Van Horn's work, several pioneering systems implemented capability-based security:\n\n- CAL-TSS (1968) at UC Berkeley was one of the first operating systems to implement software capabilities.\n\n- Hydra (1974) at Carnegie Mellon refined capability semantics, introducing the idea of "rights amplification" for controlled privilege escalation.\n\n- CAP Computer (1970s) at Cambridge University implemented capabilities directly in hardware, proving that the concept could be enforced at the processor level.\n\n- KeyKOS (1985) and its successor EROS (Extremely Reliable Operating System) demonstrated that pure capability systems could be both secure and practical.\n\n- seL4 (2009) became the world's first formally verified microkernel, using a capability-based access control model and mathematically proving its security properties.
| Era | System | Key Contribution | Legacy |
|---|---|---|---|
| 1966 | Dennis & Van Horn Paper | Defined capability concept formally | Theoretical foundation |
| 1968 | CAL-TSS | First software capability OS | Proved feasibility |
| 1974 | Hydra | Rights amplification, capability refinement | Influenced OS research |
| 1970s | CAP Computer | Hardware capability enforcement | Hardware security roots |
| 1985 | KeyKOS | Persistent capabilities | Commercial viability |
| 1999 | EROS | Pure capability semantics | Research refinement |
| 2009 | seL4 | Formally verified capability kernel | Modern gold standard |
| 2010s+ | CHERI (Cambridge) | Capability hardware (ARM/RISC-V) | Memory safety revival |
Capabilities are experiencing a renaissance. The CHERI project (Capability Hardware Enhanced RISC Instructions) is bringing hardware capability support to mainstream processors, addressing memory safety vulnerabilities that have plagued computing for decades. ARM's experimental Morello processor implements CHERI, potentially influencing the future of all computing.
A capability is a protected, unforgeable token that uniquely identifies an object and specifies the access rights that the holder has to that object. Let us dissect this definition carefully, as each component is essential.\n\nThe Three Essential Properties\n\nA true capability must satisfy three fundamental properties:\n\n1. Designation: A capability uniquely identifies (designates) a specific object. When you present a capability, the system knows exactly which object you're referring to—there is no ambiguity.\n\n2. Authorization: A capability specifies what operations the holder may perform on the designated object. These rights are encoded within the capability itself.\n\n3. Unforgeability: A capability cannot be created, modified, or forged by user-level processes. If you don't legitimately possess a capability, you cannot fabricate one.
Without unforgeability, capability-based security collapses entirely. If a process can fabricate a capability, it can grant itself arbitrary access rights. This is why capability enforcement requires either hardware support (protected memory regions, tagged architectures) or careful software isolation (capability-secure languages, sealed objects).
Formal Representation\n\nMathematically, we can represent a capability as a tuple:\n\n\nCapability = ⟨ObjectIdentifier, AccessRights⟩\n\n\nWhere:\n- ObjectIdentifier uniquely identifies the protected resource (file, memory region, hardware device, communication port, etc.)\n- AccessRights is a set of permitted operations (read, write, execute, delete, grant, revoke, etc.)\n\nThe critical constraint is that this tuple exists in protected space—memory or storage that user-level code cannot directly access or modify.
1234567891011121314151617181920212223242526272829
// Conceptual representation of a capability structure// In real systems, this would be protected by hardware/kernel typedef struct { // Object identifier - uniquely designates the protected object uint64_t object_id; // Unique identifier for the object void* object_pointer; // Direct reference to object (kernel space) // Access rights - bitfield of permitted operations uint32_t rights; #define CAP_READ (1 << 0) // Can read object contents #define CAP_WRITE (1 << 1) // Can modify object contents #define CAP_EXECUTE (1 << 2) // Can execute object (if executable) #define CAP_DELETE (1 << 3) // Can delete object #define CAP_GRANT (1 << 4) // Can create derived capabilities #define CAP_REVOKE (1 << 5) // Can revoke derived capabilities #define CAP_OWNER (1 << 6) // Full control including rights modification // Metadata for capability management uint64_t generation; // For revocation (generational approach) uint32_t flags; // Additional properties #define CAP_FLAG_WEAK (1 << 0) // Weak capability (doesn't prevent GC) #define CAP_FLAG_TEMPORAL (1 << 1) // Time-limited validity } Capability; // Key insight: User code NEVER directly accesses this structure.// It only holds opaque handles (indices, encrypted tokens, etc.)// The kernel maintains the actual capability table.The Designation vs. Authorization Unification\n\nOne of the most elegant aspects of capabilities is that they unify naming and authorization into a single concept. In traditional systems, you first name an object (e.g., /etc/passwd) and then separately check if you have permission. With capabilities, possessing the capability is the permission—there is no separate access check.\n\nThis unification has profound security implications:\n\n- No confused deputy problem: When a program acts on behalf of a user, it uses the capabilities it was given, not its own ambient authority.\n- No TOCTOU vulnerabilities: The capability designates a specific object binding; there's no race between checking access and using the object.\n- Simplified security reasoning: If you can name an object, you can access it. If you can't access it, you can't even name it.
While the formal definition tells us what a capability means, understanding its concrete structure reveals how it works in practice. A capability typically consists of several components that work together to provide secure, efficient access control.\n\nCore Components
Object Reference Mechanisms\n\nHow a capability "points to" its object is a critical design decision with significant implications for security and performance:\n\nDirect Pointers (Tagged Architectures)\n\nIn hardware capability systems like CHERI, a capability literally contains a pointer to the object, along with bounds information that limits what memory can be accessed through that pointer. The hardware enforces that:\n- Pointers can only be derived from existing capabilities\n- Pointer arithmetic cannot expand bounds beyond the original capability\n- Capabilities cannot be forged from integers\n\nThis provides memory safety at the hardware level—buffer overflows become impossible because pointers carry their bounds.\n\nIndirect References (Object Tables)\n\nIn software capability systems, capabilities often contain an index into a kernel-maintained object table. User code sees only the index (an opaque handle); the kernel translates this to the actual object reference when servicing capability operations.\n\nCryptographic Tokens\n\nSome systems use cryptographic MACs or encrypted tokens as capabilities. The capability is validated by verifying its cryptographic integrity. This approach is common in distributed systems where capabilities must be transmitted between machines.
1234567891011121314151617181920212223242526272829303132
// Three different approaches to capability representation // Approach 1: Hardware Tagged Capability (CHERI-style)// The capability IS a fat pointer with hardware-enforced propertiestypedef struct __capability { void* __attribute__((capability)) pointer; // Hardware implicitly tracks: // - Base address (lower bound of valid access) // - Length (upper bound of valid access) // - Permissions (read, write, execute, etc.) // - Object type // - Validity tag (1 bit, cannot be directly set)} HardwareCapability; // Approach 2: Kernel Object Table Index (seL4-style)typedef struct { uint32_t slot_index; // Index into caller's capability space // The actual object pointer and rights are stored // in the kernel's CSpace (capability space) data structures // User code cannot access or modify these directly} KernelCapabilityHandle; // Approach 3: Cryptographic Token (distributed systems)typedef struct { uint64_t object_id; // Which object uint32_t rights; // What operations allowed uint64_t expiration; // When capability expires uint64_t nonce; // Prevents replay uint8_t hmac[32]; // HMAC-SHA256 authenticator // Only the issuing authority can create valid HMACs // Recipients can verify, but cannot forge} CryptographicCapability;Rights Encoding\n\nThe rights field within a capability determines what operations the holder may perform. Rights can be:\n\n- Generic rights: Common across object types (read, write, delete)\n- Type-specific rights: Meaningful only for certain objects (execute for files, send for IPC endpoints, map for memory objects)\n- Meta-rights: Control the capability itself (grant allows creating derived capabilities, revoke allows invalidating capabilities)\n\nA crucial principle is that capabilities can only be weakened, never strengthened. If you have a read-write capability, you can derive a read-only capability, but you cannot derive a read-write-execute capability unless you already had execute rights.
| Right | Meaning | Typical Usage |
|---|---|---|
| Read (R) | Access object contents | Files, memory regions |
| Write (W) | Modify object contents | Files, memory regions |
| Execute (X) | Execute object as code | Executable files, memory |
| Delete (D) | Remove object from system | Files, kernel objects |
| Grant (G) | Create derived capabilities for others | Delegation scenarios |
| Revoke (V) | Invalidate derived capabilities | Revocation control |
| Owner (O) | Full control including rights modification | Resource management |
| Send (S) | Send messages through endpoint | IPC endpoints |
| Receive (R) | Receive messages from endpoint | IPC endpoints |
| Map (M) | Map memory object into address space | Memory objects |
Capabilities and Access Control Lists (ACLs) represent two fundamentally different approaches to access control. Understanding this distinction is essential for appreciating when each approach is appropriate and why capabilities offer unique security properties.\n\nWhere Are Access Rights Stored?\n\nThe core distinction lies in where access control information is maintained:\n\n- ACL-based systems: Access rights are stored with the object. Each file, device, or resource maintains a list of which subjects can access it and how.\n\n- Capability-based systems: Access rights are stored with the subject. Each process holds tokens (capabilities) that grant it specific access to specific objects.
The Access Matrix Perspective\n\nRecall the access matrix model where rows represent subjects, columns represent objects, and each cell contains the access rights that subject has to that object. ACLs are the columns of this matrix, while capability lists are the rows.\n\nThis structural difference has profound implications:\n\nACLs optimize for object-centric queries:\n- "Show me everyone who can access /etc/passwd"\n- Easy to enumerate all subjects with access to an object\n- Revocation is local: modify the object's ACL\n\nCapabilities optimize for subject-centric queries:\n- "Show me everything this process can access"\n- Easy to enumerate all objects a subject can access\n- Delegation is natural: just transfer the capability
Consider a compiler that runs with the user's identity but also needs to maintain a billing log. In an ACL system, the compiler "is" the user and also "is" the billing system—its ambient authority conflates these roles. When the user asks it to compile /etc/passwd, which identity should be checked? Capabilities solve this elegantly: the compiler uses user-provided capabilities for user files and its own billing capability for the log. No confusion is possible.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
// The Confused Deputy Problem - ACL vs Capability Approach // === ACL-BASED SYSTEM ===// The compiler runs with combined authority of user + billing system// This conflation causes the confused deputy problem int acl_compile(const char* source_file, const char* output_file) { // What identity should we check? The compiler has BOTH: // - User's authority (to access user files) // - Billing system's authority (to write billing log) // PROBLEM: If user requests compilation of "/etc/passwd", // the access check will use the compiler's ambient authority, // which might include write access to sensitive files! FILE* src = fopen(source_file, "r"); // Checked against user identity? billing identity? if (!src) return -1; // Ambiguous! // Compile... append_to_billing_log(get_current_user()); // Uses billing authority return 0;} // === CAPABILITY-BASED SYSTEM ===// No ambient authority - each operation uses an explicit capability int cap_compile(Capability source_cap, Capability output_cap, Capability billing_cap) { // Each operation uses EXACTLY the capability provided // No confusion possible // source_cap was given by the user - can only access what user intended FILE* src = cap_open(source_cap, CAP_READ); if (!src) return -1; // output_cap was given by the user FILE* out = cap_open(output_cap, CAP_WRITE); if (!out) { fclose(src); return -1; } // Compile using user-provided capabilities only... // billing_cap is the compiler's own capability - separate from user's cap_append(billing_cap, get_current_user()); // Even if user passes a malicious "source_cap" pointing to /etc/passwd, // the compiler cannot write to it unless the capability has write rights // AND unless user rightfully held that capability in the first place return 0;}Practical Security Implications\n\nThe capability model offers several security advantages that are difficult to achieve with ACLs alone:\n\n1. Principle of Least Privilege (POLP)\n\nWith capabilities, a process starts with no authority and must be explicitly granted each capability it needs. This inverts the common ACL pattern where processes often inherit ambient authority (e.g., running as a user with broad file system access).\n\n2. Sandboxing and Confinement\n\nCapability systems naturally support sandboxing. A parent process can launch a child with a carefully curated set of capabilities, preventing the child from accessing anything else. This is the foundation of capability-based sandbox designs.\n\n3. No Ambient Authority\n\nIn capability systems, there is no "ambient authority"—no background set of permissions that automatically applies. Every access requires presenting a specific capability. This eliminates entire classes of vulnerabilities where code inadvertently acts with more authority than intended.\n\n4. Secure Delegation\n\nCapabilities can be safely transferred between processes, enabling secure delegation of access rights. The recipient gains exactly the rights encoded in the capability—no more, no less.
Capability unforgeability can be enforced through hardware mechanisms, software isolation, or a combination of both. Each approach has distinct characteristics, trade-offs, and use cases.\n\nHardware Capability Enforcement\n\nIn hardware capability systems, the processor itself understands and enforces capability semantics. This approach provides the strongest guarantees and best performance, but requires specialized processors.
The CHERI (Capability Hardware Enhanced RISC Instructions) project at Cambridge University represents the state of the art in hardware capabilities. CHERI extends conventional ISAs (MIPS, RISC-V, ARM) with capability instructions while maintaining backward compatibility. ARM's Morello processor, based on CHERI, provides a practical platform for capability-enabled systems.
12345678910111213141516171819202122232425262728293031323334353637383940414243
// CHERI capability programming example// Demonstrating hardware-enforced memory safety #include <cheri/cheri.h> // In CHERI, all pointers are capabilities with bounds and permissions// The compiler and hardware enforce these properties void process_buffer(void* __capability buffer, size_t len) { // The 'buffer' capability encodes: // - Base address // - Length (automatically set from len or derived constraint) // - Permissions (read, write, execute, etc.) // This is SAFE - within bounds char* p = (char*)buffer; for (size_t i = 0; i < len; i++) { p[i] = 0; // Hardware checks: i < capability.length } // This would cause a HARDWARE EXCEPTION: // p[len + 100] = 0; // Out of bounds - capability violation! // Cannot forge a capability: // void* fake = (void*)0x12345678; // This would be a non-capability! // Attempting to dereference 'fake' would trap} // Capability derivation - can only narrow, never widenvoid* __capability derive_readonly(void* __capability cap) { // Remove write permission - this is allowed return cheri_perms_and(cap, CHERI_PERM_LOAD); // Cannot add permissions: // cheri_perms_or(cap, CHERI_PERM_EXECUTE); // Would fail at runtime} // Subsetting - create a capability to a subregionvoid* __capability get_substring(char* __capability str, size_t start, size_t len) { // Create capability to substring - bounds are narrowed return cheri_bounds_set(str + start, len); // The returned capability cannot access outside [start, start+len)}Software Capability Enforcement\n\nSoftware capability systems achieve unforgeability through kernel-enforced isolation or language-level protection. While potentially less efficient than hardware enforcement, software approaches work on conventional processors.\n\nKernel Object Tables\n\nThe most common software approach maintains capability tables in kernel space. User processes hold only opaque indices (handles); the kernel translates these to actual capabilities when needed.\n\nExamples:\n- seL4 maintains a hierarchical capability space (CSpace) for each process\n- Windows object handles are essentially software capabilities\n- Unix file descriptors are a limited form of software capability\n\nLanguage-Based Capabilities\n\nSome programming languages enforce capability semantics through type systems and encapsulation:\n- E language provides unforgeable object references\n- Caja (JavaScript subset) enforces capability semantics in web browsers\n- Rust ownership semantics provide capability-like memory safety
| Aspect | Hardware Capabilities | Software Capabilities |
|---|---|---|
| Enforcement | Processor instructions, tag bits | Kernel isolation, language semantics |
| Performance | Near-zero overhead for checks | System call overhead for operations |
| Compatibility | Requires special hardware | Works on conventional processors |
| Granularity | Byte-level memory protection | Object-level protection typical |
| Error Detection | Immediate hardware trap | Kernel check on system call |
| Forgery Prevention | Tag bits, sealed memory | Cryptographic or kernel tables |
| Legacy Support | Requires recompilation | Often compatible with existing code |
| Examples | CHERI, CAP, IBM System/38 | seL4, KeyKOS, file descriptors |
Hybrid Approaches\n\nModern systems often combine hardware and software capability mechanisms:\n\n- seL4 on CHERI provides kernel-level capabilities backed by hardware memory protection\n- Unix with CHERI could enforce file descriptor semantics in hardware while keeping kernel capability management\n- Sandbox systems use hardware memory protection (MMU) with software capability checking\n\nThe trend is toward more hardware support, as the performance benefits become critical for security-intensive applications.
True capability systems exhibit several essential properties that distinguish them from systems that merely use capabilities as an implementation technique. Understanding these properties helps identify genuine capability-based security from capability-flavored designs.\n\nThe Principle of No Ambient Authority\n\nIn a pure capability system, processes have no implicit access to any resource. All access requires explicitly presenting a capability. There is no "ambient authority" based on user identity, process identity, or inherited permissions.\n\nContrast with Unix, where a process running as root has ambient authority to access almost everything. In a capability system, even the most privileged process can only access objects for which it holds capabilities.
The security of a capability system depends on maintaining capability connectivity invariants. If capabilities can leak through side channels (covert channels, unprotected storage, reference to global namespaces), the security model breaks down. This is why pure capability systems avoid global namespaces and ambient authority entirely.
Object-Capability (OCap) Model\n\nThe Object-Capability model, or OCap, combines capabilities with object-oriented principles. Every object reference is a capability—objects can only interact with other objects through their references.\n\nKey OCap principles:\n\n1. No global mutable state — No global variables that could bypass capability discipline\n2. No ambient authority — Objects only have authority through their references\n3. Encapsulation — Object internal state is inaccessible without a reference\n4. Reference transfer — Objects share authority by passing references (capabilities)\n\nLanguages like E, Joe-E (Java subset), and Caja (JavaScript subset) implement OCap semantics.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
# Object-Capability Pattern in E language# Demonstrating capability-based access control through object references # A file object that can only be accessed through its capabilitydef makeFile(path) :File { # Private state - only accessible through the returned object var contents := readInitialContents(path) # Return an object that IS the capability to this file return def file { # Read capability - implicit in having this reference to read() { return contents } # Write capability - also implicit in having reference to write(newContents) { contents := newContents persistToStorage(path, contents) # Using encapsulated path } # Create a read-only facet - deliberate capability attenuation to readOnly() { return def roFile { to read() { return contents } # No write method - cannot write through this facet } } }} # Usage: capabilities acquired through explicit channelsdef main(fileFactory) { # Receive file capability through constructor argument (no ambient authority) def myFile := fileFactory("document.txt") # Can read and write through the full capability def data := myFile.read() myFile.write("updated content") # Create attenuated capability for untrusted code def restrictedFile := myFile.readOnly() # Pass to untrusted component - can only read untrustedComponent(restrictedFile) # untrustedComponent CANNOT write - no write method exists on roFile}Capability Safety Requirements\n\nA language or system claiming to support capabilities must satisfy several safety requirements:\n\n1. Reference Opacity: References cannot be forged by code that doesn't already possess them\n2. Memory Safety: Pointer arithmetic cannot manufacture references to arbitrary memory\n3. Encapsulation Integrity: Private object state cannot be accessed without going through object methods\n4. Effects Confinement: Objects can only affect the world through their references\n\nLanguages like C and C++ are fundamentally not capability-safe because pointer arithmetic can forge arbitrary references. This is why CHERI is significant—it makes C capability-safe through hardware enforcement.
While pure capability systems remain specialized, capability concepts have influenced many mainstream technologies. Understanding these applications reveals how capability thinking shapes modern system design.\n\nFile Descriptors: Unix's Accidental Capabilities\n\nUnix file descriptors exhibit many capability properties, though Unix itself isn't a pure capability system:\n\n- A file descriptor designates a specific open file\n- The descriptor encdes access mode (read, write, etc.)\n- Descriptors cannot be forged (indices into kernel table)\n- Descriptors can be transferred between processes (via SCM_RIGHTS)\n\nHowever, Unix also has ambient authority through the file system namespace—any process can attempt to open /etc/passwd by name. Pure capability systems have no such namespace.
| System | Capability Feature | Limitation |
|---|---|---|
| Unix file descriptors | Unforgeable, transferable access tokens | Ambient authority via pathname namespace |
| Windows object handles | Kernel-managed capability table | ACLs still primary access control |
| Android intents | Capability URIs for cross-app access | Intent spoofing risks |
| Capsicum (FreeBSD) | Capability mode with no ambient authority | Opt-in, not system-wide |
| Web browser origins | Same-origin policy as implicit capability | Not fine-grained |
| WebAssembly | Linear memory + imported capabilities | Growing but incomplete |
| CloudABI | Pure capability-based POSIX subset | Limited ecosystem |
| seL4 | Pure capability kernel | Microkernel complexity |
Capsicum, developed at Cambridge and integrated into FreeBSD, allows processes to enter 'capability mode' where ambient authority is revoked. A process in capability mode can only access resources through file descriptors it already holds—no new pathname lookups allowed. This enables fine-grained sandboxing without rewriting the application.
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
// Capsicum capability mode sandboxing// FreeBSD implementation of practical capability-based security #include <sys/capsicum.h>#include <stdio.h>#include <fcntl.h> int sandbox_file_processor(const char* input_path, const char* output_path) { // Phase 1: Open files BEFORE entering capability mode (ambient authority available) int input_fd = open(input_path, O_RDONLY); int output_fd = open(output_path, O_WRONLY | O_CREAT, 0644); if (input_fd < 0 || output_fd < 0) { perror("Failed to open files"); return -1; } // Limit capabilities on file descriptors cap_rights_t input_rights, output_rights; cap_rights_init(&input_rights, CAP_READ, CAP_SEEK); cap_rights_init(&output_rights, CAP_WRITE, CAP_SEEK); cap_rights_limit(input_fd, &input_rights); cap_rights_limit(output_fd, &output_rights); // Phase 2: Enter capability mode - revoke ALL ambient authority if (cap_enter() < 0) { perror("Failed to enter capability mode"); return -1; } // === NOW SANDBOXED === // From this point: // - Cannot open new files (no pathname access) // - Cannot create network connections // - Can only use file descriptors we already have // - Rights are limited to what we explicitly set // This would FAIL in capability mode: // open("/etc/passwd", O_RDONLY); // ENOTCAPABLE // Process file using only our pre-opened, rights-limited descriptors char buffer[4096]; ssize_t bytes; while ((bytes = read(input_fd, buffer, sizeof(buffer))) > 0) { // Transform data... write(output_fd, buffer, bytes); } // Even if this code has a vulnerability (buffer overflow, etc.), // the attacker is confined to our capability set: // - Can only read from input_fd // - Can only write to output_fd // - No network, no new files, no privilege escalation close(input_fd); close(output_fd); return 0;}seL4: The Formally Verified Capability Kernel\n\nseL4 represents the state of the art in capability-based kernel design. It is:\n\n- Formally verified: Mathematical proofs that the C code correctly implements its specification\n- Pure capability: All access control through capabilities, no ambient authority\n- High-assurance: Used in safety-critical and security-critical systems (drones, autonomous vehicles, military)\n\nseL4 demonstrates that pure capability semantics are not just academically interesting but practically viable for the most demanding applications.\n\nCHERI and Memory-Safe Computing\n\nThe CHERI project addresses one of computing's most persistent security problems: memory safety vulnerabilities. By making every pointer a capability, CHERI:\n\n- Eliminates buffer overflows (pointers carry bounds)\n- Prevents use-after-free (revocation invalidates dangling capabilities)\n- Enables fine-grained compartmentalization\n\nARM's Morello processor implements CHERI, providing a path to mainstream hardware capability support.
We have explored the capability concept—one of the most elegant and powerful ideas in operating system security. Let us consolidate the key insights from this page:
What's Next\n\nNow that we understand what capabilities are and their fundamental properties, we need to examine how they are organized and managed. The next page explores Capability Lists—how capabilities are stored, organized, and accessed by the processes that hold them.
You now understand the capability concept—how it differs from ACL-based access control, its formal properties, implementation approaches, and presence in modern systems. Continue to the next page to learn how capabilities are organized into capability lists.