Skip to content

Commit 952e43c

Browse files
committed
wip
1 parent 84dc615 commit 952e43c

File tree

1 file changed

+30
-7
lines changed

1 file changed

+30
-7
lines changed

README.org

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ The library defines a few core entities:
3131
- *Strong Security*: The aggregate signature makes the entire token cryptographically tamper-proof. The =Principal= class prevents secret key leakage.
3232
- *Clean, High-Level API*: The =CapBAC= class provides simple, intuitive methods (=forgeCertificate=, =delegateCertificate=, =invoke=) that handle all the underlying cryptographic complexity.
3333
- *Flexible Capability Model*: Supports arbitrary permission types through a =CapabilityCodec= interface, allowing you to define simple string-based permissions or complex, structured capabilities.
34+
- *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.
3435
- *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.
3536

3637
-----
@@ -46,7 +47,18 @@ Here's a complete example of a root entity delegating a permission to an interme
4647
#+BEGIN_SRC java
4748
// 1. Setup the environment and Principals
4849
CapBACScheme scheme = CapBACScheme.MIN_PK;
49-
CapBAC api = new CapBAC(scheme);
50+
51+
// Define how capabilities are decoded from bytes
52+
CapabilityCodec<StringCapability> codec = new StringCapabilityCodec();
53+
54+
// Define the attenuation rule: a child capability must be
55+
// a refinement (prefix) of its parent
56+
AttenuationChecker<StringCapability> checker =
57+
(parent, child) -> child.getValue().startsWith(parent.getValue());
58+
59+
// The CapBAC API is generic over the capability type and enforces
60+
// attenuation at both creation time and verification time
61+
CapBAC<StringCapability> api = new CapBAC<>(scheme, codec, checker);
5062

5163
// In a real app, you would load or retrieve these, not generate them.
5264
Principal root = new Principal(scheme);
@@ -60,7 +72,7 @@ TrustChecker trustChecker = id -> java.util.Arrays.equals(id, root.getId());
6072
long expiration = Instant.now().getEpochSecond() + 3600; // Expires in 1 hour
6173

6274
// 2. The Root forges the initial certificate for the intermediate principal
63-
Capability readCapability = new StringCapability("read");
75+
StringCapability readCapability = new StringCapability("read");
6476
CapBACCertificate rootCertificate = api.forgeCertificate(
6577
root,
6678
intermediate.getId(),
@@ -69,11 +81,14 @@ CapBACCertificate rootCertificate = api.forgeCertificate(
6981
);
7082

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

7486

7587
// 3. The Intermediate Principal delegates a more specific capability to the User
76-
Capability fileCapability = new StringCapability("read:/data/file.txt");
88+
// "read:/data/file.txt" starts with "read", so attenuation is valid.
89+
// Trying to delegate a broader capability (e.g. "write") would throw
90+
// IllegalArgumentException.
91+
StringCapability fileCapability = new StringCapability("read:/data/file.txt");
7792
CapBACCertificate delegatedCertificate = api.delegateCertificate(
7893
intermediate,
7994
rootCertificate,
@@ -83,7 +98,7 @@ CapBACCertificate delegatedCertificate = api.delegateCertificate(
8398
);
8499

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

88103

89104
// 4. The User invokes the capability
@@ -96,13 +111,21 @@ CapBACInvocation invocationToken = api.invoke(
96111

97112
// The final invocation token is presented to a service for verification.
98113
// The service can verify the entire chain and the invocation in one step.
99-
assertTrue(invocationToken.verify(resolver, trustChecker));
114+
assertTrue(invocationToken.verify(resolver, trustChecker, codec, checker));
100115
#+END_SRC
101116

102117
-----
103118

104119
** Security Considerations
105120

121+
*** Attenuation
122+
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:
123+
124+
- *At creation time*: =delegateCertificate()= and =invoke()= check the new capability against the parent and throw =IllegalArgumentException= if attenuation is violated.
125+
- *At verification time*: =verify()= walks the full chain and checks every parent-child capability pair, returning =false= if any step escalates privileges.
126+
127+
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.
128+
106129
*** Revocation
107130
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.
108131

@@ -129,4 +152,4 @@ The project uses Maven.
129152

130153
** Dependencies
131154

132-
- [[https://github.com/ConsenSys/jblst][jblst]]: A Java wrapper for the high-performance =blst= BLS signature library.
155+
- [[https://github.com/supranational/blst][blst]]: A high-performance BLS signature library (vendored with Java bindings).

0 commit comments

Comments
 (0)