Capability-based license enforcement
| Tier | foundation |
| Role | unclassified (baselined) |
| Path | crates/foundation/license |
| Edition | 2021 |
| Targets | foundation_license |
| Public items | 125 across 12 modules |
| Tests | 43 |
What it is for
# foundation-license
Capability-based license enforcement library crate for Rust applications.
This crate provides a server-side license enforcement system that:
- Validates signed license artifacts (Ed25519)
- Exposes a read-only interface to license capabilities
- Enforces capabilities at service and API boundaries
- Supports multiple license tiers with different modules/features
- Integrates with audit logging
Architecture
License enforcement follows a layered approach:
1. Service Layer (Primary) - Every privileged operation calls enforce_capability() 2. API Layer (Secondary) - Axum middleware gates entire route trees 3. Admin UI (Tertiary) - UI reflects license state but does not enforce
The server is always authoritative. UI gating is convenience only.
Quick Start
use foundation_license::{initialize_license, enforce_capability, LICENSE_PUBLIC_KEY};
// Initialize at startup (once)
initialize_license("license.json", &LICENSE_PUBLIC_KEY, None);
// Enforce in service methods
pub async fn create_document(input: Input) -> Result<Document, Error> {
enforce_capability("module:documents", Some(&user_id))?;
// ... proceed with operation
}
License File Format
Licenses are JSON files containing a base64-encoded payload and signature:
{
"payload": "base64-encoded-json-payload",
"signature": "base64-encoded-ed25519-signature",
"version": 1
}
Capabilities
Capabilities follow a namespace:name pattern:
module:content- Access to the content modulefeature:sso- Access to SSO featurelimit:max_users- A numeric limit (value stored separately)
Error Handling
All errors include:
- Stable error code (e.g.,
LICENSE_FORBIDDEN) - Human-readable message (neutral, professional)
- Required capability (if applicable)
- Current license status
Security Notes
- The public key is compiled into the binary
- License state cannot be mutated after initialization
- All enforcement is server-side
- Audit events are emitted for all enforcement decisions
Capabilities
CapabilityCheckResponse
License status API
| Item |
|---|
pub struct CapabilityCheckResponse |
CapabilityCheckResponse :: fn check(capability : & str) -> Self |
LicenseStatusResponse
License status API
| Item |
|---|
pub struct LicenseStatusResponse |
LicenseStatusResponse :: fn from_current_state() -> Self |
LimitSummary
License status API
| Item |
|---|
pub struct LimitSummary |
api::handlers (other)
Axum handlers for license API endpoints.
| Item |
|---|
async fn get_license_status() -> Json <LicenseStatusResponse> |
async fn check_capability(Path(capability) : Path <String>,) ->(StatusCode, Json <CapabilityCheckResponse>) |
audit (other)
License audit event types
| Item |
|---|
fn audit_license_loaded(status : LicenseStatus) |
fn audit_capability_denied(capability : & str, status : LicenseStatus, actor : Option <& str>) |
fn audit_capability_granted(capability : & str, status : LicenseStatus, actor : Option <& str>) |
fn audit_limit_exceeded(limit_name : & str, current : u64, maximum : u64, status : LicenseStatus, actor : Option <& str>,) |
AuditOutcome
License audit event types
| Item |
|---|
pub enum AuditOutcome |
LicenseAuditEntry
License audit event types
| Item |
|---|
pub struct LicenseAuditEntry |
LicenseAuditEntry :: fn new(event : LicenseAuditEvent, status : LicenseStatus, outcome : AuditOutcome) -> Self |
LicenseAuditEntry :: fn with_actor(mut self, actor : impl Into <String>) -> Self |
LicenseAuditEntry :: fn with_capability(mut self, capability : impl Into <String>) -> Self |
LicenseAuditEntry :: fn with_context(mut self, context : serde_json::Value) -> Self |
LicenseAuditEntry :: fn emit(self) |
LicenseAuditEvent
License audit event types
| Item |
|---|
pub enum LicenseAuditEvent |
enforcement (other)
License enforcement mechanisms
| Item |
|---|
fn enforce_capability(capability : & str, actor : Option <& str>) -> LicenseResult <()> |
fn enforce_limit(limit_name : & str, current_value : u64, actor : Option <& str>,) -> LicenseResult <()> |
fn has_capability(capability : & str) -> bool |
fn license_status() -> LicenseStatus |
fn is_licensed() -> bool |
CapabilityGuard
License enforcement mechanisms
| Item |
|---|
pub struct CapabilityGuard |
CapabilityGuard :: fn acquire(capability : & str, actor : Option <& str>) -> LicenseResult <Self> |
CapabilityGuard :: fn capability(& self) -> & str |
EnforcementDenial
License enforcement mechanisms
| Item |
|---|
pub struct EnforcementDenial |
EnforcementDenial :: fn from(error : & LicenseError) -> Self |
LicenseError
License error types
| Item |
|---|
pub enum LicenseError |
LicenseError :: fn error_code(& self) -> & 'static str |
LicenseError :: fn required_capability(& self) -> Option <& str> |
LicenseError :: fn license_status(& self) -> LicenseStatus |
LicenseError :: fn user_message(& self) -> & str |
LicenseResult
License error types
| Item |
|---|
pub type LicenseResult<T>: Result <T, LicenseError> |
hardware (other)
Hardware node-locking + grace-then-fail entitlement (ADR 0018).
| Item |
|---|
pub const ACCEPT_THRESHOLD: u32 |
fn match_hardware(licensed : & HardwareBinding, observed : & BTreeMap <String, String>,) -> HardwareMatch |
AccessMode
Hardware node-locking + grace-then-fail entitlement (ADR 0018).
| Item |
|---|
pub enum AccessMode |
Entitlement
Hardware node-locking + grace-then-fail entitlement (ADR 0018).
| Item |
|---|
pub struct Entitlement |
Entitlement :: fn emergency(reason : impl Into <String>) -> Self |
fn evaluate(payload : & LicensePayload, signature_valid : bool, observed : Option <& BTreeMap <String, String>>, now : DateTime <Utc>, hardware_grace_until : Option <DateTime <Utc>>,) -> Entitlement |
HardwareBinding
Hardware node-locking + grace-then-fail entitlement (ADR 0018).
| Item |
|---|
pub struct HardwareBinding |
HardwareMatch
Hardware node-locking + grace-then-fail entitlement (ADR 0018).
| Item |
|---|
pub struct HardwareMatch |
middleware (other)
Axum middleware for license enforcement
| Item |
|---|
async fn require_valid_license(request : Request, next : Next) -> Response |
fn require_capability_middleware(capability : & 'static str,) -> impl Fn(Request, Next) -> std::pin::Pin <Box <dyn std::future::Future <Output = Response> + Send>> + Clone + Send + 'static |
LicenseErrorResponse
Axum middleware for license enforcement
| Item |
|---|
pub struct LicenseErrorResponse |
LicenseErrorResponse :: fn into_response(self) -> Response |
LicenseErrorResponse :: fn from(error : LicenseError) -> Self |
LicenseRouterExt
Axum middleware for license enforcement
| Item |
|---|
pub trait LicenseRouterExt |
RequireCapability
Axum middleware for license enforcement
| Item |
|---|
pub struct RequireCapability |
RequireCapability :: async fn from_request_parts(_parts : & mut axum::http::request::Parts, _state : & S,) -> Result <Self, Self::Rejection> |
axum::Router<S>
Axum middleware for license enforcement
| Item |
|---|
axum::Router<S> :: fn require_license(self) -> Self |
axum::Router<S> :: fn require_capability(self, capability : & 'static str) -> Self |
LicenseState:LicenseState
License state management
| Item |
|---|
pub struct LicenseState |
LicenseState:check
License state management
| Item |
|---|
LicenseState :: fn check_limit(& self, name : & str, current : u64) -> LicenseResult <()> |
LicenseState:create
License state management
| Item |
|---|
fn create_test_state(payload : LicensePayload) -> LicenseState |
LicenseState:customer
License state management
| Item |
|---|
LicenseState :: fn customer_id(& self) -> Option <& str> |
LicenseState:enabled
License state management
| Item |
|---|
LicenseState :: fn enabled_modules(& self) -> Vec <& str> |
LicenseState :: fn enabled_features(& self) -> Vec <& str> |
LicenseState:expires
License state management
| Item |
|---|
LicenseState :: fn expires_at(& self) -> Option <DateTime <Utc>> |
LicenseState:get
License state management
| Item |
|---|
fn get_license() -> & 'static LicenseState |
LicenseState:has
License state management
| Item |
|---|
LicenseState :: fn has_capability(& self, cap : & str) -> bool |
LicenseState:initialize
License state management
| Item |
|---|
fn initialize_license(path : impl AsRef <Path>, public_key : & u8; 32, environment : Option <& str>,) -> & 'static LicenseState |
LicenseState:is
License state management
| Item |
|---|
LicenseState :: fn is_valid(& self) -> bool |
LicenseState:license
License state management
| Item |
|---|
LicenseState :: fn license_id(& self) -> Option <uuid::Uuid> |
LicenseState:limit
License state management
| Item |
|---|
LicenseState :: fn limit(& self, name : & str) -> Option <u64> |
LicenseState:limits
License state management
| Item |
|---|
LicenseState :: fn limits(& self) -> std::collections::HashMap <String, u64> |
LicenseState:loaded
License state management
| Item |
|---|
LicenseState :: fn loaded_at(& self) -> DateTime <Utc> |
LicenseState:require
License state management
| Item |
|---|
LicenseState :: fn require(& self, cap : & str) -> LicenseResult <()> |
LicenseState:status
License state management
| Item |
|---|
LicenseState :: fn status(& self) -> LicenseStatus |
LicenseState:try
License state management
| Item |
|---|
fn try_get_license() -> Option <& 'static LicenseState> |
LicenseStatus
License status types
| Item |
|---|
pub enum LicenseStatus |
LicenseStatus :: fn is_operational(& self) -> bool |
LicenseStatus :: fn is_terminal(& self) -> bool |
LicenseStatus :: fn needs_attention(& self) -> bool |
LicenseStatus :: fn description(& self) -> & 'static str |
LicenseStatus :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result |
Capability:Capability
License payload and capability types
| Item |
|---|
pub struct Capability |
Capability:as
License payload and capability types
| Item |
|---|
Capability :: fn as_str(& self) -> & str |
Capability:feature
License payload and capability types
| Item |
|---|
Capability :: fn feature(name : & str) -> Self |
Capability:fmt
License payload and capability types
| Item |
|---|
Capability :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result |
Capability:from
License payload and capability types
| Item |
|---|
Capability :: fn from(s : & str) -> Self |
Capability :: fn from(s : String) -> Self |
Capability:is
License payload and capability types
| Item |
|---|
Capability :: fn is_module(& self) -> bool |
Capability :: fn is_feature(& self) -> bool |
Capability :: fn is_limit(& self) -> bool |
Capability:limit
License payload and capability types
| Item |
|---|
Capability :: fn limit(name : & str) -> Self |
Capability:matches
License payload and capability types
| Item |
|---|
Capability :: fn matches(& self, pattern : & str) -> bool |
Capability:module
License payload and capability types
| Item |
|---|
Capability :: fn module(name : & str) -> Self |
Capability:name
License payload and capability types
| Item |
|---|
Capability :: fn name(& self) -> Option <& str> |
Capability:namespace
License payload and capability types
| Item |
|---|
Capability :: fn namespace(& self) -> Option <& str> |
Capability:new
License payload and capability types
| Item |
|---|
Capability :: fn new(value : impl Into <String>) -> Self |
LicensePayload
License payload and capability types
| Item |
|---|
pub struct LicensePayload |
LicensePayload :: fn builder(license_id : Uuid, customer_id : impl Into <String>) -> LicensePayloadBuilder |
LicensePayload :: fn has_capability(& self, cap : & str) -> bool |
LicensePayload :: fn limit(& self, name : & str) -> Option <u64> |
LicensePayload :: fn modules(& self) -> impl Iterator <Item = & str> |
LicensePayload :: fn features(& self) -> impl Iterator <Item = & str> |
LicensePayload :: fn is_time_valid(& self, now : DateTime <Utc>) -> bool |
LicensePayload :: fn is_in_grace_period(& self, now : DateTime <Utc>) -> bool |
LicensePayload :: fn is_revoked(& self) -> bool |
LicensePayloadBuilder:LicensePayloadBuilder
License payload and capability types
| Item |
|---|
pub struct LicensePayloadBuilder |
LicensePayloadBuilder:build
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn build(self) -> LicensePayload |
LicensePayloadBuilder:capability
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn capability(mut self, cap : impl Into <Capability>) -> Self |
LicensePayloadBuilder:environment
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn environment(mut self, environment : impl Into <String>) -> Self |
LicensePayloadBuilder:expires
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn expires_at(mut self, expires_at : DateTime <Utc>) -> Self |
LicensePayloadBuilder:feature
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn feature(mut self, name : & str) -> Self |
LicensePayloadBuilder:grace
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn grace_period_days(mut self, days : u32) -> Self |
LicensePayloadBuilder:hardware
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn hardware(mut self, binding : crate::hardware::HardwareBinding) -> Self |
LicensePayloadBuilder:issued
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn issued_at(mut self, issued_at : DateTime <Utc>) -> Self |
LicensePayloadBuilder:limit
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn limit(mut self, name : & str, value : u64) -> Self |
LicensePayloadBuilder:metadata
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn metadata(mut self, key : impl Into <String>, value : serde_json::Value) -> Self |
LicensePayloadBuilder:module
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn module(mut self, name : & str) -> Self |
LicensePayloadBuilder:new
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn new(license_id : Uuid, customer_id : impl Into <String>) -> Self |
LicensePayloadBuilder:not
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn not_before(mut self, not_before : DateTime <Utc>) -> Self |
LicensePayloadBuilder:perpetual
License payload and capability types
| Item |
|---|
LicensePayloadBuilder :: fn perpetual(mut self) -> Self |
SignedLicense
License payload and capability types
| Item |
|---|
pub struct SignedLicense |
SignedLicense :: fn new(payload : & LicensePayload, signature : & u8) -> Result <Self, serde_json::Error> |
SignedLicense :: fn payload_bytes(& self) -> Result <Vec <u8>, base64::DecodeError> |
SignedLicense :: fn signature_bytes(& self) -> Result <Vec <u8>, base64::DecodeError> |
verification (other)
License signature verification
| Item |
|---|
pub const LICENSE_PUBLIC_KEY: & u8; 32 |
fn verify_license(signed : & SignedLicense) -> LicenseResult <LicensePayload> |
fn verify_license_with_key(signed : & SignedLicense, public_key : & u8; 32,) -> LicenseResult <LicensePayload> |
fn sign_license(payload : & LicensePayload, signing_key : & foundation_crypto_sign::SigningKey,) -> LicenseResult <SignedLicense> |
fn generate_keypair() ->(foundation_crypto_sign::SigningKey, foundation_crypto_sign::VerifyingKey,) |
How to use it
From this crate's own rustdoc:
## License File Format
Licenses are JSON files containing a base64-encoded payload and signature:
Module structure
foundation_license
apiapi::handlersauditenforcementerrorhardwaremiddlewarepreludestatestatustypesverification
flowchart TD n_foundation_license["foundation_license"] n_foundation_license --> n_api["api"] n_api --> n_api__handlers["handlers"] n_foundation_license --> n_audit["audit"] n_foundation_license --> n_enforcement["enforcement"] n_foundation_license --> n_error["error"] n_foundation_license --> n_hardware["hardware"] n_foundation_license --> n_middleware["middleware"] n_foundation_license --> n_prelude["prelude"] n_foundation_license --> n_state["state"] n_foundation_license --> n_status["status"] n_foundation_license --> n_types["types"] n_foundation_license --> n_verification["verification"]
Public surface
`api`
| Item | What it is |
|---|---|
pub struct LicenseStatusResponse | Response for GET /api/license/status This is the ONLY license information exposed to the admin UI |
pub struct LimitSummary | Summary of a limit capability. |
LicenseStatusResponse :: fn from_current_state() -> Self | Builds the license status response from the current state. |
pub struct CapabilityCheckResponse | Checks if a specific capability is available (for UI conditional rendering) |
CapabilityCheckResponse :: fn check(capability : & str) -> Self | Checks if a capability is available. |
`api::handlers`
| Item | What it is |
|---|---|
async fn get_license_status() -> Json <LicenseStatusResponse> | Handler for GET /api/license/status |
async fn check_capability(Path(capability) : Path <String>,) ->(StatusCode, Json <CapabilityCheckResponse>) | Handler for GET /api/license/capability/:capability |
`audit`
| Item | What it is |
|---|---|
pub enum LicenseAuditEvent | Types of license-related audit events. |
pub struct LicenseAuditEntry | Structured audit log entry for license events. |
pub enum AuditOutcome | Outcome of an audited operation. |
LicenseAuditEntry :: fn new(event : LicenseAuditEvent, status : LicenseStatus, outcome : AuditOutcome) -> Self | Creates a new audit entry. |
LicenseAuditEntry :: fn with_actor(mut self, actor : impl Into <String>) -> Self | Sets the actor for this entry. |
LicenseAuditEntry :: fn with_capability(mut self, capability : impl Into <String>) -> Self | Sets the capability for this entry. |
LicenseAuditEntry :: fn with_context(mut self, context : serde_json::Value) -> Self | Sets additional context. |
LicenseAuditEntry :: fn emit(self) | Emits this audit entry via tracing |
fn audit_license_loaded(status : LicenseStatus) | Emits a license loaded audit event. |
fn audit_capability_denied(capability : & str, status : LicenseStatus, actor : Option <& str>) | Emits a capability denied audit event. |
fn audit_capability_granted(capability : & str, status : LicenseStatus, actor : Option <& str>) | Emits a capability granted audit event. |
fn audit_limit_exceeded(limit_name : & str, current : u64, maximum : u64, status : LicenseStatus, actor : Option <& str>,) | Emits a limit exceeded audit event. |
`enforcement`
| Item | What it is |
|---|---|
fn enforce_capability(capability : & str, actor : Option <& str>) -> LicenseResult <()> | Enforces a required capability at the service layer |
fn enforce_limit(limit_name : & str, current_value : u64, actor : Option <& str>,) -> LicenseResult <()> | Enforces a limit capability at the service layer |
fn has_capability(capability : & str) -> bool | Checks if a capability is available without enforcing |
fn license_status() -> LicenseStatus | Returns the current license status. |
fn is_licensed() -> bool | Returns true if the license allows normal operations. |
pub struct EnforcementDenial | Enforcement result for API responses. |
EnforcementDenial :: fn from(error : & LicenseError) -> Self | — |
pub struct CapabilityGuard | Guard type for service-level enforcement |
CapabilityGuard :: fn acquire(capability : & str, actor : Option <& str>) -> LicenseResult <Self> | Attempts to create a capability guard |
CapabilityGuard :: fn capability(& self) -> & str | Returns the capability this guard protects. |
`error`
| Item | What it is |
|---|---|
pub enum LicenseError | Primary error type for license operations. |
LicenseError :: fn error_code(& self) -> & 'static str | Returns a stable error code for API responses. |
LicenseError :: fn required_capability(& self) -> Option <& str> | Returns the capability that was required (if applicable). |
LicenseError :: fn license_status(& self) -> LicenseStatus | Returns the license status associated with this error. |
LicenseError :: fn user_message(& self) -> & str | Returns a human-readable message suitable for end users |
pub type LicenseResult<T>: Result <T, LicenseError> | Result type alias for license operations. |
`hardware`
| Item | What it is |
|---|---|
pub struct HardwareBinding | The licensed host fingerprint carried inside a signed license — component HMAC digests (never raw values), mirroring operations_host_inventory::MachineFingerprint. |
pub const ACCEPT_THRESHOLD: u32 | Minimum matched score to accept a node-lock (of a max 125) |
pub struct HardwareMatch | Result of scoring an observed fingerprint against a licensed HardwareBinding. |
fn match_hardware(licensed : & HardwareBinding, observed : & BTreeMap <String, String>,) -> HardwareMatch | Score an observed fingerprint (component→digest) against a licensed binding. |
pub enum AccessMode | The access mode a license grants right now (grace-then-fail, ADR 0018). |
pub struct Entitlement | The evaluated entitlement |
Entitlement :: fn emergency(reason : impl Into <String>) -> Self | The safe fallback: paid capabilities OFF, evidence access ON |
fn evaluate(payload : & LicensePayload, signature_valid : bool, observed : Option <& BTreeMap <String, String>>, now : DateTime <Utc>, hardware_grace_until : Option <DateTime <Utc>>,) -> Entitlement | Evaluate the entitlement for a license under the grace-then-fail policy |
`middleware`
| Item | What it is |
|---|---|
pub struct LicenseErrorResponse | Response type for license enforcement errors. |
LicenseErrorResponse :: fn into_response(self) -> Response | — |
LicenseErrorResponse :: fn from(error : LicenseError) -> Self | — |
async fn require_valid_license(request : Request, next : Next) -> Response | Middleware that requires a valid license for all routes |
fn require_capability_middleware(capability : & 'static str,) -> impl Fn(Request, Next) -> std::pin::Pin <Box <dyn std::future::Future <Output = Response> + Send>> + Clone + Send + 'static | Creates middleware that requires a specific capability |
pub struct RequireCapability | Extractor that validates a capability before handling a request |
RequireCapability :: async fn from_request_parts(_parts : & mut axum::http::request::Parts, _state : & S,) -> Result <Self, Self::Rejection> | — |
pub trait LicenseRouterExt | Extension trait for Router to add license-protected routes. |
axum::Router<S> :: fn require_license(self) -> Self | — |
axum::Router<S> :: fn require_capability(self, capability : & 'static str) -> Self | — |
`state`
| Item | What it is |
|---|---|
pub struct LicenseState | The loaded license state |
LicenseState :: fn status(& self) -> LicenseStatus | Returns the current license status. |
LicenseState :: fn is_valid(& self) -> bool | Returns true if the license is valid for normal operations. |
LicenseState :: fn has_capability(& self, cap : & str) -> bool | Checks if the license has a specific capability |
LicenseState :: fn require(& self, cap : & str) -> LicenseResult <()> | Requires a specific capability, returning an error if not available |
LicenseState :: fn limit(& self, name : & str) -> Option <u64> | Returns the value of a limit capability. |
LicenseState :: fn check_limit(& self, name : & str, current : u64) -> LicenseResult <()> | Checks if the current value exceeds a limit |
LicenseState :: fn expires_at(& self) -> Option <DateTime <Utc>> | Returns when the license expires (None for perpetual or missing). |
LicenseState :: fn license_id(& self) -> Option <uuid::Uuid> | Returns the license ID (if loaded). |
LicenseState :: fn customer_id(& self) -> Option <& str> | Returns the customer ID (if loaded). |
LicenseState :: fn loaded_at(& self) -> DateTime <Utc> | Returns when the license was loaded. |
LicenseState :: fn enabled_modules(& self) -> Vec <& str> | Returns the list of enabled modules. |
LicenseState :: fn enabled_features(& self) -> Vec <& str> | Returns the list of enabled features. |
LicenseState :: fn limits(& self) -> std::collections::HashMap <String, u64> | Returns all limits as a map. |
fn initialize_license(path : impl AsRef <Path>, public_key : & u8; 32, environment : Option <& str>,) -> & 'static LicenseState | Initializes the global license state from a file |
fn get_license() -> & 'static LicenseState | Gets the global license state |
fn try_get_license() -> Option <& 'static LicenseState> | Tries to get the global license state |
fn create_test_state(payload : LicensePayload) -> LicenseState | Creates a license state for testing without file I/O. |
`status`
| Item | What it is |
|---|---|
pub enum LicenseStatus | The current status of a license. |
LicenseStatus :: fn is_operational(& self) -> bool | Returns true if the license allows normal operation. |
LicenseStatus :: fn is_terminal(& self) -> bool | Returns true if the license is in a terminal invalid state. |
LicenseStatus :: fn needs_attention(& self) -> bool | Returns true if the license needs attention (expired or grace). |
LicenseStatus :: fn description(& self) -> & 'static str | Returns a human-readable description of the status. |
LicenseStatus :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result | — |
`types`
| Item | What it is |
|---|---|
pub struct Capability | A capability granted by a license |
Capability :: fn new(value : impl Into <String>) -> Self | Creates a new capability. |
Capability :: fn module(name : & str) -> Self | Creates a module capability. |
Capability :: fn feature(name : & str) -> Self | Creates a feature capability. |
Capability :: fn limit(name : & str) -> Self | Creates a limit capability. |
Capability :: fn as_str(& self) -> & str | Returns the full capability string. |
Capability :: fn namespace(& self) -> Option <& str> | Returns the namespace (part before the colon). |
Capability :: fn name(& self) -> Option <& str> | Returns the name (part after the colon). |
Capability :: fn is_module(& self) -> bool | Returns true if this is a module capability. |
Capability :: fn is_feature(& self) -> bool | Returns true if this is a feature capability. |
Capability :: fn is_limit(& self) -> bool | Returns true if this is a limit capability. |
Capability :: fn matches(& self, pattern : & str) -> bool | Checks if this capability matches a pattern |
Capability :: fn fmt(& self, f : & mut std::fmt::Formatter <'_>) -> std::fmt::Result | — |
Capability :: fn from(s : & str) -> Self | — |
Capability :: fn from(s : String) -> Self | — |
pub struct LicensePayload | The payload portion of a signed license |
LicensePayload :: fn builder(license_id : Uuid, customer_id : impl Into <String>) -> LicensePayloadBuilder | Creates a new license payload builder. |
LicensePayload :: fn has_capability(& self, cap : & str) -> bool | Checks if this license has a specific capability. |
LicensePayload :: fn limit(& self, name : & str) -> Option <u64> | Returns the value of a limit capability. |
LicensePayload :: fn modules(& self) -> impl Iterator <Item = & str> | Returns all module capabilities. |
LicensePayload :: fn features(& self) -> impl Iterator <Item = & str> | Returns all feature capabilities. |
LicensePayload :: fn is_time_valid(& self, now : DateTime <Utc>) -> bool | Checks if the license is within its validity period. |
LicensePayload :: fn is_in_grace_period(& self, now : DateTime <Utc>) -> bool | Checks if the license is in the grace period. |
LicensePayload :: fn is_revoked(& self) -> bool | Checks if the license has been revoked. |
pub struct LicensePayloadBuilder | Builder for creating license payloads. |
LicensePayloadBuilder :: fn new(license_id : Uuid, customer_id : impl Into <String>) -> Self | — |
LicensePayloadBuilder :: fn hardware(mut self, binding : crate::hardware::HardwareBinding) -> Self | Node-lock this license to a host HardwareBinding. |
LicensePayloadBuilder :: fn issued_at(mut self, issued_at : DateTime <Utc>) -> Self | — |
LicensePayloadBuilder :: fn expires_at(mut self, expires_at : DateTime <Utc>) -> Self | — |
LicensePayloadBuilder :: fn perpetual(mut self) -> Self | — |
LicensePayloadBuilder :: fn not_before(mut self, not_before : DateTime <Utc>) -> Self | — |
LicensePayloadBuilder :: fn environment(mut self, environment : impl Into <String>) -> Self | — |
LicensePayloadBuilder :: fn grace_period_days(mut self, days : u32) -> Self | — |
LicensePayloadBuilder :: fn capability(mut self, cap : impl Into <Capability>) -> Self | — |
LicensePayloadBuilder :: fn module(mut self, name : & str) -> Self | — |
LicensePayloadBuilder :: fn feature(mut self, name : & str) -> Self | — |
LicensePayloadBuilder :: fn limit(mut self, name : & str, value : u64) -> Self | — |
LicensePayloadBuilder :: fn metadata(mut self, key : impl Into <String>, value : serde_json::Value) -> Self | — |
LicensePayloadBuilder :: fn build(self) -> LicensePayload | — |
pub struct SignedLicense | A signed license artifact containing payload and signature. |
SignedLicense :: fn new(payload : & LicensePayload, signature : & u8) -> Result <Self, serde_json::Error> | Creates a new signed license from payload and signature bytes. |
SignedLicense :: fn payload_bytes(& self) -> Result <Vec <u8>, base64::DecodeError> | Decodes the payload bytes for verification. |
SignedLicense :: fn signature_bytes(& self) -> Result <Vec <u8>, base64::DecodeError> | Decodes the signature bytes for verification. |
`verification`
| Item | What it is |
|---|---|
pub const LICENSE_PUBLIC_KEY: & u8; 32 | The compiled-in public key for license verification |
fn verify_license(signed : & SignedLicense) -> LicenseResult <LicensePayload> | Verifies a signed license and extracts the payload |
fn verify_license_with_key(signed : & SignedLicense, public_key : & u8; 32,) -> LicenseResult <LicensePayload> | Verifies a signed license with a specific public key |
fn sign_license(payload : & LicensePayload, signing_key : & foundation_crypto_sign::SigningKey,) -> LicenseResult <SignedLicense> | Signs a license payload with a private key |
fn generate_keypair() ->(foundation_crypto_sign::SigningKey, foundation_crypto_sign::VerifyingKey,) | Generates a new Ed25519 keypair for license signing |
Re-exports. Exported here, defined elsewhere.
| Export | Defined in |
|---|---|
Capability | crate::types::Capability |
LICENSE_PUBLIC_KEY | verification::LICENSE_PUBLIC_KEY |
LicenseRouterExt | crate::middleware::LicenseRouterExt |
LicenseStatus | crate::status::LicenseStatus |
LicenseStatus | status::LicenseStatus |
{Capability,LicensePayload,SignedLicense} | types::{Capability,LicensePayload,SignedLicense} |
{CapabilityCheckResponse,LicenseStatusResponse,LimitSummary} | api::{CapabilityCheckResponse,LicenseStatusResponse,LimitSummary} |
{LicenseError,LicenseResult} | crate::error::{LicenseError,LicenseResult} |
{LicenseError,LicenseResult} | error::{LicenseError,LicenseResult} |
{audit_capability_denied,audit_capability_granted,audit_license_loaded,audit_limit_exceeded,AuditOutcome,LicenseAuditEntry,LicenseAuditEvent,} | audit::{audit_capability_denied,audit_capability_granted,audit_license_loaded,audit_limit_exceeded,AuditOutcome,LicenseAuditEntry,LicenseAuditEvent,} |
{enforce_capability,enforce_limit,has_capability,is_licensed,license_status,CapabilityGuard,EnforcementDenial,} | enforcement::{enforce_capability,enforce_limit,has_capability,is_licensed,license_status,CapabilityGuard,EnforcementDenial,} |
{enforce_capability,enforce_limit,has_capability,is_licensed} | crate::enforcement::{enforce_capability,enforce_limit,has_capability,is_licensed} |
{evaluate,match_hardware,AccessMode,Entitlement,HardwareBinding,HardwareMatch,ACCEPT_THRESHOLD,} | hardware::{evaluate,match_hardware,AccessMode,Entitlement,HardwareBinding,HardwareMatch,ACCEPT_THRESHOLD,} |
{get_license,initialize_license,try_get_license,LicenseState} | state::{get_license,initialize_license,try_get_license,LicenseState} |
{get_license,initialize_license} | crate::state::{get_license,initialize_license} |
{require_capability_middleware,require_valid_license,LicenseErrorResponse,LicenseRouterExt,} | middleware::{require_capability_middleware,require_valid_license,LicenseErrorResponse,LicenseRouterExt,} |
Boundary
Depends on no other workspace tier.
Shares tier foundation with 27 other crates: foundation-audit-log, foundation-basemodels, foundation-bounded-io, foundation-conversation-closure, foundation-crypto-sign, foundation-decisioning, foundation-encounter-vocabulary, foundation-fs-metadata, … (27 total).
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | foundation |
| Architectural role (taxonomy) | unclassified (baselined) |
| Location | crates/foundation/license |
| Vocabulary in force (lexicon) | current |
Dependencies
Runtime, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `foundation-crypto-sign` | foundation | no | always |
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
async-trait | ^0.1 | — | no | always |
axum | ^0.7 | multipart | yes | always |
base64 | ^0.22 | — | no | always |
chrono | ^0.4 | serde | no | always |
rand | ^0.8 | — | no | always |
serde | ^1 | derive | no | always |
serde_json | ^1 | — | no | always |
thiserror | ^2 | — | no | always |
tokio | ^1 | full | no | always |
tracing | ^0.1 | — | no | always |
uuid | ^1 | v4, v7, serde, js | no | always |
Development, in this workspace.
| Crate | Tier | Optional | Only on |
|---|---|---|---|
| `foundation-crypto-sign` | foundation | no | always |
Development, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
ed25519-dalek | ^2 | — | no | always |
tokio-test | ^0.4 | — | no | always |
Build. None.
Depended on by. 1 workspace crate.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_application_license["application-license"] -->|uses| SELF SELF["foundation-license"] SELF -->|development| n_foundation_crypto_sign["foundation-crypto-sign"] SELF -->|runtime| n_foundation_crypto_sign["foundation-crypto-sign"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
| Feature | Enables | On by default |
|---|---|---|
axum | dep:axum | no |
default | — | yes |
keygen | foundation-crypto-sign/keygen | no |
signing | — | no |
flowchart LR n_axum["axum"] --> n_dep_axum["dep:axum"] n_default["default"] n_keygen["keygen"] --> n_foundation_crypto_sign_keygen["foundation-crypto-sign/keygen"] n_signing["signing"]
Targets
| Kind | Name | Source |
|---|---|---|
| lib | foundation_license | `src/lib.rs` |
Error model
| Error type | Named by |
|---|---|
LicenseError | LicenseErrorResponse, LicenseResult |
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | yes |
| async runtime | yes |
| database access | none detected |
| network I/O | yes |
| unsafe code | none detected |
| environment variables | none detected |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
No environment variable is read with a literal name anywhere in this crate. A variable whose key is computed at run time cannot be listed here, and is not claimed to be absent.
Related capabilities
1 workspace crate depends on this one: application-license.
Verification
| Kind | Count |
|---|---|
| Unit tests | 43 |
| Integration tests | 0 |
| Examples | 0 |
| Doctests | 1 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
api | 3 | 0 | 0 |
api::handlers | 2 | 0 | 0 |
audit | 7 | 0 | 0 |
enforcement | 7 | 0 | 0 |
error | 2 | 0 | 0 |
hardware | 7 | 0 | 5 |
middleware | 5 | 0 | 0 |
state | 5 | 0 | 0 |
status | 1 | 0 | 0 |
types | 4 | 0 | 2 |
verification | 5 | 0 | 3 |
What the tests establish, by name:
test_capability_check_response—src/api.rstest_status_response_serialization—src/api.rstest_audit_entry_serialization—src/audit.rstest_audit_events_are_complete—src/audit.rstest_capability_guard_holds_capability—src/enforcement.rstest_enforcement_denial_serialization—src/enforcement.rstest_error_codes_are_stable—src/error.rstest_user_messages_are_neutral—src/error.rsanchors_gone_rejects_even_if_score_via_nonanchors—src/hardware.rsevidence_access_is_always_true—src/hardware.rsexact_match_accepts—src/hardware.rsexpired_beyond_grace_is_emergency_caps_off—src/hardware.rsexpired_within_grace_is_grace_caps_on—src/hardware.rshardware_mismatch_in_grace_then_rebind—src/hardware.rsone_swapped_secondary_still_accepts—src/hardware.rsprobe_failure_does_not_disable_caps—src/hardware.rsvalid_and_matching_is_normal—src/hardware.rstest_capability_wildcard_matching—src/lib.rstest_enforcement_denial_includes_required_fields—src/lib.rstest_error_codes_are_stable—src/lib.rstest_license_payload_roundtrip—src/lib.rstest_license_status_transitions—src/lib.rstest_error_response_serialization—src/middleware.rstest_enabled_modules_and_features—src/state.rstest_expired_license_state—src/state.rstest_grace_period_state—src/state.rstest_missing_license_state—src/state.rstest_valid_license_state—src/state.rstest_is_operational—src/status.rstest_is_terminal—src/status.rs- _… 13 more_
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 102 | 125 |
Public modules with a //! block | 11 | 12 |
pie showData
title Public items with rustdoc
"Documented" : 102
"No rustdoc detected" : 23
Metrics
| Metric | Value |
|---|---|
| Rust source files | 11 |
| Source lines | 3160 |
| Code lines | 2124 |
| Public API items | 125 |
| Public modules | 12 |
| Tests | 43 |
| Examples | 0 |
| Cargo features | 4 |
| Direct runtime dependencies | 12 |
| Workspace reverse dependencies | 1 |
pie showData
title Public API by kind
"constant" : 2
"enum" : 5
"function" : 23
"method" : 77
"struct" : 16
"trait" : 1
"type alias" : 1
pie showData
title Rust source composition
"Code" : 2124
"Blank or comment" : 1036
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.