agent-authority 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/LICENSE +21 -0
  3. package/QUICKSTART.md +91 -0
  4. package/README.md +553 -0
  5. package/dist/a2a.d.ts +73 -0
  6. package/dist/a2a.d.ts.map +1 -0
  7. package/dist/a2a.js +117 -0
  8. package/dist/a2a.js.map +1 -0
  9. package/dist/audit.d.ts +12 -0
  10. package/dist/audit.d.ts.map +1 -0
  11. package/dist/audit.js +52 -0
  12. package/dist/audit.js.map +1 -0
  13. package/dist/behalf.d.ts +173 -0
  14. package/dist/behalf.d.ts.map +1 -0
  15. package/dist/behalf.js +475 -0
  16. package/dist/behalf.js.map +1 -0
  17. package/dist/capability.d.ts +56 -0
  18. package/dist/capability.d.ts.map +1 -0
  19. package/dist/capability.js +176 -0
  20. package/dist/capability.js.map +1 -0
  21. package/dist/cli.d.ts +3 -0
  22. package/dist/cli.d.ts.map +1 -0
  23. package/dist/cli.js +273 -0
  24. package/dist/cli.js.map +1 -0
  25. package/dist/control-plane.d.ts +57 -0
  26. package/dist/control-plane.d.ts.map +1 -0
  27. package/dist/control-plane.js +332 -0
  28. package/dist/control-plane.js.map +1 -0
  29. package/dist/crypto.d.ts +68 -0
  30. package/dist/crypto.d.ts.map +1 -0
  31. package/dist/crypto.js +105 -0
  32. package/dist/crypto.js.map +1 -0
  33. package/dist/errors.d.ts +25 -0
  34. package/dist/errors.d.ts.map +1 -0
  35. package/dist/errors.js +40 -0
  36. package/dist/errors.js.map +1 -0
  37. package/dist/index.d.ts +35 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +34 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/lint.d.ts +17 -0
  42. package/dist/lint.d.ts.map +1 -0
  43. package/dist/lint.js +75 -0
  44. package/dist/lint.js.map +1 -0
  45. package/dist/mandate.d.ts +99 -0
  46. package/dist/mandate.d.ts.map +1 -0
  47. package/dist/mandate.js +141 -0
  48. package/dist/mandate.js.map +1 -0
  49. package/dist/mcp-server.d.ts +26 -0
  50. package/dist/mcp-server.d.ts.map +1 -0
  51. package/dist/mcp-server.js +111 -0
  52. package/dist/mcp-server.js.map +1 -0
  53. package/dist/mcp.d.ts +63 -0
  54. package/dist/mcp.d.ts.map +1 -0
  55. package/dist/mcp.js +123 -0
  56. package/dist/mcp.js.map +1 -0
  57. package/dist/persist.d.ts +51 -0
  58. package/dist/persist.d.ts.map +1 -0
  59. package/dist/persist.js +150 -0
  60. package/dist/persist.js.map +1 -0
  61. package/dist/quickstart.d.ts +63 -0
  62. package/dist/quickstart.d.ts.map +1 -0
  63. package/dist/quickstart.js +171 -0
  64. package/dist/quickstart.js.map +1 -0
  65. package/dist/remote.d.ts +93 -0
  66. package/dist/remote.d.ts.map +1 -0
  67. package/dist/remote.js +120 -0
  68. package/dist/remote.js.map +1 -0
  69. package/dist/seal.d.ts +12 -0
  70. package/dist/seal.d.ts.map +1 -0
  71. package/dist/seal.js +96 -0
  72. package/dist/seal.js.map +1 -0
  73. package/dist/store.d.ts +119 -0
  74. package/dist/store.d.ts.map +1 -0
  75. package/dist/store.js +139 -0
  76. package/dist/store.js.map +1 -0
  77. package/dist/types.d.ts +173 -0
  78. package/dist/types.d.ts.map +1 -0
  79. package/dist/types.js +17 -0
  80. package/dist/types.js.map +1 -0
  81. package/llms.txt +106 -0
  82. package/package.json +107 -0
  83. package/schemas/capability.schema.json +14 -0
  84. package/schemas/mandate.schema.json +68 -0
  85. package/vectors/mandate-vector.json +63 -0
