Capability System
Relevant source files
Purpose and Scope
The Capability System forms the foundation of access control in the cap_access library. This document covers the Cap
bitflags structure, the three fundamental capability types (READ, WRITE, EXECUTE), and the mechanisms for combining and checking capabilities. For information about how capabilities are used with protected objects, see Object Protection with WithCap. For details on access control methods that utilize these capabilities, see Access Control Methods.
Cap Bitflags Structure
The capability system is implemented using the bitflags
crate to provide efficient bit-level operations for permission management. The Cap
structure represents unforgeable access tokens that can be combined using bitwise operations.
flowchart TD subgraph subGraph2["Bitwise Operations"] UNION["Union (|)"] INTERSECTION["Intersection (&)"] CONTAINS["contains()"] end subgraph subGraph1["Bitflags Traits"] DEFAULT["Default"] DEBUG["Debug"] CLONE["Clone"] COPY["Copy"] end subgraph subGraph0["Cap Structure [lines 4-15]"] CAP["Cap: u32"] READ["READ = 1 << 0"] WRITE["WRITE = 1 << 1"] EXECUTE["EXECUTE = 1 << 2"] end CAP --> CLONE CAP --> COPY CAP --> DEBUG CAP --> DEFAULT CAP --> EXECUTE CAP --> READ CAP --> WRITE EXECUTE --> UNION INTERSECTION --> CONTAINS READ --> UNION UNION --> CONTAINS WRITE --> UNION
Cap Bitflags Architecture
The Cap
struct is defined as a bitflags structure that wraps a u32
value, providing type-safe capability manipulation with automatic trait derivations for common operations.
Sources: src/lib.rs(L4 - L15)
Basic Capability Types
The capability system defines three fundamental access rights that correspond to common operating system permissions:
Capability | Bit Position | Value | Purpose |
---|---|---|---|
READ | 0 | 1 << 0(1) | Grants readable access to protected data |
WRITE | 1 | 1 << 1(2) | Grants writable access to protected data |
EXECUTE | 2 | 1 << 2(4) | Grants executable access to protected data |
flowchart TD subgraph subGraph1["Capability Constants"] READ_CONST["Cap::READ = 0x01"] WRITE_CONST["Cap::WRITE = 0x02"] EXECUTE_CONST["Cap::EXECUTE = 0x04"] end subgraph subGraph0["Bit Layout [u32]"] BIT2["Bit 2: EXECUTE"] BIT1["Bit 1: WRITE"] BIT0["Bit 0: READ"] UNUSED["Bits 3-31: Reserved"] end BIT0 --> READ_CONST BIT1 --> WRITE_CONST BIT2 --> EXECUTE_CONST
Capability Bit Layout
Each capability type occupies a specific bit position, allowing for efficient combination and checking operations using bitwise arithmetic.
Sources: src/lib.rs(L8 - L14)
Capability Combinations
Capabilities can be combined using bitwise OR operations to create composite permissions. The bitflags implementation provides natural syntax for capability composition:
flowchart TD subgraph subGraph2["Use Cases"] READONLY["Read-only files"] READWRITE["Mutable data"] EXECUTABLE["Program files"] FULLACCESS["Administrative access"] end subgraph subGraph1["Common Combinations"] RW["Cap::READ | Cap::WRITE"] RX["Cap::READ | Cap::EXECUTE"] WX["Cap::WRITE | Cap::EXECUTE"] RWX["Cap::READ | Cap::WRITE | Cap::EXECUTE"] end subgraph subGraph0["Single Capabilities"] R["Cap::READ"] W["Cap::WRITE"] X["Cap::EXECUTE"] end R --> READONLY R --> RW R --> RWX R --> RX RW --> READWRITE RWX --> FULLACCESS RX --> EXECUTABLE W --> RW W --> RWX W --> WX X --> RWX X --> RX X --> WX
Capability Combination Patterns
The bitflags design enables natural combination of capabilities to express complex permission requirements.
Sources: src/lib.rs(L4 - L15)
Capability Checking Logic
The capability system provides the contains
method for checking whether a set of capabilities includes required permissions. This forms the foundation for all access control decisions in the system.
flowchart TD subgraph subGraph0["contains() Logic"] BITWISE["(self.bits & other.bits) == other.bits"] SUBSET["Check if 'other' is subset of 'self'"] end subgraph subGraph1["Example Scenarios"] SCENARIO1["Object has READ|WRITERequest: READ → true"] SCENARIO2["Object has READRequest: WRITE → false"] SCENARIO3["Object has READ|WRITERequest: READ|WRITE → true"] end START["can_access(cap: Cap)"] CHECK["self.cap.contains(cap)"] TRUE["Return true"] FALSE["Return false"] BITWISE --> SUBSET CHECK --> BITWISE START --> CHECK SUBSET --> FALSE SUBSET --> TRUE
Capability Checking Flow
The can_access
method uses bitwise operations to determine if the requested capabilities are a subset of the available capabilities.
Sources: src/lib.rs(L46 - L48)
Implementation Details
The Cap
structure leverages several key design patterns for efficient and safe capability management:
Bitflags Integration
The implementation uses the bitflags!
macro to generate a complete capability management API, including:
- Automatic implementation of bitwise operations (
|
,&
,^
,!
) - Type-safe flag manipulation methods
- Built-in
contains()
method for subset checking - Standard trait implementations (
Debug
,Clone
,Copy
,Default
)
Memory Efficiency
The Cap
structure occupies only 4 bytes (u32
) regardless of capability combinations, making it suitable for embedded environments where memory usage is critical.
Constant Evaluation
The can_access
method is marked as const fn
, enabling compile-time capability checking when capability values are known at compile time.