Skip to content

Latest commit

 

History

History
175 lines (120 loc) · 8.94 KB

File metadata and controls

175 lines (120 loc) · 8.94 KB

CapBAC-BLS: A Capability-Based Access Control Library using BLS Signatures

This is a high-performance, secure Java library for creating and verifying authorization tokens based on the Capability-Based Access Control (CapBAC) model. It uses advanced BLS Aggregate Signatures to ensure token integrity and provide highly efficient verification.

The library is designed with a clean, high-level API that abstracts away cryptographic complexity, making it easy to integrate a robust and modern authorization system into your application.


Core Concepts

The library is built on a few key concepts that work together to create a flexible and secure trust model.

1. Capability-Based Access Control (CapBAC)

Instead of checking an Access Control List (ACL) to see if a user has permission, the user presents a token (a capability) that directly grants them a specific permission. This token is a self-contained, verifiable proof of authorization.

2. BLS Aggregate Signatures

This is the cryptographic heart of the library. BLS signatures can be aggregated, meaning multiple signatures from different users can be combined into a single, compact signature. The magic is that this single aggregate signature can be verified against all the original signers and their messages in one single, fast operation. This makes verifying a chain of delegation extremely efficient.

3. The Actors and Tokens

The library defines a few core entities:

  • Principal: Represents an entity (a user, service, or device) that can hold permissions and sign tokens. It securely encapsulates the entity’s ID and their secret key.
  • CapBACCertificate: A delegation token. It represents a Principal granting a specific capability to another Principal. It is a verifiable proof of delegation.
  • CapBACInvocation: An action token. It is created when a Principal uses a delegated capability. It contains the full delegation chain plus a final invocation record, all bound together by an aggregate signature.

Features

  • High Performance: Uses BLS aggregate signatures for extremely fast verification of complex delegation chains.
  • Strong Security: The aggregate signature makes the entire token cryptographically tamper-proof. The Principal class prevents secret key leakage.
  • Clean, High-Level API: The CapBAC class provides simple, intuitive methods (forgeCertificate, delegateCertificate, invoke) that handle all the underlying cryptographic complexity.
  • Flexible Capability Model: Supports arbitrary permission types through a CapabilityCodec interface, allowing you to define simple string-based permissions or complex, structured capabilities.
  • Attenuation Enforcement: Capabilities are checked for valid attenuation at both creation time and verification time via the AttenuationChecker interface, preventing privilege escalation in delegation chains.
  • Implicit Revocation Model: Revocation is handled by removing a Principal’s public key from the Resolver, providing an immediate and simple way to invalidate all tokens signed by that principal.

High-Level API Usage

Using the library is straightforward. The main entry point is the CapBAC class.

Example: Forge, Delegate, and Invoke

Here’s a complete example of a root entity delegating a permission to an intermediate entity, who then delegates a more specific permission to a final user, who then invokes it.

// 1. Setup the environment and Principals
CapBACScheme scheme = CapBACScheme.MIN_PK;

// Define how capabilities are decoded from bytes
CapabilityCodec<StringCapability> codec = new StringCapabilityCodec();

// Define the attenuation rule: a child capability must be
// a refinement (prefix) of its parent
AttenuationChecker<StringCapability> checker =
    (parent, child) -> child.getValue().startsWith(parent.getValue());

// The CapBAC API is generic over the capability type and enforces
// attenuation at both creation time and verification time
CapBAC<StringCapability> api = new CapBAC<>(scheme, codec, checker);

// In a real app, you would load or retrieve these, not generate them.
Principal root = new Principal(scheme);
Principal intermediate = new Principal(scheme);
Principal user = new Principal(scheme);

// The resolver would typically be backed by a database.
Resolver resolver = id -> { /* ... logic to get public key for an id ... */ };
TrustChecker trustChecker = id -> id.equals(root.getId());

long expiration = Instant.now().getEpochSecond() + 3600; // Expires in 1 hour

// 2. The Root forges the initial certificate for the intermediate principal
StringCapability readCapability = new StringCapability("read");
CapBACCertificate rootCertificate = api.forgeCertificate(
    root,
    intermediate.getId(),
    readCapability,
    expiration
);

// The certificate is valid and can be passed to the intermediate principal.
assertTrue(rootCertificate.verify(resolver, trustChecker, codec, checker));


// 3. The Intermediate Principal delegates a more specific capability to the User
// "read:/data/file.txt" starts with "read", so attenuation is valid.
// Trying to delegate a broader capability (e.g. "write") would throw
// IllegalArgumentException.
StringCapability fileCapability = new StringCapability("read:/data/file.txt");
CapBACCertificate delegatedCertificate = api.delegateCertificate(
    intermediate,
    rootCertificate,
    user.getId(),
    fileCapability,
    expiration
);

// This new certificate is also valid and contains the full chain of trust.
assertTrue(delegatedCertificate.verify(resolver, trustChecker, codec, checker));


// 4. The User invokes the capability
CapBACInvocation invocationToken = api.invoke(
    user,
    delegatedCertificate,
    fileCapability, // The user invokes the specific capability they were granted
    expiration
);

// The final invocation token is presented to a service for verification.
// The service can verify the entire chain and the invocation in one step.
assertTrue(invocationToken.verify(resolver, trustChecker, codec, checker));

Security Considerations

Attenuation

The AttenuationChecker interface prevents privilege escalation in delegation chains. Each delegated or invoked capability must be a valid attenuation (a subset or refinement) of its parent capability. This is enforced in two places:

  • At creation time: delegateCertificate() and invoke() check the new capability against the parent and throw IllegalArgumentException if attenuation is violated.
  • At verification time: verify() walks the full chain and checks every parent-child capability pair, returning false if any step escalates privileges.

You define the attenuation rule by implementing AttenuationChecker. For example, a prefix-based rule where "read:/data/file.txt" is a valid attenuation of "read" but "write" is not.

Revocation

The library uses an implicit revocation model. Revocation is handled by the Resolver interface. In a production environment, the Resolver would be backed by a database or another key store. To revoke a Principal, you simply remove their public key from this store. Any subsequent attempt to verify a token signed by that Principal will fail because the resolver can no longer provide their public key.

Replay Attacks

The tokens include an expiration timestamp to mitigate replay attacks. For systems requiring higher security, it is recommended to embed a nonce or unique ID within the Capability object itself. The verifying service would then be responsible for tracking seen nonces to ensure a token can only be used once.


Usage Examples

The src/test/java/dev/dotfox/capbac/examples/ directory contains self-contained example tests that demonstrate real-world use cases:

  • AuthenticationExampleTest: User registration via proof-of-key, API token issuance, bot delegation, and revocation.
  • DeviceManufacturingExampleTest: 3-hop supply chain (manufacturer → factory → batch → device) with hierarchical revocation.
  • SmartHomeExampleTest: Time-limited guest access with expiry, attenuation enforcement, and chain invalidation.
  • MicroserviceAuthExampleTest: Service-to-service auth with resource + action capabilities and least-privilege delegation.
  • DocumentSharingExampleTest: Ordinal permission hierarchy (EDIT → COMMENT → VIEW) with cascading revocation.

Each example defines its own Capability type, CapabilityCodec, and AttenuationChecker as inner classes, and runs under both MIN_PK and MIN_SIG schemes.


Serialization Format

The binary wire format for CapBACCertificate and CapBACInvocation tokens is documented in docs/serialization-format.md.


Building and Testing

The project uses Maven.

  • To build the JAR file:
    mvn clean package
        
  • To run the test suite:
    mvn test
        

Dependencies

  • blst: A high-performance BLS signature library (vendored with Java bindings).