package/dist/behalf.js ADDED
@@ -0,0 +1,475 @@
1
+ import { newKeyPair, newId, signBlock, verifyBlock, exportPublicKey, importPublicKey, importPrivateKey, signProof, verifyProof, signMessage, verifyMessage, canonicalJson, } from "./crypto.js";
2
+ import { parse, satisfies, isNarrowing, windowMs, } from "./capability.js";
3
+ import { verify as verifyAudit, GENESIS } from "./audit.js";
4
+ import { MemoryAuditStore, MemoryRevocationStore, MemoryRateStore, } from "./store.js";
5
+ import { Mandate } from "./mandate.js";
6
+ import { unseal } from "./seal.js";
7
+ import { AuthorizationError, BehalfError, IntegrityError, WideningError } from "./errors.js";
8
+ const DURATION_RE = /^(\d+(?:\.\d+)?)(ms|s|m|h|d)$/;
9
+ function toMs(d) {
10
+ if (typeof d === "number")
11
+ return d;
12
+ const m = DURATION_RE.exec(d.trim());
13
+ if (!m)
14
+ throw new Error(`invalid duration "${d}" (use e.g. "1h", "10m", "30s")`);
15
+ const n = Number(m[1]);
16
+ const unit = { ms: 1, s: 1000, m: 60_000, h: 3_600_000, d: 86_400_000 };
17
+ return n * unit[m[2]];
18
+ }
19
+ /**
20
+ * The Behalf engine: holds the issuer keypair and the revocation / audit stores,
21
+ * and implements the five verbs. Use the default singleton via the static
22
+ * facade (`Behalf.grant`, ...) or construct an isolated instance with
23
+ * `createBehalf()`. A verify-only engine (no grant) is made with
24
+ * `createBehalf({ trust: [issuerPublicKey] })` and a generated throwaway key.
25
+ */
26
+ export class Behalf {
27
+ rootKeyPair;
28
+ agentKey;
29
+ trusted;
30
+ revocations;
31
+ auditStore;
32
+ rateStore;
33
+ proofSkewMs;
34
+ requireNonce;
35
+ /** Outstanding single-use challenges: nonce → expiry (ms). */
36
+ nonces = new Map();
37
+ now;
38
+ constructor(config = {}) {
39
+ this.rootKeyPair = config.rootKeyPair ?? newKeyPair();
40
+ this.agentKey = config.agentKey;
41
+ this.trusted = new Set(config.trust ?? []);
42
+ this.trusted.add(exportPublicKey(this.rootKeyPair.publicKey));
43
+ this.revocations = config.revocations ?? new MemoryRevocationStore();
44
+ this.auditStore = config.audit ?? new MemoryAuditStore();
45
+ this.rateStore = config.rate ?? new MemoryRateStore();
46
+ this.proofSkewMs = config.proofSkewMs ?? 300_000;
47
+ this.requireNonce = config.requireNonce ?? false;
48
+ this.now = config.now ?? (() => Date.now());
49
+ }
50
+ /**
51
+ * Issue a single-use challenge nonce. The holder binds it into its possession
52
+ * proof (`prove(action, { nonce })`); `authorize` consumes it, so that proof
53
+ * can never be replayed — even within the freshness window.
54
+ */
55
+ challenge() {
56
+ const nonce = newId();
57
+ this.nonces.set(nonce, this.now() + this.proofSkewMs);
58
+ return nonce;
59
+ }
60
+ /** This engine's issuer public key (base64url SPKI). Share it with verifiers. */
61
+ get publicKey() {
62
+ return exportPublicKey(this.rootKeyPair.publicKey);
63
+ }
64
+ /**
65
+ * This engine's agent-identity public key (base64url), or undefined if none is
66
+ * configured. Hand it to a granter so they can `bindAgent` a mandate to you;
67
+ * only an engine holding the matching private key can then authorize it.
68
+ */
69
+ get agentPublicKey() {
70
+ return this.agentKey ? exportPublicKey(this.agentKey.publicKey) : undefined;
71
+ }
72
+ /** GRANT — a principal authorizes an agent: scoped, capped, short-lived. */
73
+ grant(opts) {
74
+ const id = newId();
75
+ const next = newKeyPair();
76
+ const block = {
77
+ caveats: [
78
+ { t: "principal", principal: opts.principal },
79
+ { t: "agent", agent: opts.agent },
80
+ { t: "cap", can: opts.can },
81
+ { t: "expires", at: this.now() + toMs(opts.expiresIn) },
82
+ ...(opts.bindAgent ? [{ t: "agentKey", key: opts.bindAgent }] : []),
83
+ ],
84
+ nextPub: exportPublicKey(next.publicKey),
85
+ };
86
+ const sig = signBlock(this.rootKeyPair.privateKey, block);
87
+ const token = {
88
+ v: 2,
89
+ id,
90
+ blocks: [block],
91
+ sigs: [sig],
92
+ rootPub: this.publicKey,
93
+ };
94
+ return new Mandate(token, this, next.privateKey);
95
+ }
96
+ /** ATTENUATE — narrow a mandate for a sub-agent. Never widens. */
97
+ attenuate(token, delegationKey, opts) {
98
+ if (!delegationKey) {
99
+ throw new BehalfDelegationError();
100
+ }
101
+ this.verifySignature(token);
102
+ const parentCans = capsFromToken(token);
103
+ const caveats = [];
104
+ if (opts.can) {
105
+ const check = isNarrowing(parentCans, opts.can);
106
+ if (!check.ok)
107
+ throw new WideningError(check.offending);
108
+ caveats.push({ t: "cap", can: opts.can });
109
+ }
110
+ if (opts.expiresIn !== undefined) {
111
+ caveats.push({ t: "expires", at: this.now() + toMs(opts.expiresIn) });
112
+ }
113
+ if (opts.agent) {
114
+ caveats.push({ t: "agent", agent: opts.agent });
115
+ }
116
+ if (opts.bindAgent) {
117
+ caveats.push({ t: "agentKey", key: opts.bindAgent });
118
+ }
119
+ // A fresh id makes this link individually revocable; it stays downstream of
120
+ // the parent, so revoking the parent still kills it.
121
+ caveats.push({ t: "id", id: newId() });
122
+ const next = newKeyPair();
123
+ const block = { caveats, nextPub: exportPublicKey(next.publicKey) };
124
+ const sig = signBlock(delegationKey, block);
125
+ const newToken = {
126
+ v: 2,
127
+ id: token.id,
128
+ blocks: [...token.blocks, block],
129
+ sigs: [...token.sigs, sig],
130
+ rootPub: token.rootPub,
131
+ };
132
+ return new Mandate(newToken, this, next.privateKey);
133
+ }
134
+ /**
135
+ * Mint a possession proof for `token` using `delegationKey` (the holder's
136
+ * terminal key). Throws if the key is absent — you cannot act on a mandate you
137
+ * only hold the public token for.
138
+ */
139
+ provePossession(token, delegationKey, action, nonce, agentKeys) {
140
+ const ts = this.now();
141
+ const agentSigs = (agentKeys ?? []).map((k) => signProof(k, token.id, token.sigs, ts, action, nonce ?? ""));
142
+ return {
143
+ ts,
144
+ sig: signProof(delegationKey, token.id, token.sigs, ts, action, nonce ?? ""),
145
+ ...(nonce !== undefined ? { nonce } : {}),
146
+ ...(agentSigs.length ? { agentSigs } : {}),
147
+ };
148
+ }
149
+ /** Holder path: `mandate.authorize()` routes here, minting a PoP from its key. */
150
+ async authorizeAsHolder(token, action, delegationKey) {
151
+ if (!delegationKey)
152
+ throw new BehalfDelegationError();
153
+ // In-process the engine is its own verifier, so it can self-issue a nonce.
154
+ const nonce = this.requireNonce ? this.challenge() : undefined;
155
+ // If this engine carries an agent identity, prove it too, satisfying any
156
+ // agentKey caveat bound to us.
157
+ const agentKeys = this.agentKey ? [this.agentKey.privateKey] : [];
158
+ return this.authorize(token, action, this.provePossession(token, delegationKey, action, nonce, agentKeys));
159
+ }
160
+ /**
161
+ * AUTHORIZE — verify a token, prove the presenter possesses the chain's
162
+ * terminal key, then check a concrete action. The `proof` is required: it
163
+ * binds the presenter to the exact (untruncated) chain and a fresh timestamp,
164
+ * which is what closes trailing-block truncation and stops a serialized token
165
+ * from being a reusable bearer credential. Produce one with `provePossession`
166
+ * (or, across the wire, `agent-authority/a2a`'s `present`).
167
+ */
168
+ async authorize(token, action, proof) {
169
+ const chain = chainIds(token);
170
+ const deny = async (reason) => {
171
+ await this.auditStore.record({
172
+ mandateId: chain[chain.length - 1],
173
+ issuer: token.rootPub,
174
+ chain,
175
+ action,
176
+ decision: "deny",
177
+ reason,
178
+ });
179
+ throw new AuthorizationError(action, reason);
180
+ };
181
+ // 1. Signature chain integrity (offline, public-key only).
182
+ try {
183
+ this.verifySignature(token);
184
+ }
185
+ catch (e) {
186
+ return deny(e instanceof IntegrityError ? e.message : "invalid signature");
187
+ }
188
+ // 2. Proof of possession of the chain's terminal key (anti-truncation).
189
+ if (!proof)
190
+ return deny("possession proof required");
191
+ if (Math.abs(this.now() - proof.ts) > this.proofSkewMs)
192
+ return deny("stale possession proof");
193
+ // 2b. Single-use nonce: consumed on first use, so a captured proof can
194
+ // never be replayed. Mandatory when the engine is configured requireNonce.
195
+ if (proof.nonce !== undefined) {
196
+ const expiry = this.nonces.get(proof.nonce);
197
+ if (expiry === undefined || this.now() > expiry) {
198
+ return deny("unknown or already-used nonce");
199
+ }
200
+ this.nonces.delete(proof.nonce);
201
+ }
202
+ else if (this.requireNonce) {
203
+ return deny("nonce required (request one via challenge())");
204
+ }
205
+ const terminal = importPublicKey(token.blocks[token.blocks.length - 1].nextPub);
206
+ if (!verifyProof(terminal, token.id, token.sigs, proof.ts, action, proof.sig, proof.nonce ?? "")) {
207
+ return deny("invalid possession proof");
208
+ }
209
+ // 2c. Conjunctive agent-identity binding (C3, SVID-style). Every agentKey
210
+ // caveat in the chain must be satisfied by an agent signature over the same
211
+ // proof message. A credential thief lacks these private keys and cannot
212
+ // strip a signed caveat, so the binding cannot be bypassed; appending one's
213
+ // own binding only adds a further requirement, never removes the original.
214
+ const agentSigs = proof.agentSigs ?? [];
215
+ for (const c of allCaveats(token)) {
216
+ if (c.t !== "agentKey")
217
+ continue;
218
+ const agentPub = importPublicKey(c.key);
219
+ const satisfied = agentSigs.some((s) => verifyProof(agentPub, token.id, token.sigs, proof.ts, action, s, proof.nonce ?? ""));
220
+ if (!satisfied)
221
+ return deny("agent identity proof required");
222
+ }
223
+ // 3. Revocation + expiry + scope (shared with inspect()).
224
+ const ev = await this.evaluate(token, action);
225
+ if (!ev.ok)
226
+ return deny(ev.reason);
227
+ // 4. Rate limits (sliding window; shareable via the rate store).
228
+ if (ev.matched?.rate) {
229
+ const key = `${chain[0]}|${ev.request.verb}:${ev.request.resource}`;
230
+ const allowed = await this.rateStore.hit(key, windowMs(ev.matched.rate.per), ev.matched.rate.value, this.now());
231
+ if (!allowed) {
232
+ return deny(`rate limit exceeded (${ev.matched.rate.value}/${ev.matched.rate.per})`);
233
+ }
234
+ }
235
+ await this.auditStore.record({
236
+ mandateId: chain[chain.length - 1],
237
+ issuer: token.rootPub,
238
+ chain,
239
+ action,
240
+ decision: "allow",
241
+ });
242
+ }
243
+ /**
244
+ * INSPECT — advisory check of signature, revocation, expiry, and scope WITHOUT
245
+ * a possession proof. Use for "would this token allow X?" tooling (CLI,
246
+ * dashboards, `check_authority`). It does NOT prove the caller holds the
247
+ * mandate, does not consume rate budget, and writes no audit record — never
248
+ * gate a real action on it; use `authorize` for that.
249
+ */
250
+ async inspect(token, action) {
251
+ const ev = await this.evaluate(token, action);
252
+ return ev.ok ? { allowed: true } : { allowed: false, reason: ev.reason };
253
+ }
254
+ /** Shared signature + revocation + expiry + scope check (no PoP, no side effects). */
255
+ async evaluate(token, action) {
256
+ try {
257
+ this.verifySignature(token);
258
+ }
259
+ catch (e) {
260
+ return { ok: false, reason: e instanceof IntegrityError ? e.message : "invalid signature" };
261
+ }
262
+ for (const id of chainIds(token)) {
263
+ if (await this.revocations.isRevoked(id))
264
+ return { ok: false, reason: `revoked (${id})` };
265
+ }
266
+ const caveats = allCaveats(token);
267
+ const now = this.now();
268
+ for (const c of caveats) {
269
+ if (c.t === "expires" && now > c.at)
270
+ return { ok: false, reason: "expired" };
271
+ }
272
+ let request;
273
+ try {
274
+ request = parse(action);
275
+ }
276
+ catch (e) {
277
+ return { ok: false, reason: e.message };
278
+ }
279
+ let matched;
280
+ for (const c of caveats) {
281
+ if (c.t !== "cap")
282
+ continue;
283
+ const grant = c.can.map(parse).find((g) => satisfies(g, request));
284
+ if (!grant)
285
+ return { ok: false, reason: `"${action}" not within granted scope` };
286
+ if (grant.rate)
287
+ matched = grant;
288
+ }
289
+ return { ok: true, matched, request };
290
+ }
291
+ /** REVOKE — kill a mandate (and, transitively, everything downstream). */
292
+ async revoke(id) {
293
+ await this.revocations.revoke(id);
294
+ }
295
+ /** AUDIT — fetch the hash-chained audit trail for a mandate's chain. */
296
+ async audit(id) {
297
+ return this.auditStore.forMandate(id);
298
+ }
299
+ /** Verify the integrity of the entire audit log. */
300
+ async verifyAuditLog() {
301
+ return verifyAudit(await this.auditStore.all());
302
+ }
303
+ /**
304
+ * Sign an anchor over the audit log's current head (C4). Store checkpoints
305
+ * somewhere the log's writer can't reach (another host, object storage, a
306
+ * ledger): a later `verifyAuditCheckpoint` then detects tail-deletion and
307
+ * full-chain rewrites, which the unkeyed hash chain alone cannot.
308
+ */
309
+ async checkpointAudit() {
310
+ const entries = await this.auditStore.all();
311
+ const head = entries[entries.length - 1];
312
+ const body = { seq: head?.seq ?? -1, hash: head?.hash ?? GENESIS, ts: this.now() };
313
+ return {
314
+ ...body,
315
+ signer: this.publicKey,
316
+ sig: signMessage(this.rootKeyPair.privateKey, canonicalJson(body)),
317
+ };
318
+ }
319
+ /**
320
+ * Verify the log against a previously-taken checkpoint: the checkpoint's
321
+ * signature must verify under a trusted key, the chain must replay, and the
322
+ * entry at `checkpoint.seq` must still carry exactly the anchored hash.
323
+ */
324
+ async verifyAuditCheckpoint(checkpoint) {
325
+ if (!this.trusted.has(checkpoint.signer)) {
326
+ return { ok: false, reason: "checkpoint signer is not trusted" };
327
+ }
328
+ const body = { seq: checkpoint.seq, hash: checkpoint.hash, ts: checkpoint.ts };
329
+ if (!verifyMessage(importPublicKey(checkpoint.signer), canonicalJson(body), checkpoint.sig)) {
330
+ return { ok: false, reason: "invalid checkpoint signature" };
331
+ }
332
+ const entries = await this.auditStore.all();
333
+ const chain = verifyAudit(entries);
334
+ if (!chain.ok)
335
+ return { ...chain, reason: `hash chain broken at seq ${chain.brokenAt}` };
336
+ if (checkpoint.seq === -1)
337
+ return { ok: true };
338
+ const anchored = entries.find((e) => e.seq === checkpoint.seq);
339
+ if (!anchored || anchored.hash !== checkpoint.hash) {
340
+ return { ok: false, reason: "anchored entry missing or rewritten (tail deletion / rewrite)" };
341
+ }
342
+ return { ok: true };
343
+ }
344
+ // ---- Issuer key rotation (B5) ----
345
+ /**
346
+ * Rotate the issuer key with overlap: returns a NEW engine with a fresh
347
+ * keypair that shares this engine's stores/config and still trusts every
348
+ * previously trusted key (including the old one), so existing mandates keep
349
+ * verifying while new grants are signed by the new key. Distribute the new
350
+ * `publicKey` to verifiers, wait out the longest outstanding mandate expiry,
351
+ * then end the overlap with `untrustKey(oldPublicKey)`.
352
+ */
353
+ rotate() {
354
+ return new Behalf({
355
+ rootKeyPair: newKeyPair(),
356
+ agentKey: this.agentKey,
357
+ trust: [...this.trusted],
358
+ revocations: this.revocations,
359
+ audit: this.auditStore,
360
+ rate: this.rateStore,
361
+ proofSkewMs: this.proofSkewMs,
362
+ requireNonce: this.requireNonce,
363
+ now: this.now,
364
+ });
365
+ }
366
+ /** Currently trusted issuer public keys (own key included). */
367
+ get trustedKeys() {
368
+ return [...this.trusted];
369
+ }
370
+ /** Trust an additional issuer key (e.g. a peer's, or a pre-staged next key). */
371
+ trustKey(publicKey) {
372
+ this.trusted.add(publicKey);
373
+ }
374
+ /** End a rotation overlap. Refuses to remove this engine's own key. */
375
+ untrustKey(publicKey) {
376
+ if (publicKey === this.publicKey) {
377
+ throw new BehalfError("cannot untrust this engine's own key");
378
+ }
379
+ return this.trusted.delete(publicKey);
380
+ }
381
+ /**
382
+ * Re-hydrate a Mandate from a serialized string. Accepts both forms:
383
+ * - `serialize()` (public token) → inspect/verify only; cannot authorize,
384
+ * prove, or attenuate (no delegation key).
385
+ * - `serializeWithKey()` (token + delegation key) → a full holder credential
386
+ * that can authorize, prove, and attenuate.
387
+ */
388
+ import(serialized) {
389
+ const parsed = JSON.parse(Buffer.from(serialized, "base64url").toString("utf8"));
390
+ if ("token" in parsed && "key" in parsed) {
391
+ const token = parsed.token;
392
+ // The delegation key's public half is the chain's terminal nextPub.
393
+ const pub = token.blocks[token.blocks.length - 1].nextPub;
394
+ return new Mandate(token, this, importPrivateKey(parsed.key, pub));
395
+ }
396
+ return new Mandate(parsed, this);
397
+ }
398
+ /**
399
+ * Decrypt and import a sealed holder credential (see
400
+ * `mandate.sealForRecipient`) using the recipient's X25519 sealing keypair.
401
+ * Equivalent to `import(unseal(sealed, recipient))`.
402
+ */
403
+ importSealed(sealed, recipient) {
404
+ return this.import(unseal(sealed, recipient));
405
+ }
406
+ /**
407
+ * Throws {@link IntegrityError} if the issuer is untrusted or the Ed25519
408
+ * signature chain does not verify. Pure public-key checks — no secrets.
409
+ */
410
+ verifySignature(token) {
411
+ if (token.v !== 2)
412
+ throw new IntegrityError(`unsupported token version ${token.v}`);
413
+ if (!this.trusted.has(token.rootPub))
414
+ throw new IntegrityError("untrusted issuer");
415
+ if (token.blocks.length !== token.sigs.length)
416
+ throw new IntegrityError("malformed token");
417
+ let signerPub = importPublicKey(token.rootPub);
418
+ for (let i = 0; i < token.blocks.length; i++) {
419
+ const block = token.blocks[i];
420
+ if (!verifyBlock(signerPub, block, token.sigs[i])) {
421
+ throw new IntegrityError(`signature failed at block ${i}`);
422
+ }
423
+ signerPub = importPublicKey(block.nextPub);
424
+ }
425
+ }
426
+ // ---- Static facade over a lazily-created default instance ----
427
+ static _default;
428
+ static get default() {
429
+ return (Behalf._default ??= new Behalf());
430
+ }
431
+ /** Replace the default instance (e.g. to inject a persistent store). */
432
+ static configure(config) {
433
+ return (Behalf._default = new Behalf(config));
434
+ }
435
+ static grant(opts) {
436
+ return Behalf.default.grant(opts);
437
+ }
438
+ static revoke(id) {
439
+ return Behalf.default.revoke(id);
440
+ }
441
+ static audit(id) {
442
+ return Behalf.default.audit(id);
443
+ }
444
+ static import(serialized) {
445
+ return Behalf.default.import(serialized);
446
+ }
447
+ }
448
+ /** Thrown when attenuating a mandate that has no in-memory delegation key. */
449
+ export class BehalfDelegationError extends BehalfError {
450
+ constructor() {
451
+ super("this mandate cannot be delegated (it was imported without its delegation key)");
452
+ }
453
+ }
454
+ /** Construct an isolated engine (own key + stores). */
455
+ export function createBehalf(config = {}) {
456
+ return new Behalf(config);
457
+ }
458
+ function chainIds(token) {
459
+ const ids = [token.id];
460
+ for (const c of allCaveats(token))
461
+ if (c.t === "id")
462
+ ids.push(c.id);
463
+ return ids;
464
+ }
465
+ function allCaveats(token) {
466
+ return token.blocks.flatMap((b) => b.caveats);
467
+ }
468
+ function capsFromToken(token) {
469
+ let latest = [];
470
+ for (const c of allCaveats(token))
471
+ if (c.t === "cap")
472
+ latest = c.can;
473
+ return latest;
474
+ }
475
+ //# sourceMappingURL=behalf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"behalf.js","sourceRoot":"","sources":["../src/behalf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Capability grammar.
3
+ *
4
+ * read:calendar simple capability
5
+ * write:repo/acme-app resource-scoped (path segments)
6
+ * spend:usd<=50 quantitative limit
7
+ * send:email rate<=10/h rate limit
8
+ * * wildcard (discouraged; lint warns)
9
+ *
10
+ * A capability is `<verb>:<resource>[<op><amount>] [<key><op><value>[/<unit>]]`.
11
+ */
12
+ export type Op = "<=" | ">=" | "<" | ">" | "=";
13
+ export interface Amount {
14
+ op: Op;
15
+ value: number;
16
+ }
17
+ export interface Rate {
18
+ op: Op;
19
+ value: number;
20
+ /** Window unit: seconds, minutes, hours, days. Defaults to hours. */
21
+ per: "s" | "m" | "h" | "d";
22
+ }
23
+ export interface Capability {
24
+ raw: string;
25
+ wildcard: boolean;
26
+ verb: string;
27
+ resource: string;
28
+ /** Quantitative constraint on the resource, e.g. usd<=50. */
29
+ amount?: Amount;
30
+ /** Rate constraint, e.g. rate<=10/h. */
31
+ rate?: Rate;
32
+ }
33
+ /** Parse a capability string into structured form. Throws on malformed input. */
34
+ export declare function parse(raw: string): Capability;
35
+ /** Window length in milliseconds for a rate unit. */
36
+ export declare function windowMs(per: Rate["per"]): number;
37
+ /**
38
+ * Does the `grant` capability permit the `request` action?
39
+ *
40
+ * The request is the concrete action being attempted (e.g. `spend:usd=20`); the
41
+ * grant is the authority held (e.g. `spend:usd<=50`). Rate limits are *not*
42
+ * evaluated here — they require call history and are enforced by the engine.
43
+ */
44
+ export declare function satisfies(grant: Capability, request: Capability): boolean;
45
+ /** Convenience: parse both sides then check satisfaction. */
46
+ export declare function permits(grant: string, request: string): boolean;
47
+ /**
48
+ * Is every capability in `child` covered by some capability in `parent`?
49
+ * Used to reject widening at attenuation time (the chain enforces it too, but
50
+ * this gives a clear, early error).
51
+ */
52
+ export declare function isNarrowing(parent: string[], child: string[]): {
53
+ ok: boolean;
54
+ offending?: string;
55
+ };
56
+ //# sourceMappingURL=capability.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability.d.ts","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE/C,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,EAAE,CAAC;IACP,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,EAAE,CAAC;IACP,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;CAC5B;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,OAAO,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAMD,iFAAiF;AACjF,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAsC7C;AAED,qDAAqD;AACrD,wBAAgB,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,MAAM,CAWjD;AA4BD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAiBzE;AAED,6DAA6D;AAC7D,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAE/D;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,CAQlG"}