@agenticprimitives/a2a 0.0.0-alpha.19 → 0.0.0-alpha.20

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 (91) hide show
  1. package/CLAUDE.md +42 -38
  2. package/bin/a2a-conform.mjs +17 -0
  3. package/dist/agent.d.ts +9 -0
  4. package/dist/agent.d.ts.map +1 -1
  5. package/dist/agent.js +25 -8
  6. package/dist/agent.js.map +1 -1
  7. package/dist/client.d.ts +20 -11
  8. package/dist/client.d.ts.map +1 -1
  9. package/dist/client.js +69 -17
  10. package/dist/client.js.map +1 -1
  11. package/dist/conform/index.d.ts +36 -0
  12. package/dist/conform/index.d.ts.map +1 -0
  13. package/dist/conform/index.js +232 -0
  14. package/dist/conform/index.js.map +1 -0
  15. package/dist/discovery.d.ts +4 -0
  16. package/dist/discovery.d.ts.map +1 -1
  17. package/dist/discovery.js +6 -2
  18. package/dist/discovery.js.map +1 -1
  19. package/dist/engagement.d.ts +37 -0
  20. package/dist/engagement.d.ts.map +1 -0
  21. package/dist/engagement.js +83 -0
  22. package/dist/engagement.js.map +1 -0
  23. package/dist/handoff.d.ts +42 -0
  24. package/dist/handoff.d.ts.map +1 -0
  25. package/dist/handoff.js +28 -0
  26. package/dist/handoff.js.map +1 -0
  27. package/dist/index.d.ts +14 -3
  28. package/dist/index.d.ts.map +1 -1
  29. package/dist/index.js +13 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/session-wire.d.ts +69 -0
  32. package/dist/session-wire.d.ts.map +1 -0
  33. package/dist/session-wire.js +170 -0
  34. package/dist/session-wire.js.map +1 -0
  35. package/dist/standard/caller.d.ts +86 -0
  36. package/dist/standard/caller.d.ts.map +1 -0
  37. package/dist/standard/caller.js +159 -0
  38. package/dist/standard/caller.js.map +1 -0
  39. package/dist/standard/client.d.ts +50 -0
  40. package/dist/standard/client.d.ts.map +1 -0
  41. package/dist/standard/client.js +86 -0
  42. package/dist/standard/client.js.map +1 -0
  43. package/dist/standard/delegated.d.ts +119 -0
  44. package/dist/standard/delegated.d.ts.map +1 -0
  45. package/dist/standard/delegated.js +168 -0
  46. package/dist/standard/delegated.js.map +1 -0
  47. package/dist/standard/errors.d.ts +31 -0
  48. package/dist/standard/errors.d.ts.map +1 -0
  49. package/dist/standard/errors.js +75 -0
  50. package/dist/standard/errors.js.map +1 -0
  51. package/dist/standard/from-agent.d.ts +38 -0
  52. package/dist/standard/from-agent.d.ts.map +1 -0
  53. package/dist/standard/from-agent.js +109 -0
  54. package/dist/standard/from-agent.js.map +1 -0
  55. package/dist/standard/index.d.ts +9 -0
  56. package/dist/standard/index.d.ts.map +1 -0
  57. package/dist/standard/index.js +13 -0
  58. package/dist/standard/index.js.map +1 -0
  59. package/dist/standard/mount.d.ts +91 -0
  60. package/dist/standard/mount.d.ts.map +1 -0
  61. package/dist/standard/mount.js +181 -0
  62. package/dist/standard/mount.js.map +1 -0
  63. package/dist/standard/server.d.ts +105 -0
  64. package/dist/standard/server.d.ts.map +1 -0
  65. package/dist/standard/server.js +454 -0
  66. package/dist/standard/server.js.map +1 -0
  67. package/dist/standard/types.d.ts +186 -0
  68. package/dist/standard/types.d.ts.map +1 -0
  69. package/dist/standard/types.js +14 -0
  70. package/dist/standard/types.js.map +1 -0
  71. package/dist/subject-ask.d.ts +96 -0
  72. package/dist/subject-ask.d.ts.map +1 -0
  73. package/dist/subject-ask.js +45 -0
  74. package/dist/subject-ask.js.map +1 -0
  75. package/dist/subject-hop.d.ts +75 -0
  76. package/dist/subject-hop.d.ts.map +1 -0
  77. package/dist/subject-hop.js +170 -0
  78. package/dist/subject-hop.js.map +1 -0
  79. package/dist/task-store.d.ts +4 -0
  80. package/dist/task-store.d.ts.map +1 -1
  81. package/dist/task-store.js +4 -0
  82. package/dist/task-store.js.map +1 -1
  83. package/dist/wire-verify.d.ts +35 -0
  84. package/dist/wire-verify.d.ts.map +1 -0
  85. package/dist/wire-verify.js +51 -0
  86. package/dist/wire-verify.js.map +1 -0
  87. package/package.json +20 -7
  88. package/dist/jsonrpc.d.ts +0 -27
  89. package/dist/jsonrpc.d.ts.map +0 -1
  90. package/dist/jsonrpc.js +0 -81
  91. package/dist/jsonrpc.js.map +0 -1
