@peac/mappings-a2a 0.12.4 → 0.12.6

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.
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # @peac/mappings-a2a
2
2
 
3
- Agent-to-Agent Protocol (A2A) integration for PEAC.
4
-
5
- Maps PEAC evidence carriers to A2A metadata (TaskStatus, Message, Artifact) per A2A spec v0.3.0.
3
+ Agent-to-Agent Protocol (A2A) integration for PEAC: maps A2A agent cards, task states, and metadata to PEAC evidence carriers.
6
4
 
7
5
  ## Installation
8
6
 
@@ -10,9 +8,117 @@ Maps PEAC evidence carriers to A2A metadata (TaskStatus, Message, Artifact) per
10
8
  pnpm add @peac/mappings-a2a
11
9
  ```
12
10
 
13
- ## Documentation
11
+ ## What It Does
12
+
13
+ `@peac/mappings-a2a` bridges PEAC signed interaction receipts and the Agent-to-Agent Protocol (A2A). It normalizes A2A v0.3.0 and v1.0.0 structures into a consistent shape, attaches and extracts PEAC evidence carriers from A2A metadata, and discovers PEAC capabilities advertised by remote agents. All carrier operations enforce transport constraints (64 KB embed limit for A2A).
14
+
15
+ ## How Do I Use It?
16
+
17
+ ### Normalize an A2A Agent Card
18
+
19
+ Accept either v0.3.0 or v1.0.0 Agent Cards and get a consistent interface:
20
+
21
+ ```typescript
22
+ import { normalizeAgentCard } from '@peac/mappings-a2a';
23
+
24
+ const card = {
25
+ name: 'billing-agent',
26
+ supportedInterfaces: [
27
+ { url: 'https://billing.example.com', protocolBinding: 'http+json', protocolVersion: '1.0.0' },
28
+ ],
29
+ };
30
+ const normalized = normalizeAgentCard(card);
31
+
32
+ if (normalized) {
33
+ console.log(normalized.version); // '1.0.0'
34
+ console.log(normalized.url); // 'https://billing.example.com'
35
+ }
36
+ ```
37
+
38
+ ### Normalize a task state across versions
39
+
40
+ ```typescript
41
+ import { normalizeTaskState } from '@peac/mappings-a2a';
42
+
43
+ // v0.3.0 value normalized to v1.0.0 canonical form
44
+ console.log(normalizeTaskState('working')); // 'TASK_STATE_WORKING'
45
+
46
+ // v1.0.0 values pass through unchanged
47
+ console.log(normalizeTaskState('TASK_STATE_COMPLETED')); // 'TASK_STATE_COMPLETED'
48
+ ```
49
+
50
+ ### Attach a receipt to A2A TaskStatus metadata
51
+
52
+ ```typescript
53
+ import { attachReceiptToTaskStatus } from '@peac/mappings-a2a';
54
+ import type { PeacEvidenceCarrier } from '@peac/kernel';
55
+
56
+ const carrier: PeacEvidenceCarrier = {
57
+ receipt_ref: 'sha256-abc123...',
58
+ receipt_jws: 'eyJ...',
59
+ };
60
+
61
+ const status = { state: 'TASK_STATE_COMPLETED', metadata: {} };
62
+ attachReceiptToTaskStatus(status, [carrier]);
63
+ // status.metadata now contains the PEAC extension payload
64
+ ```
65
+
66
+ ### Extract receipts from A2A metadata
67
+
68
+ ```typescript
69
+ import { extractReceiptFromMetadata } from '@peac/mappings-a2a';
70
+
71
+ const result = extractReceiptFromMetadata(taskStatus.metadata);
72
+ if (result) {
73
+ console.log(result.receipts.length); // number of valid carriers
74
+ console.log(result.meta.transport); // 'a2a'
75
+ }
76
+ ```
77
+
78
+ ### Use the carrier adapter
79
+
80
+ ```typescript
81
+ import { A2ACarrierAdapter, createA2ACarrierMeta } from '@peac/mappings-a2a';
82
+
83
+ const adapter = new A2ACarrierAdapter();
84
+ const meta = createA2ACarrierMeta();
85
+
86
+ // Extract from incoming TaskStatus
87
+ const extracted = adapter.extract(incomingStatus);
88
+
89
+ // Attach to outgoing TaskStatus
90
+ const outgoing = adapter.attach(responseStatus, carriers, meta);
91
+ ```
92
+
93
+ ### Discover PEAC capabilities from a remote agent
94
+
95
+ ```typescript
96
+ import { discoverPeacCapabilities } from '@peac/mappings-a2a';
97
+
98
+ const result = await discoverPeacCapabilities('https://agent.example.com');
99
+ if (result) {
100
+ console.log(result.source); // 'agent_card' | 'well_known' | 'header_probe'
101
+ console.log(result.kinds); // supported receipt kinds
102
+ console.log(result.carrier_formats); // supported carrier formats
103
+ }
104
+ ```
105
+
106
+ ## Integrates With
107
+
108
+ - `@peac/kernel` (Layer 0): Evidence carrier types and constants
109
+ - `@peac/schema` (Layer 1): Carrier schema validation and receipt ref consistency
110
+ - `@peac/protocol` (Layer 3): Receipt issuance and verification
111
+ - `@peac/mcp-server` (Layer 5): MCP tool server with A2A interoperability
112
+
113
+ ## For Agent Developers
114
+
115
+ If you are building an AI agent that communicates via A2A and needs signed interaction receipts:
14
116
 
15
- See [peacprotocol.org](https://www.peacprotocol.org) for full documentation.
117
+ - Use `normalizeAgentCard()` and `normalizeTaskState()` to handle both A2A v0.3.0 and v1.0.0 inputs
118
+ - Use `attachReceiptToTaskStatus()` to embed evidence in outgoing A2A messages
119
+ - Use `extractReceiptFromMetadata()` to retrieve evidence from incoming A2A messages
120
+ - Use `A2ACarrierAdapter` for a transport-agnostic carrier interface
121
+ - Use `discoverPeacCapabilities()` to check whether a remote agent supports PEAC before sending receipts
16
122
 
17
123
  ## License
18
124
 
@@ -0,0 +1,86 @@
1
+ /**
2
+ * OAuth 2.0 Device Authorization Grant types for A2A.
3
+ *
4
+ * Types only: no implementation in this release. Device Code flow
5
+ * (RFC 8628) is an alternative auth model for headless A2A agents
6
+ * that cannot handle browser redirects.
7
+ *
8
+ * All type names and field names mirror RFC 8628 wire format exactly.
9
+ * Normalization (if needed) belongs in a separate layer.
10
+ */
11
+ /**
12
+ * A2A Device Code flow configuration.
13
+ *
14
+ * Field names mirror the A2A spec OAuth flow object for Device Code.
15
+ */
16
+ export interface A2ADeviceCodeFlowConfig {
17
+ /** Device authorization endpoint URL (HTTPS required) */
18
+ readonly deviceAuthorizationUrl: string;
19
+ /** Token endpoint URL (HTTPS required) */
20
+ readonly tokenUrl: string;
21
+ /** Refresh token endpoint URL (optional, HTTPS required) */
22
+ readonly refreshUrl?: string;
23
+ /** Requested scopes */
24
+ readonly scopes?: readonly string[];
25
+ }
26
+ /**
27
+ * Device authorization request parameters (RFC 8628 Section 3.1).
28
+ *
29
+ * Wire field names per the RFC.
30
+ */
31
+ export interface DeviceCodeRequest {
32
+ /** Client identifier */
33
+ readonly client_id: string;
34
+ /** Space-delimited scopes (wire format) */
35
+ readonly scope?: string;
36
+ }
37
+ /**
38
+ * Device authorization response from the authorization server (RFC 8628 Section 3.2).
39
+ *
40
+ * All field names match the RFC 8628 JSON wire format.
41
+ */
42
+ export interface DeviceCodeResponse {
43
+ /** Device verification code */
44
+ readonly device_code: string;
45
+ /** End-user verification code (short, displayed to user) */
46
+ readonly user_code: string;
47
+ /** End-user verification URI */
48
+ readonly verification_uri: string;
49
+ /** Optional complete verification URI with user_code pre-filled */
50
+ readonly verification_uri_complete?: string;
51
+ /** Lifetime of device_code and user_code in seconds */
52
+ readonly expires_in: number;
53
+ /** Minimum polling interval in seconds (default 5 per RFC 8628 Section 3.2) */
54
+ readonly interval?: number;
55
+ }
56
+ /**
57
+ * Token endpoint error codes during Device Code polling (RFC 8628 Section 3.5).
58
+ *
59
+ * These are the raw wire values returned in the `error` field of the
60
+ * token endpoint error response during device authorization polling.
61
+ */
62
+ export type DeviceCodePollingError = 'authorization_pending' | 'slow_down' | 'access_denied' | 'expired_token';
63
+ /**
64
+ * Token endpoint error response during Device Code polling.
65
+ *
66
+ * Wire shape per RFC 8628 Section 3.5 + OAuth 2.0 error response format.
67
+ */
68
+ export interface DeviceCodeErrorResponse {
69
+ /** RFC 8628 polling error code */
70
+ readonly error: DeviceCodePollingError;
71
+ /** Human-readable error description */
72
+ readonly error_description?: string;
73
+ }
74
+ /**
75
+ * Successful token response from Device Code flow completion.
76
+ *
77
+ * Same shape as standard OAuth 2.0 token response (RFC 6749 Section 5.1).
78
+ */
79
+ export interface DeviceCodeTokenResponse {
80
+ readonly access_token: string;
81
+ readonly token_type: string;
82
+ readonly expires_in?: number;
83
+ readonly refresh_token?: string;
84
+ readonly scope?: string;
85
+ }
86
+ //# sourceMappingURL=device-code.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-code.d.ts","sourceRoot":"","sources":["../../src/auth/device-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAMH;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,yDAAyD;IACzD,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;IACxC,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,uBAAuB;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAMD;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,wBAAwB;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,+BAA+B;IAC/B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,gCAAgC;IAChC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,mEAAmE;IACnE,QAAQ,CAAC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IAC5C,uDAAuD;IACvD,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAC9B,uBAAuB,GACvB,WAAW,GACX,eAAe,GACf,eAAe,CAAC;AAEpB;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,QAAQ,CAAC,KAAK,EAAE,sBAAsB,CAAC;IACvC,uCAAuC;IACvC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;CACrC;AAED;;;;GAIG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * A2A auth error mapping to google.rpc.Status with ErrorInfo.
3
+ *
4
+ * A2A v1.0 uses gRPC-style status codes for transport errors. For
5
+ * A2A-specific errors, implementations include `google.rpc.ErrorInfo`
6
+ * in `status.details[]`. This module produces the full Status + ErrorInfo
7
+ * shape for auth-related A2A errors.
8
+ */
9
+ /**
10
+ * gRPC canonical status codes used in A2A auth error responses.
11
+ * Values match google.rpc.Code numeric assignments.
12
+ */
13
+ export declare const GrpcStatusCode: {
14
+ readonly OK: 0;
15
+ readonly INVALID_ARGUMENT: 3;
16
+ readonly NOT_FOUND: 5;
17
+ readonly PERMISSION_DENIED: 7;
18
+ readonly INTERNAL: 13;
19
+ readonly UNAVAILABLE: 14;
20
+ readonly UNAUTHENTICATED: 16;
21
+ };
22
+ export type GrpcStatusCodeValue = (typeof GrpcStatusCode)[keyof typeof GrpcStatusCode];
23
+ /**
24
+ * google.rpc.ErrorInfo per https://cloud.google.com/apis/design/errors.
25
+ *
26
+ * Included in `status.details[]` for A2A-specific auth errors.
27
+ */
28
+ export interface GrpcErrorInfo {
29
+ /** Fully-qualified type URL for ErrorInfo */
30
+ readonly '@type': 'type.googleapis.com/google.rpc.ErrorInfo';
31
+ /** Machine-readable error reason (SCREAMING_SNAKE_CASE) */
32
+ readonly reason: string;
33
+ /** Domain for the error (always 'a2a-protocol.org' per A2A spec) */
34
+ readonly domain: string;
35
+ /** Key-value metadata providing additional error context */
36
+ readonly metadata: Readonly<Record<string, string>>;
37
+ }
38
+ /**
39
+ * google.rpc.Status with typed ErrorInfo detail.
40
+ *
41
+ * This is the wire shape returned in A2A gRPC error responses and
42
+ * JSON-RPC error data objects.
43
+ */
44
+ export interface GrpcStatus {
45
+ /** gRPC canonical status code */
46
+ readonly code: GrpcStatusCodeValue;
47
+ /** Human-readable error message */
48
+ readonly message: string;
49
+ /** Structured error details (contains ErrorInfo for A2A-specific errors) */
50
+ readonly details: readonly GrpcErrorInfo[];
51
+ }
52
+ declare const AUTH_ERROR_DEFS: {
53
+ readonly PKCE_MISMATCH: {
54
+ readonly grpcCode: 16;
55
+ readonly message: "PKCE code challenge verification failed";
56
+ readonly reason: "PKCE_CHALLENGE_MISMATCH";
57
+ };
58
+ readonly PKCE_INVALID_VERIFIER: {
59
+ readonly grpcCode: 3;
60
+ readonly message: "PKCE code verifier does not meet RFC 7636 requirements";
61
+ readonly reason: "PKCE_INVALID_VERIFIER";
62
+ };
63
+ readonly TOKEN_EXCHANGE_FAILED: {
64
+ readonly grpcCode: 16;
65
+ readonly message: "OAuth token exchange failed";
66
+ readonly reason: "TOKEN_EXCHANGE_FAILED";
67
+ };
68
+ readonly AUTH_SERVER_UNAVAILABLE: {
69
+ readonly grpcCode: 14;
70
+ readonly message: "Authorization server is unavailable";
71
+ readonly reason: "AUTH_SERVER_UNAVAILABLE";
72
+ };
73
+ readonly INVALID_AUTH_CODE: {
74
+ readonly grpcCode: 16;
75
+ readonly message: "Authorization code is invalid or expired";
76
+ readonly reason: "INVALID_AUTH_CODE";
77
+ };
78
+ readonly INVALID_CLIENT: {
79
+ readonly grpcCode: 7;
80
+ readonly message: "Client authentication failed";
81
+ readonly reason: "INVALID_CLIENT";
82
+ };
83
+ readonly SCOPE_DENIED: {
84
+ readonly grpcCode: 7;
85
+ readonly message: "Requested scope was denied by the authorization server";
86
+ readonly reason: "SCOPE_DENIED";
87
+ };
88
+ readonly DEVICE_CODE_EXPIRED: {
89
+ readonly grpcCode: 16;
90
+ readonly message: "Device authorization code has expired";
91
+ readonly reason: "DEVICE_CODE_EXPIRED";
92
+ };
93
+ };
94
+ export type A2AAuthErrorCode = keyof typeof AUTH_ERROR_DEFS;
95
+ /**
96
+ * Create a google.rpc.Status with ErrorInfo for an A2A auth error.
97
+ *
98
+ * Returns the full Status shape with `details[]` containing a single
99
+ * `google.rpc.ErrorInfo` entry, as required by the A2A spec for
100
+ * implementation-specific errors.
101
+ *
102
+ * @param errorCode - A2A auth error code
103
+ * @param metadata - Additional key-value context for ErrorInfo.metadata
104
+ * @returns google.rpc.Status with embedded ErrorInfo
105
+ */
106
+ export declare function createA2AAuthStatus(errorCode: A2AAuthErrorCode, metadata?: Record<string, string>): GrpcStatus;
107
+ export {};
108
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/auth/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH;;;GAGG;AACH,eAAO,MAAM,cAAc;;;;;;;;CAQjB,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,OAAO,cAAc,CAAC,CAAC;AAMvF;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,6CAA6C;IAC7C,QAAQ,CAAC,OAAO,EAAE,0CAA0C,CAAC;IAC7D,2DAA2D;IAC3D,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,oEAAoE;IACpE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAMD;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,iCAAiC;IACjC,QAAQ,CAAC,IAAI,EAAE,mBAAmB,CAAC;IACnC,mCAAmC;IACnC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAeD,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyC4B,CAAC;AAElD,MAAM,MAAM,gBAAgB,GAAG,MAAM,OAAO,eAAe,CAAC;AAM5D;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,SAAS,EAAE,gBAAgB,EAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAChC,UAAU,CAcZ"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * A2A auth event to PEAC evidence mapping.
3
+ *
4
+ * Maps A2A OAuth authentication events to access extension observations.
5
+ * Auth success produces an **observation** receipt, never an automatic
6
+ * access-decision receipt. The caller must explicitly construct
7
+ * access-decision receipts when a business-level decision is made.
8
+ */
9
+ import type { JsonObject } from '@peac/kernel';
10
+ import { ACCESS_EXTENSION_KEY } from '@peac/schema';
11
+ /** Supported A2A auth methods */
12
+ export type A2AAuthMethod = 'oauth2_pkce' | 'oauth2_device_code' | 'oauth2_client_credentials';
13
+ /**
14
+ * Input event describing an A2A authentication occurrence.
15
+ *
16
+ * This represents what happened at the auth layer, not a business
17
+ * decision about whether to grant access.
18
+ */
19
+ export interface A2AAuthEvent {
20
+ /** Auth method used */
21
+ readonly method: A2AAuthMethod;
22
+ /** Resource URI that was authenticated against */
23
+ readonly resource: string;
24
+ /** Action that was requested (e.g., 'authenticate', 'tasks/send') */
25
+ readonly action: string;
26
+ /** OAuth scopes that were granted (from token response) */
27
+ readonly grantedScopes?: readonly string[];
28
+ /** Authorization server that issued the token */
29
+ readonly authServer?: string;
30
+ /** Client identifier used */
31
+ readonly clientId?: string;
32
+ /** ISO 8601 timestamp of the auth event */
33
+ readonly timestamp?: string;
34
+ }
35
+ /**
36
+ * Output structure for the access extension in a Wire 0.2 receipt.
37
+ *
38
+ * Uses `org.peacprotocol/access` extension group with `auth_event`
39
+ * set to `'observation'` to distinguish from access-decision receipts.
40
+ */
41
+ export interface A2AAuthEvidenceResult {
42
+ /** Extension key for receipt `ext` field */
43
+ readonly extensionKey: typeof ACCESS_EXTENSION_KEY;
44
+ /** Access extension fields for the receipt */
45
+ readonly extension: {
46
+ readonly resource: string;
47
+ readonly action: string;
48
+ readonly decision: 'review';
49
+ };
50
+ /** Additional evidence metadata for the receipt `evidence` field */
51
+ readonly evidence: JsonObject;
52
+ }
53
+ /**
54
+ * Map an A2A auth event to access extension evidence.
55
+ *
56
+ * Produces an **observation** receipt: `decision` is always `'review'`,
57
+ * indicating that authentication occurred but no access decision was
58
+ * made by the evidence layer. Callers who need `'allow'` or `'deny'`
59
+ * decisions must explicitly construct those receipts.
60
+ *
61
+ * Tokens are never included in the evidence. Only structural metadata
62
+ * (method, scopes, server, client_id) is recorded.
63
+ *
64
+ * @param event - A2A auth event to map
65
+ * @returns Extension data and evidence metadata for receipt construction
66
+ */
67
+ export declare function fromA2AAuthEvent(event: A2AAuthEvent): A2AAuthEvidenceResult;
68
+ //# sourceMappingURL=evidence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evidence.d.ts","sourceRoot":"","sources":["../../src/auth/evidence.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAMpD,iCAAiC;AACjC,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,oBAAoB,GAAG,2BAA2B,CAAC;AAE/F;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,uBAAuB;IACvB,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,kDAAkD;IAClD,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,qEAAqE;IACrE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,2DAA2D;IAC3D,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,iDAAiD;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,6BAA6B;IAC7B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,2CAA2C;IAC3C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,4CAA4C;IAC5C,QAAQ,CAAC,YAAY,EAAE,OAAO,oBAAoB,CAAC;IACnD,8CAA8C;IAC9C,QAAQ,CAAC,SAAS,EAAE;QAClB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;KAC7B,CAAC;IACF,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC;CAC/B;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,YAAY,GAAG,qBAAqB,CAmC3E"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * A2A v1.0 authentication surface.
3
+ *
4
+ * OAuth 2.0 PKCE (S256), Device Code types, auth evidence mapping,
5
+ * and google.rpc.Status error modeling.
6
+ */
7
+ export { generatePKCEChallenge, computeS256Challenge, validatePKCEVerifier } from './pkce.js';
8
+ export type { PKCEChallenge } from './pkce.js';
9
+ export { buildAuthorizationRequest, exchangeAuthorizationCode } from './oauth.js';
10
+ export type { A2AOAuthConfig, AuthorizationRequest, TokenResponse, FetchFn } from './oauth.js';
11
+ export type { A2ADeviceCodeFlowConfig, DeviceCodeRequest, DeviceCodeResponse, DeviceCodePollingError, DeviceCodeErrorResponse, DeviceCodeTokenResponse, } from './device-code.js';
12
+ export { fromA2AAuthEvent } from './evidence.js';
13
+ export type { A2AAuthMethod, A2AAuthEvent, A2AAuthEvidenceResult } from './evidence.js';
14
+ export { GrpcStatusCode, createA2AAuthStatus } from './errors.js';
15
+ export type { GrpcStatusCodeValue, GrpcErrorInfo, GrpcStatus, A2AAuthErrorCode } from './errors.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAC9F,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAG/C,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAClF,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG/F,YAAY,EACV,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,GACxB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAGxF,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClE,YAAY,EAAE,mBAAmB,EAAE,aAAa,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * OAuth 2.0 authorization code flow utilities for A2A v1.0.
3
+ *
4
+ * A2A v1.0 specifies OAuth 2.0 with PKCE as the preferred auth model.
5
+ * All network calls accept a `fetchFn` parameter (no global fetch).
6
+ *
7
+ * Config field names mirror the A2A spec OAuth flow object:
8
+ * authorizationUrl, tokenUrl, refreshUrl, scopes, pkceRequired.
9
+ */
10
+ /**
11
+ * Minimal fetch signature for OAuth network calls.
12
+ *
13
+ * Narrower than global `fetch` to avoid coupling to runtime-specific
14
+ * fetch extensions (AbortSignal, Request objects, etc.).
15
+ */
16
+ export type FetchFn = (url: string, init: {
17
+ method: string;
18
+ headers: Record<string, string>;
19
+ body: string;
20
+ }) => Promise<{
21
+ ok: boolean;
22
+ status: number;
23
+ json: () => Promise<unknown>;
24
+ text: () => Promise<string>;
25
+ }>;
26
+ /**
27
+ * OAuth 2.0 configuration for an A2A authorization server.
28
+ *
29
+ * Field names mirror the A2A spec OAuth flow object.
30
+ */
31
+ export interface A2AOAuthConfig {
32
+ /** Authorization endpoint URL (HTTPS required) */
33
+ readonly authorizationUrl: string;
34
+ /** Token endpoint URL (HTTPS required) */
35
+ readonly tokenUrl: string;
36
+ /** Refresh token endpoint URL (optional, HTTPS required) */
37
+ readonly refreshUrl?: string;
38
+ /** Client identifier */
39
+ readonly clientId: string;
40
+ /** Redirect URI for authorization code delivery (HTTPS required) */
41
+ readonly redirectUri: string;
42
+ /** Requested scopes */
43
+ readonly scopes?: readonly string[];
44
+ /** Whether PKCE is required (always true for A2A v1.0) */
45
+ readonly pkceRequired?: boolean;
46
+ /** Additional authorization parameters (must not override reserved params) */
47
+ readonly extraParams?: Readonly<Record<string, string>>;
48
+ }
49
+ /**
50
+ * Authorization request parameters for constructing the redirect URL.
51
+ */
52
+ export interface AuthorizationRequest {
53
+ /** Full authorization URL with query parameters */
54
+ readonly url: string;
55
+ /** PKCE code verifier (store securely; needed for token exchange) */
56
+ readonly codeVerifier: string;
57
+ /** State parameter for CSRF protection */
58
+ readonly state: string;
59
+ }
60
+ /**
61
+ * OAuth 2.0 token response from the authorization server.
62
+ */
63
+ export interface TokenResponse {
64
+ readonly access_token: string;
65
+ readonly token_type: string;
66
+ readonly expires_in?: number;
67
+ readonly refresh_token?: string;
68
+ readonly scope?: string;
69
+ }
70
+ /**
71
+ * Build an authorization URL with PKCE challenge and state parameter.
72
+ *
73
+ * The caller must redirect the user-agent to the returned URL. The
74
+ * `codeVerifier` must be stored securely for the subsequent token
75
+ * exchange call.
76
+ *
77
+ * @param config - A2A OAuth server configuration
78
+ * @param pkce - PKCE challenge pair (from `generatePKCEChallenge()`)
79
+ * @returns Authorization request with URL, verifier, and state
80
+ * @throws Error if endpoint URLs are not HTTPS or extraParams override reserved params
81
+ */
82
+ export declare function buildAuthorizationRequest(config: A2AOAuthConfig, pkce: {
83
+ readonly challenge: string;
84
+ readonly verifier: string;
85
+ }): AuthorizationRequest;
86
+ /**
87
+ * Exchange an authorization code for tokens.
88
+ *
89
+ * Sends a POST to the token endpoint with the authorization code and
90
+ * PKCE code verifier. Validates the verifier format before sending.
91
+ *
92
+ * @param code - Authorization code from the redirect callback
93
+ * @param verifier - PKCE code verifier from the authorization request
94
+ * @param config - A2A OAuth server configuration
95
+ * @param fetchFn - Fetch implementation (no global fetch)
96
+ * @returns Token response from the authorization server
97
+ * @throws Error if the token endpoint returns an error response
98
+ */
99
+ export declare function exchangeAuthorizationCode(code: string, verifier: string, config: A2AOAuthConfig, fetchFn: FetchFn): Promise<TokenResponse>;
100
+ //# sourceMappingURL=oauth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH;;;;;GAKG;AACH,MAAM,MAAM,OAAO,GAAG,CACpB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IACJ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;CACd,KACE,OAAO,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,IAAI,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;CAC7B,CAAC,CAAC;AAMH;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,wBAAwB;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,oEAAoE;IACpE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,uBAAuB;IACvB,QAAQ,CAAC,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACpC,0DAA0D;IAC1D,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAChC,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACzD;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,mDAAmD;IACnD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,0CAA0C;IAC1C,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAuBD;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE;IAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GAC9D,oBAAoB,CAgCtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,cAAc,EACtB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,aAAa,CAAC,CAyCxB"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * PKCE (Proof Key for Code Exchange) utilities for A2A OAuth flows.
3
+ *
4
+ * Implements S256 challenge method per RFC 7636. Plain method is
5
+ * rejected: S256 is the only method permitted by A2A v1.0.
6
+ */
7
+ /**
8
+ * Result of PKCE challenge generation.
9
+ */
10
+ export interface PKCEChallenge {
11
+ /** High-entropy code verifier (43-128 unreserved chars) */
12
+ readonly verifier: string;
13
+ /** Base64url-encoded SHA-256 hash of the verifier */
14
+ readonly challenge: string;
15
+ /** Always 'S256' */
16
+ readonly method: 'S256';
17
+ }
18
+ /**
19
+ * Generate a PKCE code verifier and S256 challenge.
20
+ *
21
+ * Uses `crypto.getRandomValues()` for verifier entropy (32 bytes,
22
+ * base64url-encoded to 43 chars). S256 only; plain method is not
23
+ * supported per A2A v1.0 security requirements.
24
+ *
25
+ * @returns PKCE verifier + challenge pair
26
+ */
27
+ export declare function generatePKCEChallenge(): Promise<PKCEChallenge>;
28
+ /**
29
+ * Compute the S256 challenge for a given verifier.
30
+ *
31
+ * `BASE64URL(SHA256(ASCII(code_verifier)))` per RFC 7636 Section 4.2.
32
+ *
33
+ * @param verifier - Code verifier string
34
+ * @returns Base64url-encoded SHA-256 digest
35
+ * @throws Error if verifier does not meet RFC 7636 requirements
36
+ */
37
+ export declare function computeS256Challenge(verifier: string): Promise<string>;
38
+ /**
39
+ * Validate that a PKCE code verifier meets RFC 7636 requirements.
40
+ *
41
+ * Checks length (43-128) and character set (unreserved per RFC 7636 Section 4.1).
42
+ *
43
+ * @param verifier - Code verifier to validate
44
+ * @throws Error with code `E_PKCE_INVALID_VERIFIER` if invalid
45
+ */
46
+ export declare function validatePKCEVerifier(verifier: string): void;
47
+ //# sourceMappingURL=pkce.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAmBH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,oBAAoB;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;;GAQG;AACH,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,aAAa,CAAC,CAMpE;AAED;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAM5E;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE3D"}