Access Control Methods

Relevant source files

Purpose and Scope

This document covers the access control methods provided by the WithCap<T> wrapper for accessing protected objects. It explains the different access patterns available, their safety guarantees, and appropriate usage scenarios. For information about the capability system and permission flags, see Capability System. For details about the WithCap<T> wrapper structure itself, see Object Protection with WithCap.

The access control methods implement a capability-based security model where objects can only be accessed when the caller presents the required capabilities. The system provides multiple access patterns to accommodate different error handling strategies and performance requirements.

Access Control Flow

The access control system follows a consistent pattern where capability validation determines whether access is granted to the protected object.

flowchart TD
CALLER["Caller Code"]
METHOD["Access Method Call"]
CHECK["can_access(cap)"]
VALIDATE["CapabilityValidation"]
GRANT["Access Granted"]
DENY["Access Denied"]
RETURN_REF["Return &T"]
ERROR_HANDLING["Error Handling"]
OPTION["Option::None"]
RESULT["Result::Err(E)"]
UNSAFE["Undefined Behavior"]
SAFE_ACCESS["access(cap)"]
RESULT_ACCESS["access_or_err(cap, err)"]
UNSAFE_ACCESS["access_unchecked()"]

CALLER --> METHOD
CHECK --> VALIDATE
DENY --> ERROR_HANDLING
ERROR_HANDLING --> OPTION
ERROR_HANDLING --> RESULT
ERROR_HANDLING --> UNSAFE
GRANT --> RETURN_REF
METHOD --> CHECK
METHOD --> RESULT_ACCESS
METHOD --> SAFE_ACCESS
METHOD --> UNSAFE_ACCESS
RESULT_ACCESS --> CHECK
SAFE_ACCESS --> CHECK
UNSAFE_ACCESS --> RETURN_REF
VALIDATE --> DENY
VALIDATE --> GRANT

Sources: src/lib.rs(L46 - L99) 

Capability Validation

All safe access methods rely on the can_access method for capability validation. This method performs a bitwise containment check to determine if the required capabilities are present.

can_accessMethod

The can_access method provides the fundamental capability checking logic used by all safe access patterns.

Method SignatureReturn TypePurpose
can_access(&self, cap: Cap)boolCheck if capabilities allow access

Implementation Details:

  • Uses self.cap.contains(cap) for bitwise capability checking
  • Declared as const fn for compile-time evaluation
  • Returns true if all requested capability bits are present
  • Returns false if any requested capability bits are missing

Sources: src/lib.rs(L46 - L48) 

Safe Access Methods

The library provides two safe access methods that perform capability validation before granting access to the protected object.

Option-Based Access

The access method provides safe access with Option<&T> return semantics for cases where capability failure should be handled gracefully.

flowchart TD
INPUT["access(cap: Cap)"]
CHECK["can_access(cap)"]
SOME["Some(&self.inner)"]
NONE["None"]
CLIENT_OK["Client handles success"]
CLIENT_ERR["Client handles None"]

CHECK --> NONE
CHECK --> SOME
INPUT --> CHECK
NONE --> CLIENT_ERR
SOME --> CLIENT_OK

Method Characteristics:

  • Signature: access(&self, cap: Cap) -> Option<&T>
  • Safety: Memory safe with compile-time guarantees
  • Performance: Minimal overhead with const fn optimization
  • Error Handling: Returns None on capability mismatch

Usage Pattern:

if let Some(data) = protected_obj.access(Cap::READ) {
    // Use data safely
} else {
    // Handle access denial
}

Sources: src/lib.rs(L72 - L78) 

Result-Based Access

The access_or_err method provides safe access with Result<&T, E> return semantics, allowing custom error types and error propagation patterns.

flowchart TD
INPUT["access_or_err(cap: Cap, err: E)"]
CHECK["can_access(cap)"]
OK["Ok(&self.inner)"]
ERR["Err(err)"]
CLIENT_OK["Client handles success"]
CLIENT_ERR["Client handles custom error"]
PROPAGATE["Error propagation with ?"]

CHECK --> ERR
CHECK --> OK
ERR --> CLIENT_ERR
ERR --> PROPAGATE
INPUT --> CHECK
OK --> CLIENT_OK

Method Characteristics:

  • Signature: access_or_err<E>(&self, cap: Cap, err: E) -> Result<&T, E>
  • Safety: Memory safe with compile-time guarantees
  • Error Handling: Returns custom error type on capability mismatch
  • Integration: Compatible with ? operator for error propagation

Usage Pattern:

let data = protected_obj.access_or_err(Cap::WRITE, "Write access denied")?;
// Use data safely, or propagate error

Sources: src/lib.rs(L93 - L99) 

Unsafe Access Methods

The library provides an unsafe access method for performance-critical scenarios where capability checking overhead must be eliminated.

Unchecked Access

The access_unchecked method bypasses all capability validation and directly returns a reference to the protected object.

flowchart TD
INPUT["access_unchecked()"]
DIRECT["&self.inner"]
WARNING["⚠️ UNSAFE:No capability validation"]
CALLER["Caller Responsibility"]
BYPASS["Bypasses can_access()"]
PERFORMANCE["Zero-overhead access"]

BYPASS --> PERFORMANCE
DIRECT --> WARNING
INPUT --> BYPASS
INPUT --> DIRECT
WARNING --> CALLER

Method Characteristics:

  • Signature: unsafe fn access_unchecked(&self) -> &T
  • Safety: UNSAFE - No capability validation performed
  • Performance: Zero overhead - direct memory access
  • Responsibility: Caller must ensure capability compliance

Safety Requirements: The caller must guarantee that they have the appropriate capabilities for the intended use of the object. Violating this contract may lead to:

  • Security vulnerabilities
  • Privilege escalation
  • Undefined behavior in security-critical contexts

Sources: src/lib.rs(L55 - L57) 

Access Method Comparison

MethodSafetyReturn TypeOverheadUse Case
accessSafeOption<&T>MinimalGeneral purpose with option handling
access_or_errSafeResult<&T, E>MinimalError propagation and custom errors
access_uncheckedUnsafe&TZeroPerformance-critical trusted code

Implementation Architecture

The access control methods are implemented as part of the WithCap<T> struct and follow a layered architecture:

flowchart TD
subgraph subGraph2["Memory Access"]
    INNER_REF["&self.inner"]
end
subgraph subGraph1["Core Validation"]
    CONTAINS["self.cap.contains(cap)"]
    BITFLAGS["bitflags operations"]
end
subgraph subGraph0["WithCap Access Methods"]
    CAN_ACCESS["can_access(cap: Cap)→ bool"]
    ACCESS["access(cap: Cap)→ Option<&T>"]
    ACCESS_ERR["access_or_err(cap: Cap, err: E)→ Result<&T, E>"]
    ACCESS_UNSAFE["access_unchecked()→ &T"]
end

ACCESS --> CAN_ACCESS
ACCESS --> INNER_REF
ACCESS_ERR --> CAN_ACCESS
ACCESS_ERR --> INNER_REF
ACCESS_UNSAFE --> INNER_REF
CAN_ACCESS --> CONTAINS
CONTAINS --> BITFLAGS

Architecture Characteristics:

  • Layered Design: Safe methods build upon capability validation
  • Shared Validation: All safe methods use can_access for consistency
  • Zero-Cost Abstractions: const fn declarations enable compile-time optimization
  • Type Safety: Generic design works with any wrapped type T

Sources: src/lib.rs(L23 - L100)