package/dist/index.js CHANGED
@@ -24,11 +24,22 @@ export { authorizeA2aMessage, hashA2aMessage, hashA2aTaskRequest, hashPushConfig
24
24
  export { createA2aAgent } from './agent.js';
25
25
  // Card-audience authentication (spec 338 §8, W4-b) — closes the `?view=authenticated` hole.
26
26
  export { PUBLIC_AUDIENCE, createCardAudienceResolver, readCardAudienceClaim } from './card-audience.js';
27
- export { dispatchA2aRpc, handleA2aRpcBody } from './jsonrpc.js';
28
27
  export { A2aWireAdapter } from './client.js';
29
28
  // Agent discovery (§8) — name → SA → endpoint + agent-card fetch (injected resolvers, ADR-0021)
30
- export { resolveA2aTarget, fetchAgentCard } from './discovery.js';
29
+ export { resolveA2aTarget, fetchAgentCard, A2A_JSONRPC_PATH, A2A_AGENT_CARD_PATH } from './discovery.js';
31
30
  // Delivery — signed push + SSE (W4)
32
31
  export { hashPushPayload, deliverPush, verifyPushEnvelope } from './push.js';
32
+ // Spec 366 R2 / 367 §8 — the subject-ask application profile (one agent asks another to answer a step about itself).
33
+ export { AP_SUBJECT_ASK_EXTENSION_URI, validateSubjectAsk, subjectAsk, subjectAnswer } from './subject-ask.js';
34
+ // Spec 376 — the hand-off profile (one step, run elsewhere under a child mandate).
35
+ export { AP_HANDOFF_EXTENSION_URI, validateHandoff, handoff } from './handoff.js';
36
+ // Spec 384 W2 — the intent-engagement binding (spec 336 §5): probe/response as messages under one extension URI, never a task.
37
+ export { AP_ENGAGEMENT_EXTENSION_URI, ENGAGEMENT_CARD_EXTENSION, validateEngagementProbe, validateEngagementResponse, engagementProbeMessage, engagementResponseMessage, engagementOf } from './engagement.js';
33
38
  export { SSE_HEADERS, formatSseEvent, formatSseComment, isStreamEnd } from './sse.js';
39
+ // ─── Spec 350 §8 — session wires: sign as an identity you do not custody (ONE implementation) ──────
40
+ export { SESSION_WRAPPED_SIG_TYPE, wrapSessionSignature, parseSessionWrappedSignature, wireToDelegation, delegationToWire, checkSessionWireShape, verifySessionWrappedSignature, sessionBodyHash, } from './session-wire.js';
41
+ // ─── Spec 399 §4 promotions — the delegate-key tail every A2A service verifies, and the routed hop ─────
42
+ export { verifyDelegationWire, delegationOfWire } from './wire-verify.js';
43
+ // Spec 366 R4 / 374 §4 / 376 — a routed ask, a delivered answer and a hand-off over the one wire; resolved through the card.
44
+ export { a2aEndpointOf, subjectAskMessage, subjectAskOf, SUBJECT_ANSWER_ARTIFACT, routedRunRefFor, subjectEnvelopeOf, sendSubjectAskOverWire, subjectAnswerMessage, subjectAnswerOf, handoffMessage, handoffOf } from './subject-hop.js';
34
45
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,wGAAwG;AACxG,yGAAyG;AACzG,wGAAwG;AAExG,MAAM,CAAC,MAAM,YAAY,GAAG,wBAAwB,CAAC;AACrD,MAAM,CAAC,MAAM,cAAc,GAAG,4BAAqC,CAAC;AACpE,MAAM,CAAC,MAAM,QAAQ,GAAG,8CAA8C,CAAC;AAavE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAI1D,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAKxF,kGAAkG;AAClG,qGAAqG;AACrG,sGAAsG;AACtG,mEAAmE;AACnE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5E,6CAA6C;AAC7C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGhF,mCAAmC;AACnC,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,WAAW,CAAC;AAGnB,4CAA4C;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,4FAA4F;AAC5F,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAWxG,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEhE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,gGAAgG;AAChG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAGlE,oCAAoC;AACpC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE7E,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,wGAAwG;AACxG,yGAAyG;AACzG,wGAAwG;AAExG,MAAM,CAAC,MAAM,YAAY,GAAG,wBAAwB,CAAC;AACrD,MAAM,CAAC,MAAM,cAAc,GAAG,4BAAqC,CAAC;AACpE,MAAM,CAAC,MAAM,QAAQ,GAAG,8CAA8C,CAAC;AAavE,OAAO,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAIzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAI1D,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAKxF,kGAAkG;AAClG,qGAAqG;AACrG,sGAAsG;AACtG,mEAAmE;AACnE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAElC,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,4BAA4B,EAC5B,2BAA2B,EAC3B,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAE3B,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5E,6CAA6C;AAC7C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGhF,mCAAmC;AACnC,OAAO,EACL,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,EAClB,oBAAoB,EACpB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,WAAW,CAAC;AAGnB,4CAA4C;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5C,4FAA4F;AAC5F,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAYxG,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,gGAAgG;AAChG,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAGzG,oCAAoC;AACpC,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE7E,qHAAqH;AACrH,OAAO,EAAE,4BAA4B,EAAE,kBAAkB,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC/G,mFAAmF;AACnF,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAClF,+HAA+H;AAC/H,OAAO,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/M,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGtF,sGAAsG;AACtG,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,4BAA4B,EAC5B,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,6BAA6B,EAC7B,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAG3B,0GAA0G;AAC1G,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE1E,6HAA6H;AAC7H,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,YAAY,EAAE,uBAAuB,EAAE,eAAe,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,eAAe,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,69 @@
1
+ import { type Address, type Hex } from 'viem';
2
+ import { type Delegation } from '@agenticprimitives/delegation';
3
+ /** The JSON-safe form of a delegation as it travels (bigint salt as a string). */
4
+ export interface DelegationWireV1 {
5
+ delegator: Address;
6
+ delegate: Address;
7
+ authority: Hex;
8
+ caveats: Array<{
9
+ enforcer: Address;
10
+ terms: Hex;
11
+ args?: Hex;
12
+ }>;
13
+ salt: string;
14
+ signature: Hex;
15
+ }
16
+ /** Signature type byte for the session-wrapped form. Unknown to AgentAccount `_validateSig` (fails closed
17
+ * on chain) and to every other verifier — only a gate that calls `verifySessionWrappedSignature` accepts
18
+ * it, and only after full verification. */
19
+ export declare const SESSION_WRAPPED_SIG_TYPE = "0x51";
20
+ /** Wrap a raw session-key ECDSA signature with the wire that authorizes it. */
21
+ export declare function wrapSessionSignature(wire: DelegationWireV1, sig: Hex): Hex;
22
+ /** Parse the session-wrapped form; null for any other signature shape (callers then use the standard
23
+ * ERC-1271 path — one detector, no ambiguity). */
24
+ export declare function parseSessionWrappedSignature(signature: string): {
25
+ wire: DelegationWireV1;
26
+ sig: Hex;
27
+ } | null;
28
+ export declare function wireToDelegation(w: DelegationWireV1): Delegation;
29
+ export declare function delegationToWire(d: Delegation): DelegationWireV1;
30
+ /**
31
+ * Shape check for a session wire (at ceremony store time AND at every gate hit): timestamp-bounded, a
32
+ * pinned allowedMethods set that never carries the any-skill sentinel and — when `skill` is given — names
33
+ * that skill's selector.
34
+ *
35
+ * `skill` should be passed wherever the request names one: a wire minted for one rail must not authorize
36
+ * another. It is omitted only on the read/control path (`tasks/get`, `tasks/cancel`,
37
+ * `pushNotificationConfig/set`), whose digest binds a method and a taskId, not a skill. That omission is
38
+ * narrow rather than lax — the wire must still be pinned, live, ERC-1271-valid and unrevoked, and the task
39
+ * runtime independently requires the caller to BE a party to the task.
40
+ */
41
+ export declare function checkSessionWireShape(wire: DelegationWireV1, enforcers: {
42
+ timestamp: string;
43
+ allowedMethods: string;
44
+ }, nowSec: number, opts?: {
45
+ skill?: string;
46
+ }): string | null;
47
+ /**
48
+ * Verify a session-wrapped signature for `signer` over `digest`, fail-closed on every leg. The on-chain
49
+ * checks are the SAME injected ones the standard gate uses (`OnChainChecks`) — revocation is immediate.
50
+ * Pass `skill` whenever the request names one.
51
+ */
52
+ export declare function verifySessionWrappedSignature(args: {
53
+ signer: Address;
54
+ digest: Hex;
55
+ signature: string;
56
+ enforcers: {
57
+ timestamp: string;
58
+ allowedMethods: string;
59
+ };
60
+ verifyDelegationSig: (d: Delegation) => Promise<boolean>;
61
+ isRevoked: (d: Delegation) => Promise<boolean>;
62
+ /** The skill the inbound message requests. Omit ONLY on the read/control path. */
63
+ skill?: string;
64
+ /** Milliseconds (Date.now() shape); injected for determinism. */
65
+ now?: number;
66
+ }): Promise<boolean>;
67
+ /** keccak over stable-JSON — the a2a body-hash convention (equals the task runtime's `hashBody`). */
68
+ export declare const sessionBodyHash: (data: unknown) => Hex;
69
+ //# sourceMappingURL=session-wire.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-wire.d.ts","sourceRoot":"","sources":["../src/session-wire.ts"],"names":[],"mappings":"AA0BA,OAAO,EAAmD,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAC/F,OAAO,EAAmD,KAAK,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAGjH,kFAAkF;AAClF,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,GAAG,CAAC;IACf,OAAO,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,KAAK,EAAE,GAAG,CAAC;QAAC,IAAI,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC,CAAC;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,GAAG,CAAC;CAChB;AAED;;4CAE4C;AAC5C,eAAO,MAAM,wBAAwB,SAAS,CAAC;AAU/C,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,gBAAgB,EAAE,GAAG,EAAE,GAAG,GAAG,GAAG,CAE1E;AAED;mDACmD;AACnD,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,GAAG,EAAE,GAAG,CAAA;CAAE,GAAG,IAAI,CAS3G;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,gBAAgB,GAAG,UAAU,CAShE;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,GAAG,gBAAgB,CAMhE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,gBAAgB,EACtB,SAAS,EAAE;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,EACxD,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GACxB,MAAM,GAAG,IAAI,CA2Bf;AAED;;;;GAIG;AACH,wBAAsB,6BAA6B,CAAC,IAAI,EAAE;IACxD,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,GAAG,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,mBAAmB,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,SAAS,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iEAAiE;IACjE,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,OAAO,CAAC,CAuBnB;AAED,qGAAqG;AACrG,eAAO,MAAM,eAAe,SAAU,OAAO,KAAG,GAAuD,CAAC"}
@@ -0,0 +1,170 @@
1
+ // SESSION WIRES — how an agent signs as an identity whose key it does not hold. Spec 350 §8 / spec 326.
2
+ //
3
+ // THE CALLER-SIGNATURE GAP, RESOLVED (spec 329 §3.1, generalized). A runtime holds no key for the identity
4
+ // it acts as — an org's DO holds no org key, a relying service must never custody the service agent it
5
+ // acts as (ADR-0019: a relying key is always a DELEGATE, never a custodian), a skills worker signs as
6
+ // `skills-agent` without holding it. Yet A2A needs per-message sender signatures and per-poll caller
7
+ // signatures that verify against THAT identity. A ceremony therefore mints a NARROW delegation —
8
+ // delegator = the identity, delegate = a KMS session key, allowedMethods = a pinned set of skill
9
+ // selectors (never the any-skill sentinel), allowedTargets pinned, timestamp-bounded — signed by the
10
+ // identity's own custody credential. The runtime stores the wire; NO raw key ever rests there; the KMS
11
+ // key signs each digest on demand.
12
+ //
13
+ // ON THE WIRE such a signature is the SESSION-WRAPPED form: `0x51` (a type byte no on-chain validator
14
+ // accepts — it fails closed anywhere but a gate that understands it) followed by hex(utf8(JSON({ wire,
15
+ // sig }))). A gate verifies it fail-closed PER MESSAGE: delegator === the claimed signer; timestamp window
16
+ // live; a pinned selector set that names the requested skill and never A2A_ANY_SKILL; the raw ECDSA sig
17
+ // recovers to the wire's delegate; the wire's own signature ERC-1271-verifies against the delegator; AND
18
+ // the wire is unrevoked on chain — so a custodian's revocation kills the authority at every gate, now.
19
+ //
20
+ // WHY THIS IS HERE. Four copies of this file existed across two repos (demo-a2a's session-wire.ts and
21
+ // org-wire.ts, skills-a2a's service-wire.ts, and a sibling worker's). "Copy the wire implementation, do not
22
+ // invent a third" was the instruction, and the count had already reached four. It is an A2A signature
23
+ // format that consumes this package's own `skillSelector`; it belongs here, and the apps now consume it.
24
+ // What STAYS in the apps is policy — which caveat SHAPE counts as stewardship vs member access, which
25
+ // contracts a stewardship wire must pin. `org-wire.ts`'s `hasStewardshipShape` is a positive identity
26
+ // test no generic layer can express, and it does not move.
27
+ import { hashMessage, keccak256, recoverAddress, toBytes } from 'viem';
28
+ import { decodeAllowedMethodsTerms, decodeTimestampTerms } from '@agenticprimitives/delegation';
29
+ import { A2A_ANY_SKILL, skillSelector } from './grant.js';
30
+ /** Signature type byte for the session-wrapped form. Unknown to AgentAccount `_validateSig` (fails closed
31
+ * on chain) and to every other verifier — only a gate that calls `verifySessionWrappedSignature` accepts
32
+ * it, and only after full verification. */
33
+ export const SESSION_WRAPPED_SIG_TYPE = '0x51';
34
+ const utf8ToHex = (s) => `0x${Array.from(new TextEncoder().encode(s), (b) => b.toString(16).padStart(2, '0')).join('')}`;
35
+ const hexToUtf8 = (h) => {
36
+ const clean = h.startsWith('0x') ? h.slice(2) : h;
37
+ const bytes = new Uint8Array(clean.length / 2);
38
+ for (let i = 0; i < bytes.length; i++)
39
+ bytes[i] = parseInt(clean.slice(i * 2, i * 2 + 2), 16);
40
+ return new TextDecoder().decode(bytes);
41
+ };
42
+ /** Wrap a raw session-key ECDSA signature with the wire that authorizes it. */
43
+ export function wrapSessionSignature(wire, sig) {
44
+ return (SESSION_WRAPPED_SIG_TYPE + utf8ToHex(JSON.stringify({ wire, sig })).slice(2));
45
+ }
46
+ /** Parse the session-wrapped form; null for any other signature shape (callers then use the standard
47
+ * ERC-1271 path — one detector, no ambiguity). */
48
+ export function parseSessionWrappedSignature(signature) {
49
+ if (!signature?.startsWith(SESSION_WRAPPED_SIG_TYPE) || signature.length <= SESSION_WRAPPED_SIG_TYPE.length)
50
+ return null;
51
+ try {
52
+ const parsed = JSON.parse(hexToUtf8(`0x${signature.slice(SESSION_WRAPPED_SIG_TYPE.length)}`));
53
+ if (!parsed?.wire?.delegator || !parsed.wire.delegate || !parsed.wire.signature || !parsed.sig)
54
+ return null;
55
+ return { wire: parsed.wire, sig: parsed.sig };
56
+ }
57
+ catch {
58
+ return null;
59
+ }
60
+ }
61
+ export function wireToDelegation(w) {
62
+ return {
63
+ delegator: w.delegator,
64
+ delegate: w.delegate,
65
+ authority: w.authority,
66
+ caveats: w.caveats.map((c) => ({ enforcer: c.enforcer, terms: c.terms, args: (c.args ?? '0x') })),
67
+ salt: BigInt(w.salt),
68
+ signature: w.signature,
69
+ };
70
+ }
71
+ export function delegationToWire(d) {
72
+ return {
73
+ delegator: d.delegator, delegate: d.delegate, authority: d.authority,
74
+ caveats: d.caveats.map((c) => ({ enforcer: c.enforcer, terms: c.terms, ...(c.args && c.args !== '0x' ? { args: c.args } : {}) })),
75
+ salt: d.salt.toString(), signature: d.signature,
76
+ };
77
+ }
78
+ /**
79
+ * Shape check for a session wire (at ceremony store time AND at every gate hit): timestamp-bounded, a
80
+ * pinned allowedMethods set that never carries the any-skill sentinel and — when `skill` is given — names
81
+ * that skill's selector.
82
+ *
83
+ * `skill` should be passed wherever the request names one: a wire minted for one rail must not authorize
84
+ * another. It is omitted only on the read/control path (`tasks/get`, `tasks/cancel`,
85
+ * `pushNotificationConfig/set`), whose digest binds a method and a taskId, not a skill. That omission is
86
+ * narrow rather than lax — the wire must still be pinned, live, ERC-1271-valid and unrevoked, and the task
87
+ * runtime independently requires the caller to BE a party to the task.
88
+ */
89
+ export function checkSessionWireShape(wire, enforcers, nowSec, opts) {
90
+ const byEnforcer = (addr) => (wire.caveats ?? []).find((c) => (c.enforcer ?? '').toLowerCase() === addr.toLowerCase());
91
+ const tsCav = byEnforcer(enforcers.timestamp);
92
+ if (!tsCav?.terms)
93
+ return 'session wire must be timestamp-bounded';
94
+ try {
95
+ const win = decodeTimestampTerms(tsCav.terms);
96
+ const now = BigInt(nowSec);
97
+ if (now < win.validAfter || now >= win.validUntil)
98
+ return 'session wire outside its timestamp window';
99
+ }
100
+ catch {
101
+ return 'session wire timestamp terms undecodable';
102
+ }
103
+ const amCav = byEnforcer(enforcers.allowedMethods);
104
+ if (!amCav?.terms)
105
+ return 'session wire must carry an allowedMethods caveat';
106
+ try {
107
+ const selectors = decodeAllowedMethodsTerms(amCav.terms).map((s) => s.toLowerCase());
108
+ // A PINNED SET, never the any-skill sentinel. A leaked delegate key can send only what the custodian
109
+ // enumerated; `A2A_ANY_SKILL` is the line between "these operations" and "anything this agent can do".
110
+ if (selectors.some((s) => s === A2A_ANY_SKILL.toLowerCase()))
111
+ return 'session wire must never carry the any-skill sentinel';
112
+ if (selectors.length === 0)
113
+ return 'session wire allowedMethods must name at least one selector';
114
+ if (opts?.skill) {
115
+ const want = skillSelector(opts.skill).toLowerCase();
116
+ if (!selectors.includes(want))
117
+ return `session wire allowedMethods does not name the ${opts.skill} selector`;
118
+ }
119
+ }
120
+ catch {
121
+ return 'session wire allowedMethods terms undecodable';
122
+ }
123
+ return null;
124
+ }
125
+ /**
126
+ * Verify a session-wrapped signature for `signer` over `digest`, fail-closed on every leg. The on-chain
127
+ * checks are the SAME injected ones the standard gate uses (`OnChainChecks`) — revocation is immediate.
128
+ * Pass `skill` whenever the request names one.
129
+ */
130
+ export async function verifySessionWrappedSignature(args) {
131
+ const parsed = parseSessionWrappedSignature(args.signature);
132
+ if (!parsed)
133
+ return false;
134
+ const { wire, sig } = parsed;
135
+ if (wire.delegator.toLowerCase() !== args.signer.toLowerCase())
136
+ return false;
137
+ const shapeOpts = args.skill ? { skill: args.skill } : undefined;
138
+ if (checkSessionWireShape(wire, args.enforcers, Math.floor((args.now ?? Date.now()) / 1000), shapeOpts) !== null)
139
+ return false;
140
+ // The raw sig must recover to the wire's delegate (the KMS session key). Accept both raw-digest and
141
+ // eth-signed-message recovery, mirroring AgentAccount._verifyEcdsa.
142
+ const delegate = wire.delegate.toLowerCase();
143
+ let recovered = false;
144
+ try {
145
+ recovered = (await recoverAddress({ hash: args.digest, signature: sig })).toLowerCase() === delegate;
146
+ }
147
+ catch { /* try wrapped */ }
148
+ if (!recovered) {
149
+ try {
150
+ recovered = (await recoverAddress({ hash: hashMessage({ raw: toBytes(args.digest) }), signature: sig })).toLowerCase() === delegate;
151
+ }
152
+ catch {
153
+ return false;
154
+ }
155
+ }
156
+ if (!recovered)
157
+ return false;
158
+ const d = wireToDelegation(wire);
159
+ try {
160
+ if (await args.isRevoked(d))
161
+ return false; // custodian revoke ⇒ immediate kill at every gate
162
+ return await args.verifyDelegationSig(d);
163
+ }
164
+ catch {
165
+ return false; // fail-closed on chain-read failure (ADR-0013)
166
+ }
167
+ }
168
+ /** keccak over stable-JSON — the a2a body-hash convention (equals the task runtime's `hashBody`). */
169
+ export const sessionBodyHash = (data) => keccak256(toBytes(JSON.stringify(data ?? null)));
170
+ //# sourceMappingURL=session-wire.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-wire.js","sourceRoot":"","sources":["../src/session-wire.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import { type Address, type Hex } from 'viem';
2
+ import type { Delegation } from '@agenticprimitives/delegation';
3
+ import { type DelegationWireV1 } from '../session-wire.js';
4
+ import type { Principal } from './server.js';
5
+ /** The Authorization scheme an agent presents its session wire under. */
6
+ export declare const SESSION_AUTH_SCHEME = "A2A-Session";
7
+ /** The skill a session wire must pin to reach the standard surface: asking this agent, and nothing else.
8
+ * A wire that names other selectors and not this one is refused — pinning is the point. */
9
+ export declare const STANDARD_SURFACE_SKILL = "harness.ask";
10
+ /** What a caller signs. Every field is bound: a captured assertion cannot be replayed onto another method,
11
+ * another body, another host, or a later moment. `issuedAt` is IN the digest and checked (stale / ahead refused,
12
+ * the digest claimed once) — the wire path's freshness field that the deleted JSON-RPC dispatcher once dropped
13
+ * (audit a2a-issuedat-dropped-in-dispatch; the folded wire of spec 372 S4 is where the check lives now). */
14
+ export interface CallerAssertionV1 {
15
+ /** The Smart Agent the caller acts AS — must equal the wire's delegator. */
16
+ agent: string;
17
+ /** The A2A method this assertion is for. */
18
+ method: string;
19
+ /** keccak256 over the raw JSON-RPC request body. */
20
+ bodyHash: Hex;
21
+ /** Seconds since the epoch. */
22
+ issuedAt: number;
23
+ /** The origin the request is addressed to (`https://host`), so an assertion for one agent's host is not
24
+ * usable at another's. */
25
+ audience: string;
26
+ /** The `0x51`-wrapped session signature over `callerAssertionDigest(...)`. */
27
+ signature: string;
28
+ }
29
+ /** The digest a caller signs — keccak over stable JSON, the a2a body-hash convention. */
30
+ export declare function callerAssertionDigest(a: Omit<CallerAssertionV1, 'signature'>): Hex;
31
+ /** keccak over the raw request body, exactly as it arrived — never over a re-serialized parse. */
32
+ export declare const requestBodyHash: (raw: string) => Hex;
33
+ /** Build the `Authorization` header value a runtime sends. */
34
+ export declare function sessionAuthorizationHeader(a: CallerAssertionV1): string;
35
+ /** Read an `A2A-Session` header. Returns null for any other scheme (a `Bearer` is a person's, not ours) and
36
+ * for anything malformed — never a partial assertion. */
37
+ export declare function parseSessionAuthorization(header: string | null | undefined): CallerAssertionV1 | null;
38
+ export interface SessionWirePrincipalDeps {
39
+ /** The enforcer addresses the wire's caveats must carry (this deployment's). */
40
+ enforcers: {
41
+ timestamp: string;
42
+ allowedMethods: string;
43
+ };
44
+ /** ERC-1271 / ECDSA verification of the wire against its delegator. */
45
+ verifyDelegationSig: (d: Delegation) => Promise<boolean>;
46
+ /** On-chain revocation — a custodian's revoke kills the caller at the next request. */
47
+ isRevoked: (d: Delegation) => Promise<boolean>;
48
+ /**
49
+ * Verify an assertion the agent signed DIRECTLY — ERC-1271 against its own account, no session key in
50
+ * between. Some agents can do that (a relayer holding the SA's credential, a persona in this estate) and
51
+ * before the fold they proved themselves exactly this way, with `caller` + `signature` on the wire.
52
+ *
53
+ * NOT A FALLBACK (ADR-0013). The signature's own type byte chooses: `0x51` is session-wrapped and takes
54
+ * the wire path; anything else takes this one. Neither runs because the other failed, and omitting this
55
+ * means a direct signature is simply not admitted.
56
+ */
57
+ verifyAgentSignature?: (agent: Address, digest: Hex, signature: Hex) => Promise<boolean>;
58
+ /** How old an assertion may be (default 120 s). */
59
+ maxAgeSec?: number;
60
+ /** Tolerated clock skew for an assertion dated ahead (default 30 s). */
61
+ skewSec?: number;
62
+ now?: () => number;
63
+ /**
64
+ * Spend an assertion, once. Returns true when THIS call claimed it and false when it was already spent.
65
+ * The default is an in-isolate map, which is not replay protection where requests fan out across
66
+ * isolates — bind the estate's single writer (the agent's own object) in production.
67
+ */
68
+ claim?: (digest: Hex, expiresAtMs: number) => Promise<boolean>;
69
+ /** Told why a caller was refused — for the operator's log, never for the caller (a refusal says only
70
+ * that it was refused; which leg failed is not a fact an unauthenticated caller is owed). */
71
+ onRefused?: (reason: string, agent?: string) => void;
72
+ }
73
+ /**
74
+ * The `principal` implementation for agents. Returns `{ agent, kind: 'agent' }` on every leg passing, and
75
+ * `null` otherwise — the server answers 401 and no method runs.
76
+ *
77
+ * SINGLE-USE. An accepted assertion's digest is SPENT: a captured request cannot be replayed while it is
78
+ * still fresh. With `claim` bound to the estate's single writer this holds everywhere; without it, only
79
+ * within this isolate — which on a fanned-out edge is no protection at all, and was observed live before
80
+ * the ledger existed. The claim happens AFTER the signature verifies, so an unauthenticated caller can
81
+ * spend nothing and write nothing.
82
+ */
83
+ export declare function sessionWirePrincipal(deps: SessionWirePrincipalDeps): (request: Request) => Promise<Principal | null>;
84
+ /** Re-export so a client can build a wire-signed call without reaching past the standard surface. */
85
+ export type { DelegationWireV1 };
86
+ //# sourceMappingURL=caller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caller.d.ts","sourceRoot":"","sources":["../../src/standard/caller.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAsB,KAAK,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,MAAM,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAChE,OAAO,EAA+D,KAAK,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACxH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,gBAAgB,CAAC;AAEjD;4FAC4F;AAC5F,eAAO,MAAM,sBAAsB,gBAAgB,CAAC;AAEpD;;;6GAG6G;AAC7G,MAAM,WAAW,iBAAiB;IAChC,4EAA4E;IAC5E,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,QAAQ,EAAE,GAAG,CAAC;IACd,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB;+BAC2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,yFAAyF;AACzF,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,IAAI,CAAC,iBAAiB,EAAE,WAAW,CAAC,GAAG,GAAG,CASlF;AAED,kGAAkG;AAClG,eAAO,MAAM,eAAe,QAAS,MAAM,KAAG,GAA8B,CAAC;AAQ7E,8DAA8D;AAC9D,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAEvE;AAED;0DAC0D;AAC1D,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,iBAAiB,GAAG,IAAI,CAerG;AAED,MAAM,WAAW,wBAAwB;IACvC,gFAAgF;IAChF,SAAS,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,cAAc,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,uEAAuE;IACvE,mBAAmB,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzD,uFAAuF;IACvF,SAAS,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/C;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,GAAG,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzF,mDAAmD;IACnD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC/D;kGAC8F;IAC9F,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CACtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,wBAAwB,GAAG,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA4DpH;AAED,qGAAqG;AACrG,YAAY,EAAE,gBAAgB,EAAE,CAAC"}
@@ -0,0 +1,159 @@
1
+ // THE RUNTIME AS ITS OWN CALLER — spec 372 S3c.
2
+ //
3
+ // A person reaches the standard surface with a Home session bearer. An outside runtime — Claude Code, Goose,
4
+ // a deploy bot — has no Home session and must never be given one: it is not a person, and a bearer minted for
5
+ // a person is exactly the credential-sharing this estate exists to avoid. What it holds instead is what every
6
+ // agent here holds: a SESSION WIRE (spec 350 §8) — a narrow delegation from its own Smart Agent to a key it
7
+ // controls, timestamp-bounded, pinning the one skill it may exercise, signed by the agent's custody credential
8
+ // and revocable on chain by that custodian at any moment.
9
+ //
10
+ // So the runtime signs each request with that key and presents the wire beside it. The server verifies, per
11
+ // request and fail-closed: the wire's delegator IS the agent claimed; the wire's shape is sound (bounded,
12
+ // pinned, never the any-skill sentinel); the raw signature recovers to the wire's delegate; the wire itself
13
+ // verifies against the delegator on chain (ERC-1271) and is NOT revoked. Revoking the wire kills the caller
14
+ // at the next request, everywhere, with no list to update.
15
+ //
16
+ // TWO SCHEMES, NOT A FALLBACK (ADR-0013). `Bearer` is a person's Home session; `A2A-Session` is an agent's
17
+ // wire. The scheme token in the header selects ONE mechanism, and it fails closed on its own terms — neither
18
+ // is ever tried after the other fails. Which one arrived says WHO is asking. Neither says what they may do.
19
+ import { keccak256, toBytes } from 'viem';
20
+ import { parseSessionWrappedSignature, verifySessionWrappedSignature } from '../session-wire.js';
21
+ /** The Authorization scheme an agent presents its session wire under. */
22
+ export const SESSION_AUTH_SCHEME = 'A2A-Session';
23
+ /** The skill a session wire must pin to reach the standard surface: asking this agent, and nothing else.
24
+ * A wire that names other selectors and not this one is refused — pinning is the point. */
25
+ export const STANDARD_SURFACE_SKILL = 'harness.ask';
26
+ /** The digest a caller signs — keccak over stable JSON, the a2a body-hash convention. */
27
+ export function callerAssertionDigest(a) {
28
+ return keccak256(toBytes(JSON.stringify({
29
+ v: 'ap.a2a.caller-assertion.v1',
30
+ agent: a.agent.toLowerCase(),
31
+ method: a.method,
32
+ bodyHash: a.bodyHash.toLowerCase(),
33
+ issuedAt: a.issuedAt,
34
+ audience: a.audience.replace(/\/$/, '').toLowerCase(),
35
+ })));
36
+ }
37
+ /** keccak over the raw request body, exactly as it arrived — never over a re-serialized parse. */
38
+ export const requestBodyHash = (raw) => keccak256(toBytes(raw));
39
+ const b64urlDecode = (s) => {
40
+ const padded = s.replace(/-/g, '+').replace(/_/g, '/') + '='.repeat((4 - (s.length % 4)) % 4);
41
+ return atob(padded);
42
+ };
43
+ const b64urlEncode = (s) => btoa(s).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
44
+ /** Build the `Authorization` header value a runtime sends. */
45
+ export function sessionAuthorizationHeader(a) {
46
+ return `${SESSION_AUTH_SCHEME} ${b64urlEncode(JSON.stringify(a))}`;
47
+ }
48
+ /** Read an `A2A-Session` header. Returns null for any other scheme (a `Bearer` is a person's, not ours) and
49
+ * for anything malformed — never a partial assertion. */
50
+ export function parseSessionAuthorization(header) {
51
+ const m = new RegExp(`^${SESSION_AUTH_SCHEME}\\s+(.+)$`, 'i').exec((header ?? '').trim());
52
+ if (!m)
53
+ return null;
54
+ try {
55
+ const a = JSON.parse(b64urlDecode(m[1].trim()));
56
+ if (typeof a.agent !== 'string' || !/^0x[0-9a-fA-F]{40}$/.test(a.agent))
57
+ return null;
58
+ if (typeof a.method !== 'string' || !a.method)
59
+ return null;
60
+ if (typeof a.bodyHash !== 'string' || !/^0x[0-9a-fA-F]{64}$/.test(a.bodyHash))
61
+ return null;
62
+ if (typeof a.issuedAt !== 'number' || !Number.isFinite(a.issuedAt))
63
+ return null;
64
+ if (typeof a.audience !== 'string' || !a.audience)
65
+ return null;
66
+ if (typeof a.signature !== 'string' || !a.signature.startsWith('0x'))
67
+ return null;
68
+ return a;
69
+ }
70
+ catch {
71
+ return null;
72
+ }
73
+ }
74
+ /**
75
+ * The `principal` implementation for agents. Returns `{ agent, kind: 'agent' }` on every leg passing, and
76
+ * `null` otherwise — the server answers 401 and no method runs.
77
+ *
78
+ * SINGLE-USE. An accepted assertion's digest is SPENT: a captured request cannot be replayed while it is
79
+ * still fresh. With `claim` bound to the estate's single writer this holds everywhere; without it, only
80
+ * within this isolate — which on a fanned-out edge is no protection at all, and was observed live before
81
+ * the ledger existed. The claim happens AFTER the signature verifies, so an unauthenticated caller can
82
+ * spend nothing and write nothing.
83
+ */
84
+ export function sessionWirePrincipal(deps) {
85
+ const maxAgeSec = deps.maxAgeSec ?? 120;
86
+ const skewSec = deps.skewSec ?? 30;
87
+ const now = deps.now ?? (() => Date.now());
88
+ const seen = new Map();
89
+ const refuse = (reason, agent) => { deps.onRefused?.(reason, agent); return null; };
90
+ return async (request) => {
91
+ const a = parseSessionAuthorization(request.headers.get('authorization'));
92
+ if (!a)
93
+ return null; // not our scheme — say nothing; another principal may own it
94
+ const nowSec = Math.floor(now() / 1000);
95
+ if (a.issuedAt > nowSec + skewSec)
96
+ return refuse('assertion is dated ahead', a.agent);
97
+ if (a.issuedAt < nowSec - maxAgeSec)
98
+ return refuse('assertion is stale', a.agent);
99
+ const audience = new URL(request.url).origin;
100
+ if (a.audience.replace(/\/$/, '').toLowerCase() !== audience.toLowerCase())
101
+ return refuse(`assertion is for ${a.audience}, not ${audience}`, a.agent);
102
+ let raw;
103
+ try {
104
+ raw = await request.clone().text();
105
+ }
106
+ catch {
107
+ return refuse('request body unreadable', a.agent);
108
+ }
109
+ if (requestBodyHash(raw).toLowerCase() !== a.bodyHash.toLowerCase())
110
+ return refuse('assertion does not bind this body', a.agent);
111
+ let method;
112
+ try {
113
+ method = JSON.parse(raw).method;
114
+ }
115
+ catch {
116
+ return refuse('body is not JSON', a.agent);
117
+ }
118
+ if (method !== a.method)
119
+ return refuse(`assertion is for ${a.method}, body calls ${String(method)}`, a.agent);
120
+ const digest = callerAssertionDigest(a);
121
+ // A cheap local reject first, so a replay landing on the isolate that served the original costs no
122
+ // chain read; the authoritative claim is below, after the signature verifies.
123
+ for (const [k, at] of seen)
124
+ if (at < nowSec - maxAgeSec - skewSec)
125
+ seen.delete(k);
126
+ if (seen.has(digest))
127
+ return refuse('assertion already used', a.agent);
128
+ const wrapped = parseSessionWrappedSignature(a.signature) !== null;
129
+ const ok = wrapped
130
+ ? await verifySessionWrappedSignature({
131
+ signer: a.agent.toLowerCase(),
132
+ digest,
133
+ signature: a.signature,
134
+ enforcers: deps.enforcers,
135
+ verifyDelegationSig: deps.verifyDelegationSig,
136
+ isRevoked: deps.isRevoked,
137
+ skill: STANDARD_SURFACE_SKILL,
138
+ now: now(),
139
+ }).catch(() => false)
140
+ : deps.verifyAgentSignature
141
+ ? await deps.verifyAgentSignature(a.agent.toLowerCase(), digest, a.signature).catch(() => false)
142
+ : false;
143
+ if (!ok) {
144
+ return refuse(wrapped
145
+ ? 'session wire did not verify (shape, signature, delegator or revocation)'
146
+ : deps.verifyAgentSignature ? 'the agent\'s own signature did not verify' : 'a direct agent signature is not admitted here', a.agent);
147
+ }
148
+ // SPENT, now that it is known to be genuine: the single writer decides who was first. A ledger that
149
+ // cannot be reached refuses the call — a replay window is not something to fail open into (ADR-0013).
150
+ if (deps.claim) {
151
+ const claimed = await deps.claim(digest, (a.issuedAt + maxAgeSec + skewSec) * 1000).catch(() => false);
152
+ if (!claimed)
153
+ return refuse('assertion already used', a.agent);
154
+ }
155
+ seen.set(digest, nowSec);
156
+ return { agent: a.agent.toLowerCase(), kind: 'agent' };
157
+ };
158
+ }
159
+ //# sourceMappingURL=caller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caller.js","sourceRoot":"","sources":["../../src/standard/caller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ import type { AgentCardV1, MessageV1, PartV1, TaskV1 } from './types.js';
2
+ export interface ResolvedAgentCard {
3
+ card: AgentCardV1;
4
+ /** SHA-256 over the card's bytes as served, hex — what a record pins and a later fetch is compared to. */
5
+ cardDigest: string;
6
+ /** The JSON-RPC 1.x interface the card publishes. */
7
+ endpoint: string;
8
+ cardUrl: string;
9
+ }
10
+ /** The A2A 1.0 JSON-RPC endpoint a card publishes (top-level `protocolVersion` covers a released card's interfaces). */
11
+ export declare function jsonRpcEndpointOf(card: AgentCardV1 & {
12
+ protocolVersion?: string;
13
+ }): string | null;
14
+ /** Fetch a card, digest its bytes, read its endpoint. A card without a 1.x JSON-RPC interface is refused. */
15
+ export declare function resolveAgentCard(cardUrl: string, fetchImpl?: typeof fetch, expectDigest?: string): Promise<ResolvedAgentCard>;
16
+ export interface StandardA2aClientOptions {
17
+ endpoint: string;
18
+ fetch?: typeof fetch;
19
+ /** Extra headers on every call — a bearer, a session wire. Never a mandate. */
20
+ headers?: Record<string, string>;
21
+ }
22
+ export interface SendResult {
23
+ task?: TaskV1;
24
+ message?: MessageV1;
25
+ }
26
+ export interface StandardA2aClient {
27
+ sendMessage(parts: PartV1[], opts?: {
28
+ metadata?: Record<string, unknown>;
29
+ extensions?: string[];
30
+ contextId?: string;
31
+ taskId?: string;
32
+ }): Promise<SendResult>;
33
+ getTask(id: string): Promise<TaskV1>;
34
+ /** Poll until the task is terminal or the deadline passes; the last task seen is returned either way. */
35
+ awaitTask(id: string, opts?: {
36
+ timeoutMs?: number;
37
+ everyMs?: number;
38
+ }): Promise<TaskV1>;
39
+ /** Send one text message and wait: the reply's text (status message + text artifacts) and the task. */
40
+ ask(text: string, opts?: {
41
+ metadata?: Record<string, unknown>;
42
+ timeoutMs?: number;
43
+ }): Promise<{
44
+ text: string;
45
+ task?: TaskV1;
46
+ message?: MessageV1;
47
+ }>;
48
+ }
49
+ export declare function createStandardA2aClient(o: StandardA2aClientOptions): StandardA2aClient;
50
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/standard/client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAmB,MAAM,YAAY,CAAC;AAG1F,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,WAAW,CAAC;IAClB,0GAA0G;IAC1G,UAAU,EAAE,MAAM,CAAC;IACnB,qDAAqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAOD,wHAAwH;AACxH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,GAAG,IAAI,CAIjG;AAED,6GAA6G;AAC7G,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,OAAO,KAAa,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAY1I;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IAAG,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE;AAIlE,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAC7J,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,yGAAyG;IACzG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxF,uGAAuG;IACvG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,SAAS,CAAA;KAAE,CAAC,CAAC;CACrJ;AAED,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,wBAAwB,GAAG,iBAAiB,CA0CtF"}