@adcp/sdk 7.6.0 → 7.7.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.
- package/bin/adcp.js +3 -1
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/test-controller.d.ts +46 -1
- package/dist/lib/server/test-controller.d.ts.map +1 -1
- package/dist/lib/server/test-controller.js +49 -2
- package/dist/lib/server/test-controller.js.map +1 -1
- package/dist/lib/signing/canonicalize.d.ts +53 -0
- package/dist/lib/signing/canonicalize.d.ts.map +1 -1
- package/dist/lib/signing/canonicalize.js +33 -1
- package/dist/lib/signing/canonicalize.js.map +1 -1
- package/dist/lib/signing/client.d.ts +6 -5
- package/dist/lib/signing/client.d.ts.map +1 -1
- package/dist/lib/signing/client.js +16 -1
- package/dist/lib/signing/client.js.map +1 -1
- package/dist/lib/signing/errors.d.ts +11 -0
- package/dist/lib/signing/errors.d.ts.map +1 -1
- package/dist/lib/signing/errors.js +11 -1
- package/dist/lib/signing/errors.js.map +1 -1
- package/dist/lib/signing/jwks-helpers.d.ts +4 -1
- package/dist/lib/signing/jwks-helpers.d.ts.map +1 -1
- package/dist/lib/signing/jwks-helpers.js.map +1 -1
- package/dist/lib/signing/provider.d.ts +17 -0
- package/dist/lib/signing/provider.d.ts.map +1 -1
- package/dist/lib/signing/replay.d.ts +16 -0
- package/dist/lib/signing/replay.d.ts.map +1 -1
- package/dist/lib/signing/replay.js.map +1 -1
- package/dist/lib/signing/request-context.d.ts +140 -0
- package/dist/lib/signing/request-context.d.ts.map +1 -0
- package/dist/lib/signing/request-context.js +160 -0
- package/dist/lib/signing/request-context.js.map +1 -0
- package/dist/lib/signing/response-verifier.d.ts +105 -0
- package/dist/lib/signing/response-verifier.d.ts.map +1 -0
- package/dist/lib/signing/response-verifier.js +271 -0
- package/dist/lib/signing/response-verifier.js.map +1 -0
- package/dist/lib/signing/server.d.ts +5 -3
- package/dist/lib/signing/server.d.ts.map +1 -1
- package/dist/lib/signing/server.js +13 -1
- package/dist/lib/signing/server.js.map +1 -1
- package/dist/lib/signing/signer-async.d.ts +8 -2
- package/dist/lib/signing/signer-async.d.ts.map +1 -1
- package/dist/lib/signing/signer-async.js +14 -0
- package/dist/lib/signing/signer-async.js.map +1 -1
- package/dist/lib/signing/signer.d.ts +149 -1
- package/dist/lib/signing/signer.d.ts.map +1 -1
- package/dist/lib/signing/signer.js +164 -0
- package/dist/lib/signing/signer.js.map +1 -1
- package/dist/lib/signing/testing.d.ts +10 -0
- package/dist/lib/signing/testing.d.ts.map +1 -1
- package/dist/lib/signing/testing.js +9 -0
- package/dist/lib/signing/testing.js.map +1 -1
- package/dist/lib/signing/types.d.ts +36 -0
- package/dist/lib/signing/types.d.ts.map +1 -1
- package/dist/lib/signing/types.js +37 -1
- package/dist/lib/signing/types.js.map +1 -1
- package/dist/lib/testing/comply-controller.d.ts +26 -1
- package/dist/lib/testing/comply-controller.d.ts.map +1 -1
- package/dist/lib/testing/comply-controller.js +17 -7
- package/dist/lib/testing/comply-controller.js.map +1 -1
- package/dist/lib/testing/index.d.ts +1 -1
- package/dist/lib/testing/index.d.ts.map +1 -1
- package/dist/lib/testing/index.js.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.js +10 -1
- package/dist/lib/testing/storyboard/request-signing/builder.js.map +1 -1
- package/dist/lib/testing/storyboard/runner.d.ts +9 -1
- package/dist/lib/testing/storyboard/runner.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/runner.js +17 -1
- package/dist/lib/testing/storyboard/runner.js.map +1 -1
- package/dist/lib/testing/storyboard/types.d.ts +43 -1
- package/dist/lib/testing/storyboard/types.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/types.js.map +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts.map +1 -1
- package/dist/lib/testing/storyboard/validations.js +182 -0
- package/dist/lib/testing/storyboard/validations.js.map +1 -1
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/package.json +1 -1
|
@@ -1,10 +1,39 @@
|
|
|
1
|
-
import { type RequestLike, type SignatureParams } from './canonicalize';
|
|
1
|
+
import { type RequestLike, type ResponseLike, type SignatureParams } from './canonicalize';
|
|
2
|
+
import type { AdcpUse } from './jwks-helpers';
|
|
2
3
|
import { type AdcpJsonWebKey, type AdcpSignAlg } from './types';
|
|
3
4
|
export interface SignerKey {
|
|
4
5
|
keyid: string;
|
|
5
6
|
alg: 'ed25519' | 'ecdsa-p256-sha256';
|
|
7
|
+
/**
|
|
8
|
+
* Private JWK. MUST carry `adcp_use` matching the helper being called:
|
|
9
|
+
* - `signRequest` requires `adcp_use: 'request-signing'`
|
|
10
|
+
* - `signWebhook` requires `adcp_use: 'webhook-signing'`
|
|
11
|
+
* - `signResponse` requires `adcp_use: 'response-signing'`
|
|
12
|
+
*
|
|
13
|
+
* Mismatched or missing `adcp_use` throws at the signer with the same
|
|
14
|
+
* error code the verifier raises at step 8 — failure surfaces at
|
|
15
|
+
* configuration time rather than at the receiver, where the message is
|
|
16
|
+
* far from its cause. Mint keys with `pemToAdcpJwk({ adcp_use: ... })`
|
|
17
|
+
* to get the binding right by construction.
|
|
18
|
+
*/
|
|
6
19
|
privateKey: AdcpJsonWebKey;
|
|
7
20
|
}
|
|
21
|
+
/**
|
|
22
|
+
* Async-path equivalent. Mirrors {@link assertKeyPurpose} but reads
|
|
23
|
+
* `adcpUse` from a {@link SigningProvider} rather than a `SignerKey`.
|
|
24
|
+
*
|
|
25
|
+
* **Optional binding.** When `provider.adcpUse` is `undefined`, the gate
|
|
26
|
+
* is skipped — preserves backward compat with adapters that pre-date the
|
|
27
|
+
* `SigningProvider.adcpUse` field. Adapter authors who want signer-side
|
|
28
|
+
* defense-in-depth set `adcpUse` on their provider; the async helpers
|
|
29
|
+
* (`signRequestAsync` / `signWebhookAsync` / `signResponseAsync`) then
|
|
30
|
+
* enforce the binding parallel to the sync path.
|
|
31
|
+
*/
|
|
32
|
+
declare function assertProviderPurpose(provider: {
|
|
33
|
+
readonly keyid: string;
|
|
34
|
+
readonly adcpUse?: AdcpUse;
|
|
35
|
+
}, expected: AdcpUse): void;
|
|
36
|
+
export { assertProviderPurpose };
|
|
8
37
|
export interface SignRequestOptions {
|
|
9
38
|
coverContentDigest?: boolean;
|
|
10
39
|
label?: string;
|
|
@@ -49,6 +78,15 @@ export interface PreparedRequestSignature {
|
|
|
49
78
|
* Canonicalize a request for RFC 9421 request-signing. Pure (no I/O); the
|
|
50
79
|
* sync and async paths share this so canonicalization can't drift between
|
|
51
80
|
* them.
|
|
81
|
+
*
|
|
82
|
+
* **No purpose-binding gate.** This function takes a `SignatureIdentity`
|
|
83
|
+
* (just `keyid` + `alg`), not a full `SignerKey`, so it deliberately
|
|
84
|
+
* cannot enforce `adcp_use`. Callers composing `prepare* + own-signer`
|
|
85
|
+
* are responsible for purpose binding themselves — the convenience
|
|
86
|
+
* helper `signRequest` runs `assertKeyPurpose` before calling this and
|
|
87
|
+
* is what most adopters want. Test-vector authors who need to sign with
|
|
88
|
+
* wrong-purpose keys (e.g. AdCP negative-vector 009 cross-purpose
|
|
89
|
+
* rejection) use this prepare/finalize composition deliberately.
|
|
52
90
|
*/
|
|
53
91
|
export declare function prepareRequestSignature(request: RequestLike, identity: SignatureIdentity, options?: SignRequestOptions): PreparedRequestSignature;
|
|
54
92
|
/**
|
|
@@ -81,6 +119,10 @@ export interface SignWebhookOptions {
|
|
|
81
119
|
* `signWebhookAsync` paths. Covers the five mandatory components —
|
|
82
120
|
* `@method`, `@target-uri`, `@authority`, `content-type`, `content-digest` —
|
|
83
121
|
* and sets `Content-Digest` on the outgoing headers.
|
|
122
|
+
*
|
|
123
|
+
* **No purpose-binding gate** — same caveat as
|
|
124
|
+
* {@link prepareRequestSignature}. The convenience helper `signWebhook`
|
|
125
|
+
* runs `assertKeyPurpose` before calling this.
|
|
84
126
|
*/
|
|
85
127
|
export declare function prepareWebhookSignature(request: RequestLike, identity: SignatureIdentity, options?: SignWebhookOptions): PreparedRequestSignature;
|
|
86
128
|
/**
|
|
@@ -91,4 +133,110 @@ export declare function prepareWebhookSignature(request: RequestLike, identity:
|
|
|
91
133
|
* conformant webhooks should use this instead of hand-rolling signatures.
|
|
92
134
|
*/
|
|
93
135
|
export declare function signWebhook(request: RequestLike, key: SignerKey, options?: SignWebhookOptions): SignedRequest;
|
|
136
|
+
export interface SignResponseOptions {
|
|
137
|
+
/**
|
|
138
|
+
* Cover a `Content-Digest` of the response body. Defaults to `true` when
|
|
139
|
+
* the response has a body.
|
|
140
|
+
*
|
|
141
|
+
* **Asymmetric with `signRequest`.** Request signing defaults to opt-in
|
|
142
|
+
* (`coverContentDigest: true` required to cover); response signing
|
|
143
|
+
* defaults to opt-out because an unbound body is the most common
|
|
144
|
+
* cross-purpose footgun for response signing — without a body digest,
|
|
145
|
+
* an attacker that can swap the payload but preserve headers can pass
|
|
146
|
+
* the signature check. The asymmetry is deliberate; callers that want
|
|
147
|
+
* to omit (e.g. when an upstream proxy computes the digest) pass
|
|
148
|
+
* `false` explicitly.
|
|
149
|
+
*/
|
|
150
|
+
coverContentDigest?: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Additional derived/header components to cover beyond
|
|
153
|
+
* {@link RESPONSE_MANDATORY_COMPONENTS}. The defaults already include
|
|
154
|
+
* `@status`, `@authority`, and `@target-uri`. Use this for `@method`
|
|
155
|
+
* (uncommon for responses — request method is usually implicit) or for
|
|
156
|
+
* custom headers (`x-content-type-options`, etc.).
|
|
157
|
+
*/
|
|
158
|
+
additionalComponents?: ReadonlyArray<string>;
|
|
159
|
+
label?: string;
|
|
160
|
+
windowSeconds?: number;
|
|
161
|
+
now?: () => number;
|
|
162
|
+
nonce?: string;
|
|
163
|
+
/**
|
|
164
|
+
* Override the signature tag. Defaults to `adcp/response-signing/v1`.
|
|
165
|
+
* Exposed so test suites can pin a wrong tag to exercise receiver
|
|
166
|
+
* rejection paths without mutating the signed headers post-hoc.
|
|
167
|
+
*/
|
|
168
|
+
tag?: string;
|
|
169
|
+
}
|
|
170
|
+
export interface SignedResponse {
|
|
171
|
+
status: number;
|
|
172
|
+
headers: Record<string, string>;
|
|
173
|
+
signatureBase: string;
|
|
174
|
+
params: SignatureParams;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Result of canonicalizing a response for signing — everything `signResponse`
|
|
178
|
+
* and `signResponseAsync` produce up to (but not including) the call into
|
|
179
|
+
* the signer/provider.
|
|
180
|
+
*/
|
|
181
|
+
export interface PreparedResponseSignature {
|
|
182
|
+
status: number;
|
|
183
|
+
components: string[];
|
|
184
|
+
params: SignatureParams;
|
|
185
|
+
/**
|
|
186
|
+
* Outbound response headers including `Content-Digest` when covered, but
|
|
187
|
+
* not yet including `Signature-Input` / `Signature` — those are appended
|
|
188
|
+
* by {@link finalizeResponseSignature}.
|
|
189
|
+
*/
|
|
190
|
+
headers: Record<string, string>;
|
|
191
|
+
/** Canonical signature base bytes (UTF-8). Pass to the signer/provider. */
|
|
192
|
+
base: string;
|
|
193
|
+
label: string;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Canonicalize a response for RFC 9421 response-signing (§2.2.9). Pure
|
|
197
|
+
* (no I/O); shared between sync `signResponse` and async `signResponseAsync`
|
|
198
|
+
* so canonicalization can't drift between them. Covers
|
|
199
|
+
* {@link RESPONSE_MANDATORY_COMPONENTS} by default; adds `content-type` +
|
|
200
|
+
* `content-digest` automatically when the response carries a body. Callers
|
|
201
|
+
* can extend the covered set via
|
|
202
|
+
* {@link SignResponseOptions.additionalComponents}.
|
|
203
|
+
*
|
|
204
|
+
* **No purpose-binding gate** — same caveat as
|
|
205
|
+
* {@link prepareRequestSignature}. The convenience helper `signResponse`
|
|
206
|
+
* runs `assertKeyPurpose` before calling this.
|
|
207
|
+
*/
|
|
208
|
+
export declare function prepareResponseSignature(response: ResponseLike, identity: SignatureIdentity, options?: SignResponseOptions): PreparedResponseSignature;
|
|
209
|
+
/**
|
|
210
|
+
* Attach `Signature` / `Signature-Input` headers given the bytes returned
|
|
211
|
+
* by the signer/provider. Mirrors {@link finalizeRequestSignature} but
|
|
212
|
+
* returns a {@link SignedResponse} that carries the response status alongside
|
|
213
|
+
* the stamped headers so the caller can hand the whole object back to its
|
|
214
|
+
* HTTP layer.
|
|
215
|
+
*/
|
|
216
|
+
export declare function finalizeResponseSignature(prepared: PreparedResponseSignature, signature: Uint8Array): SignedResponse;
|
|
217
|
+
/**
|
|
218
|
+
* Sign an outbound response under the RFC 9421 response-signing profile
|
|
219
|
+
* (`tag=adcp/response-signing/v1`). Covers `@status` and `@authority` by
|
|
220
|
+
* default, plus `content-type` + `content-digest` when a body is present.
|
|
221
|
+
* Servers emitting signed responses (e.g. seller agents whose clients
|
|
222
|
+
* verify `get_products` payloads before parsing) should use this instead
|
|
223
|
+
* of hand-rolling signatures.
|
|
224
|
+
*
|
|
225
|
+
* Returns headers as a plain `Record<string, string>` for direct use with
|
|
226
|
+
* Express (`res.set(signed.headers)`). For Fetch / Node `Response` (where
|
|
227
|
+
* the headers object is immutable on construction), spread into the
|
|
228
|
+
* `Headers` constructor or `setHeader` loop:
|
|
229
|
+
*
|
|
230
|
+
* ```ts
|
|
231
|
+
* // Express
|
|
232
|
+
* res.status(signed.status).set(signed.headers).send(body);
|
|
233
|
+
*
|
|
234
|
+
* // Fetch / Workers / Node 20+ Response
|
|
235
|
+
* return new Response(body, { status: signed.status, headers: signed.headers });
|
|
236
|
+
*
|
|
237
|
+
* // Node `http.ServerResponse`
|
|
238
|
+
* res.writeHead(signed.status, signed.headers).end(body);
|
|
239
|
+
* ```
|
|
240
|
+
*/
|
|
241
|
+
export declare function signResponse(response: ResponseLike, key: SignerKey, options?: SignResponseOptions): SignedResponse;
|
|
94
242
|
//# sourceMappingURL=signer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../../src/lib/signing/signer.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../../src/lib/signing/signer.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,eAAe,EACrB,MAAM,gBAAgB,CAAC;AAGxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAML,KAAK,cAAc,EACnB,KAAK,WAAW,EACjB,MAAM,SAAS,CAAC;AAGjB,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,SAAS,GAAG,mBAAmB,CAAC;IACrC;;;;;;;;;;;OAWG;IACH,UAAU,EAAE,cAAc,CAAC;CAC5B;AAkBD;;;;;;;;;;GAUG;AACH,iBAAS,qBAAqB,CAC5B,QAAQ,EAAE;IAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,EAChE,QAAQ,EAAE,OAAO,GAChB,IAAI,CAGN;AAyBD,OAAO,EAAE,qBAAqB,EAAE,CAAC;AAEjC,MAAM,WAAW,kBAAkB;IACjC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,WAAW,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,kBAAuB,GAC/B,wBAAwB,CA8B1B;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,wBAAwB,EAAE,SAAS,EAAE,UAAU,GAAG,aAAa,CAMjH;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,GAAE,kBAAuB,GAAG,aAAa,CAKjH;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,WAAW,EACpB,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,kBAAuB,GAC/B,wBAAwB,CAuB1B;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,WAAW,EAAE,GAAG,EAAE,SAAS,EAAE,OAAO,GAAE,kBAAuB,GAAG,aAAa,CAKjH;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;;OAYG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,eAAe,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,MAAM,EAAE,eAAe,CAAC;IACxB;;;;OAIG;IACH,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,GAAE,mBAAwB,GAChC,yBAAyB,CAmC3B;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,yBAAyB,EAAE,SAAS,EAAE,UAAU,GAAG,cAAc,CAMpH;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,SAAS,EACd,OAAO,GAAE,mBAAwB,GAChC,cAAc,CAKhB"}
|
|
@@ -1,19 +1,86 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.assertProviderPurpose = assertProviderPurpose;
|
|
3
4
|
exports.prepareRequestSignature = prepareRequestSignature;
|
|
4
5
|
exports.finalizeRequestSignature = finalizeRequestSignature;
|
|
5
6
|
exports.signRequest = signRequest;
|
|
6
7
|
exports.prepareWebhookSignature = prepareWebhookSignature;
|
|
7
8
|
exports.signWebhook = signWebhook;
|
|
9
|
+
exports.prepareResponseSignature = prepareResponseSignature;
|
|
10
|
+
exports.finalizeResponseSignature = finalizeResponseSignature;
|
|
11
|
+
exports.signResponse = signResponse;
|
|
8
12
|
const crypto_1 = require("crypto");
|
|
9
13
|
const canonicalize_1 = require("./canonicalize");
|
|
10
14
|
const content_digest_1 = require("./content-digest");
|
|
15
|
+
const errors_1 = require("./errors");
|
|
11
16
|
const types_1 = require("./types");
|
|
12
17
|
const webhook_verifier_1 = require("./webhook-verifier");
|
|
18
|
+
/**
|
|
19
|
+
* Step-8-equivalent purpose-binding gate on the signer side. The verifier
|
|
20
|
+
* already enforces `jwk.adcp_use === expected` at step 8 (see verifier.ts
|
|
21
|
+
* for request signing; webhook-verifier.ts for webhooks). Replicating the
|
|
22
|
+
* check on the signer side prevents the more common operator footgun:
|
|
23
|
+
* passing a wrong-purpose key into the helper, producing a wire-conformant
|
|
24
|
+
* signature that the downstream verifier then rejects, surfacing the
|
|
25
|
+
* misconfiguration at the wrong end of the connection.
|
|
26
|
+
*
|
|
27
|
+
* Errors emit the same code the verifier uses for that direction so log
|
|
28
|
+
* scrapers across signer / verifier see consistent vocabulary.
|
|
29
|
+
*/
|
|
30
|
+
function assertKeyPurpose(key, expected) {
|
|
31
|
+
throwIfPurposeMismatch(key.keyid, key.privateKey.adcp_use, expected);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Async-path equivalent. Mirrors {@link assertKeyPurpose} but reads
|
|
35
|
+
* `adcpUse` from a {@link SigningProvider} rather than a `SignerKey`.
|
|
36
|
+
*
|
|
37
|
+
* **Optional binding.** When `provider.adcpUse` is `undefined`, the gate
|
|
38
|
+
* is skipped — preserves backward compat with adapters that pre-date the
|
|
39
|
+
* `SigningProvider.adcpUse` field. Adapter authors who want signer-side
|
|
40
|
+
* defense-in-depth set `adcpUse` on their provider; the async helpers
|
|
41
|
+
* (`signRequestAsync` / `signWebhookAsync` / `signResponseAsync`) then
|
|
42
|
+
* enforce the binding parallel to the sync path.
|
|
43
|
+
*/
|
|
44
|
+
function assertProviderPurpose(provider, expected) {
|
|
45
|
+
if (provider.adcpUse === undefined)
|
|
46
|
+
return;
|
|
47
|
+
throwIfPurposeMismatch(provider.keyid, provider.adcpUse, expected);
|
|
48
|
+
}
|
|
49
|
+
function throwIfPurposeMismatch(keyid, actual, expected) {
|
|
50
|
+
if (actual === expected)
|
|
51
|
+
return;
|
|
52
|
+
const message = `Signing key '${keyid}' has adcp_use=${actual === undefined ? '<missing>' : `'${actual}'`} ` +
|
|
53
|
+
`but the helper requires '${expected}'. Mint a key scoped for '${expected}' via ` +
|
|
54
|
+
`pemToAdcpJwk({ adcp_use: '${expected}' }) — sharing keys across purposes is intentionally refused.`;
|
|
55
|
+
switch (expected) {
|
|
56
|
+
case 'request-signing':
|
|
57
|
+
throw new errors_1.RequestSignatureError('request_signature_key_purpose_invalid', 8, message);
|
|
58
|
+
case 'webhook-signing':
|
|
59
|
+
throw new errors_1.WebhookSignatureError('webhook_signature_key_purpose_invalid', 8, message);
|
|
60
|
+
case 'response-signing':
|
|
61
|
+
throw new errors_1.ResponseSignatureError('response_signature_key_purpose_invalid', 8, message);
|
|
62
|
+
default: {
|
|
63
|
+
// Compile-time exhaustiveness: a future `AdcpUse` widening must add
|
|
64
|
+
// a case arm here. Trips `tsc --noEmit` if the union grows without
|
|
65
|
+
// an explicit gate decision for the new member.
|
|
66
|
+
const _exhaustive = expected;
|
|
67
|
+
throw new Error(`unreachable: unhandled AdcpUse '${_exhaustive}'`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
13
71
|
/**
|
|
14
72
|
* Canonicalize a request for RFC 9421 request-signing. Pure (no I/O); the
|
|
15
73
|
* sync and async paths share this so canonicalization can't drift between
|
|
16
74
|
* them.
|
|
75
|
+
*
|
|
76
|
+
* **No purpose-binding gate.** This function takes a `SignatureIdentity`
|
|
77
|
+
* (just `keyid` + `alg`), not a full `SignerKey`, so it deliberately
|
|
78
|
+
* cannot enforce `adcp_use`. Callers composing `prepare* + own-signer`
|
|
79
|
+
* are responsible for purpose binding themselves — the convenience
|
|
80
|
+
* helper `signRequest` runs `assertKeyPurpose` before calling this and
|
|
81
|
+
* is what most adopters want. Test-vector authors who need to sign with
|
|
82
|
+
* wrong-purpose keys (e.g. AdCP negative-vector 009 cross-purpose
|
|
83
|
+
* rejection) use this prepare/finalize composition deliberately.
|
|
17
84
|
*/
|
|
18
85
|
function prepareRequestSignature(request, identity, options = {}) {
|
|
19
86
|
const now = options.now ? options.now() : Math.floor(Date.now() / 1000);
|
|
@@ -61,6 +128,7 @@ function finalizeRequestSignature(prepared, signature) {
|
|
|
61
128
|
return { headers, signatureBase: prepared.base, params: prepared.params };
|
|
62
129
|
}
|
|
63
130
|
function signRequest(request, key, options = {}) {
|
|
131
|
+
assertKeyPurpose(key, 'request-signing');
|
|
64
132
|
const prepared = prepareRequestSignature(request, { keyid: key.keyid, alg: key.alg }, options);
|
|
65
133
|
const signature = produceSignature(key, Buffer.from(prepared.base, 'utf8'));
|
|
66
134
|
return finalizeRequestSignature(prepared, signature);
|
|
@@ -71,6 +139,10 @@ function signRequest(request, key, options = {}) {
|
|
|
71
139
|
* `signWebhookAsync` paths. Covers the five mandatory components —
|
|
72
140
|
* `@method`, `@target-uri`, `@authority`, `content-type`, `content-digest` —
|
|
73
141
|
* and sets `Content-Digest` on the outgoing headers.
|
|
142
|
+
*
|
|
143
|
+
* **No purpose-binding gate** — same caveat as
|
|
144
|
+
* {@link prepareRequestSignature}. The convenience helper `signWebhook`
|
|
145
|
+
* runs `assertKeyPurpose` before calling this.
|
|
74
146
|
*/
|
|
75
147
|
function prepareWebhookSignature(request, identity, options = {}) {
|
|
76
148
|
const now = options.now ? options.now() : Math.floor(Date.now() / 1000);
|
|
@@ -100,10 +172,102 @@ function prepareWebhookSignature(request, identity, options = {}) {
|
|
|
100
172
|
* conformant webhooks should use this instead of hand-rolling signatures.
|
|
101
173
|
*/
|
|
102
174
|
function signWebhook(request, key, options = {}) {
|
|
175
|
+
assertKeyPurpose(key, 'webhook-signing');
|
|
103
176
|
const prepared = prepareWebhookSignature(request, { keyid: key.keyid, alg: key.alg }, options);
|
|
104
177
|
const signature = produceSignature(key, Buffer.from(prepared.base, 'utf8'));
|
|
105
178
|
return finalizeRequestSignature(prepared, signature);
|
|
106
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* Canonicalize a response for RFC 9421 response-signing (§2.2.9). Pure
|
|
182
|
+
* (no I/O); shared between sync `signResponse` and async `signResponseAsync`
|
|
183
|
+
* so canonicalization can't drift between them. Covers
|
|
184
|
+
* {@link RESPONSE_MANDATORY_COMPONENTS} by default; adds `content-type` +
|
|
185
|
+
* `content-digest` automatically when the response carries a body. Callers
|
|
186
|
+
* can extend the covered set via
|
|
187
|
+
* {@link SignResponseOptions.additionalComponents}.
|
|
188
|
+
*
|
|
189
|
+
* **No purpose-binding gate** — same caveat as
|
|
190
|
+
* {@link prepareRequestSignature}. The convenience helper `signResponse`
|
|
191
|
+
* runs `assertKeyPurpose` before calling this.
|
|
192
|
+
*/
|
|
193
|
+
function prepareResponseSignature(response, identity, options = {}) {
|
|
194
|
+
const now = options.now ? options.now() : Math.floor(Date.now() / 1000);
|
|
195
|
+
const windowSeconds = Math.min(options.windowSeconds ?? 300, types_1.MAX_SIGNATURE_WINDOW_SECONDS);
|
|
196
|
+
const nonce = options.nonce ?? base64UrlRandom(16);
|
|
197
|
+
const label = options.label ?? 'sig1';
|
|
198
|
+
const hasBody = (response.body ?? '').length > 0;
|
|
199
|
+
const coverDigest = (options.coverContentDigest ?? true) && hasBody;
|
|
200
|
+
const headers = { ...flattenHeaders(response.headers) };
|
|
201
|
+
if (coverDigest) {
|
|
202
|
+
headers['Content-Digest'] = (0, content_digest_1.computeContentDigest)(response.body ?? '');
|
|
203
|
+
}
|
|
204
|
+
const components = [...types_1.RESPONSE_MANDATORY_COMPONENTS];
|
|
205
|
+
if (hasBody)
|
|
206
|
+
components.push('content-type');
|
|
207
|
+
if (coverDigest)
|
|
208
|
+
components.push('content-digest');
|
|
209
|
+
if (options.additionalComponents) {
|
|
210
|
+
for (const c of options.additionalComponents) {
|
|
211
|
+
if (!components.includes(c))
|
|
212
|
+
components.push(c);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const params = {
|
|
216
|
+
created: now,
|
|
217
|
+
expires: now + windowSeconds,
|
|
218
|
+
nonce,
|
|
219
|
+
keyid: identity.keyid,
|
|
220
|
+
alg: identity.alg,
|
|
221
|
+
tag: options.tag ?? types_1.RESPONSE_SIGNING_TAG,
|
|
222
|
+
};
|
|
223
|
+
const normalizedResponse = { ...response, headers };
|
|
224
|
+
const base = (0, canonicalize_1.buildResponseSignatureBase)(components, normalizedResponse, params);
|
|
225
|
+
return { status: response.status, components, params, headers, base, label };
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Attach `Signature` / `Signature-Input` headers given the bytes returned
|
|
229
|
+
* by the signer/provider. Mirrors {@link finalizeRequestSignature} but
|
|
230
|
+
* returns a {@link SignedResponse} that carries the response status alongside
|
|
231
|
+
* the stamped headers so the caller can hand the whole object back to its
|
|
232
|
+
* HTTP layer.
|
|
233
|
+
*/
|
|
234
|
+
function finalizeResponseSignature(prepared, signature) {
|
|
235
|
+
const headers = { ...prepared.headers };
|
|
236
|
+
const sigB64 = Buffer.from(signature).toString('base64url');
|
|
237
|
+
headers['Signature-Input'] = `${prepared.label}=${(0, canonicalize_1.formatSignatureParams)(prepared.components, prepared.params)}`;
|
|
238
|
+
headers['Signature'] = `${prepared.label}=:${sigB64}:`;
|
|
239
|
+
return { status: prepared.status, headers, signatureBase: prepared.base, params: prepared.params };
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Sign an outbound response under the RFC 9421 response-signing profile
|
|
243
|
+
* (`tag=adcp/response-signing/v1`). Covers `@status` and `@authority` by
|
|
244
|
+
* default, plus `content-type` + `content-digest` when a body is present.
|
|
245
|
+
* Servers emitting signed responses (e.g. seller agents whose clients
|
|
246
|
+
* verify `get_products` payloads before parsing) should use this instead
|
|
247
|
+
* of hand-rolling signatures.
|
|
248
|
+
*
|
|
249
|
+
* Returns headers as a plain `Record<string, string>` for direct use with
|
|
250
|
+
* Express (`res.set(signed.headers)`). For Fetch / Node `Response` (where
|
|
251
|
+
* the headers object is immutable on construction), spread into the
|
|
252
|
+
* `Headers` constructor or `setHeader` loop:
|
|
253
|
+
*
|
|
254
|
+
* ```ts
|
|
255
|
+
* // Express
|
|
256
|
+
* res.status(signed.status).set(signed.headers).send(body);
|
|
257
|
+
*
|
|
258
|
+
* // Fetch / Workers / Node 20+ Response
|
|
259
|
+
* return new Response(body, { status: signed.status, headers: signed.headers });
|
|
260
|
+
*
|
|
261
|
+
* // Node `http.ServerResponse`
|
|
262
|
+
* res.writeHead(signed.status, signed.headers).end(body);
|
|
263
|
+
* ```
|
|
264
|
+
*/
|
|
265
|
+
function signResponse(response, key, options = {}) {
|
|
266
|
+
assertKeyPurpose(key, 'response-signing');
|
|
267
|
+
const prepared = prepareResponseSignature(response, { keyid: key.keyid, alg: key.alg }, options);
|
|
268
|
+
const signature = produceSignature(key, Buffer.from(prepared.base, 'utf8'));
|
|
269
|
+
return finalizeResponseSignature(prepared, signature);
|
|
270
|
+
}
|
|
107
271
|
function produceSignature(key, data) {
|
|
108
272
|
const privateKey = (0, crypto_1.createPrivateKey)({
|
|
109
273
|
key: key.privateKey,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../../src/lib/signing/signer.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"signer.js","sourceRoot":"","sources":["../../../src/lib/signing/signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,15 @@ export interface InMemorySigningProviderOptions {
|
|
|
16
16
|
algorithm: AdcpSignAlg;
|
|
17
17
|
/** Private JWK including the `d` scalar. */
|
|
18
18
|
privateKey: AdcpJsonWebKey;
|
|
19
|
+
/**
|
|
20
|
+
* Optional purpose binding. When supplied, the async signing helpers
|
|
21
|
+
* (`signRequestAsync` / `signWebhookAsync` / `signResponseAsync`) refuse
|
|
22
|
+
* to sign with a mismatched purpose — same defense-in-depth gate the
|
|
23
|
+
* sync path's `SignerKey.privateKey.adcp_use` provides. Defaults to the
|
|
24
|
+
* value carried on `privateKey.adcp_use` when present, so adapters
|
|
25
|
+
* minted via `pemToAdcpJwk({ adcp_use: ... })` get the binding for free.
|
|
26
|
+
*/
|
|
27
|
+
adcpUse?: AdcpUse;
|
|
19
28
|
}
|
|
20
29
|
/**
|
|
21
30
|
* Reference {@link SigningProvider} that holds the private JWK in process
|
|
@@ -32,6 +41,7 @@ export declare class InMemorySigningProvider implements SigningProvider {
|
|
|
32
41
|
readonly keyid: string;
|
|
33
42
|
readonly algorithm: AdcpSignAlg;
|
|
34
43
|
readonly fingerprint: string;
|
|
44
|
+
readonly adcpUse?: AdcpUse;
|
|
35
45
|
private readonly privateKey;
|
|
36
46
|
constructor(options: InMemorySigningProviderOptions);
|
|
37
47
|
sign(payload: Uint8Array): Promise<Uint8Array>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../src/lib/signing/testing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,gCAAgC,CAAC;
|
|
1
|
+
{"version":3,"file":"testing.d.ts","sourceRoot":"","sources":["../../../src/lib/signing/testing.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAE3D;;;;;GAKG;AACH,eAAO,MAAM,0BAA0B,gCAAgC,CAAC;AAOxE,MAAM,WAAW,8BAA8B;IAC7C,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,SAAS,EAAE,WAAW,CAAC;IACvB,4CAA4C;IAC5C,UAAU,EAAE,cAAc,CAAC;IAC3B;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,uBAAwB,YAAW,eAAe;IAC7D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;IAC3B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiB;gBAEhC,OAAO,EAAE,8BAA8B;IAoC7C,IAAI,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;CAQrD;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,eAAe,CAMnE;AAED,MAAM,WAAW,mBAAmB;IAClC,uCAAuC;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,SAAS,EAAE,WAAW,CAAC;IACvB,kFAAkF;IAClF,SAAS,EAAE,cAAc,CAAC;IAC1B;;;;OAIG;IACH,UAAU,EAAE,cAAc,CAAC;CAC5B;AAED,MAAM,WAAW,8BAA8B;IAC7C;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,uBAAuB,CAAC,IAAI,CAAC,EAAE,8BAA8B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAoCjH"}
|
|
@@ -44,6 +44,10 @@ const node_crypto_1 = require("node:crypto");
|
|
|
44
44
|
* production-time guard.
|
|
45
45
|
*/
|
|
46
46
|
exports.ALLOW_IN_MEMORY_SIGNER_ENV = 'ADCP_ALLOW_IN_MEMORY_SIGNER';
|
|
47
|
+
const ADCP_USE_VALUES = new Set(['request-signing', 'webhook-signing', 'response-signing']);
|
|
48
|
+
function isAdcpUse(value) {
|
|
49
|
+
return typeof value === 'string' && ADCP_USE_VALUES.has(value);
|
|
50
|
+
}
|
|
47
51
|
/**
|
|
48
52
|
* Reference {@link SigningProvider} that holds the private JWK in process
|
|
49
53
|
* memory. Useful for unit tests, conformance vectors, and local development.
|
|
@@ -59,6 +63,7 @@ class InMemorySigningProvider {
|
|
|
59
63
|
keyid;
|
|
60
64
|
algorithm;
|
|
61
65
|
fingerprint;
|
|
66
|
+
adcpUse;
|
|
62
67
|
privateKey;
|
|
63
68
|
constructor(options) {
|
|
64
69
|
// The env is read once at construction. Module-init paths that
|
|
@@ -78,6 +83,10 @@ class InMemorySigningProvider {
|
|
|
78
83
|
this.keyid = options.keyid;
|
|
79
84
|
this.algorithm = options.algorithm;
|
|
80
85
|
this.privateKey = options.privateKey;
|
|
86
|
+
// Prefer explicit `adcpUse` option; fall back to the JWK's `adcp_use`
|
|
87
|
+
// metadata so keys minted via `pemToAdcpJwk` get the binding for free.
|
|
88
|
+
const jwkUse = options.privateKey.adcp_use;
|
|
89
|
+
this.adcpUse = options.adcpUse ?? (isAdcpUse(jwkUse) ? jwkUse : undefined);
|
|
81
90
|
// Mirrors the historical `privateKeyFingerprint` derivation — same input,
|
|
82
91
|
// same 64-bit cache disambiguator, so behavior carries over for callers
|
|
83
92
|
// who switch from the inline `request_signing` shape to a provider while
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../../src/lib/signing/testing.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../../../src/lib/signing/testing.ts"],"names":[],"mappings":"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"}
|
|
@@ -78,6 +78,16 @@ export type VerifyResult = ({
|
|
|
78
78
|
verified_at: number;
|
|
79
79
|
};
|
|
80
80
|
export declare const REQUEST_SIGNING_TAG = "adcp/request-signing/v1";
|
|
81
|
+
/**
|
|
82
|
+
* Tag value for the AdCP response-signing profile (RFC 9421 §2.2.9).
|
|
83
|
+
*
|
|
84
|
+
* Signer ships in #1823; verifier (`verifyResponseSignature`) ships in
|
|
85
|
+
* #1826. The wire format is now exercised both directions inside this SDK
|
|
86
|
+
* via round-trip tests. The `v1` suffix gives a clean break path if cross-
|
|
87
|
+
* SDK interop testing later surfaces an incompat — any breaking change
|
|
88
|
+
* ships as `v2` and verifiers reject `v1`.
|
|
89
|
+
*/
|
|
90
|
+
export declare const RESPONSE_SIGNING_TAG = "adcp/response-signing/v1";
|
|
81
91
|
export declare const ALLOWED_ALGS: Set<string>;
|
|
82
92
|
/**
|
|
83
93
|
* Wire-format algorithm identifier — the string that appears in
|
|
@@ -87,4 +97,30 @@ export type AdcpSignAlg = 'ed25519' | 'ecdsa-p256-sha256';
|
|
|
87
97
|
export declare const MAX_SIGNATURE_WINDOW_SECONDS = 300;
|
|
88
98
|
export declare const CLOCK_SKEW_TOLERANCE_SECONDS = 60;
|
|
89
99
|
export declare const MANDATORY_COMPONENTS: ReadonlyArray<string>;
|
|
100
|
+
/**
|
|
101
|
+
* Minimum derived components covered by a response signature under the AdCP
|
|
102
|
+
* response-signing profile (RFC 9421 §2.2.9).
|
|
103
|
+
*
|
|
104
|
+
* - `@status` — binds the signature to the response status code.
|
|
105
|
+
* - `@authority` — binds it to the request origin the response was emitted
|
|
106
|
+
* for (so a compromised origin can't cross-sign for a sibling tenant on
|
|
107
|
+
* the same fleet).
|
|
108
|
+
* - `@target-uri` — binds the signature to the specific request path + query,
|
|
109
|
+
* preventing a multi-tenant seller from emitting interchangeable signatures
|
|
110
|
+
* across endpoints sharing the same authority. Matches RFC 9421 §B.2.5
|
|
111
|
+
* examples for response signing.
|
|
112
|
+
*
|
|
113
|
+
* `content-type` + `content-digest` are added at signing time when the
|
|
114
|
+
* response carries a body — `content-digest` is opt-out via
|
|
115
|
+
* `coverContentDigest: false` because an unbound body is the most common
|
|
116
|
+
* cross-purpose footgun for response signing. Callers can extend the
|
|
117
|
+
* covered set further via `SignResponseOptions.additionalComponents`
|
|
118
|
+
* (e.g. `@method`, custom headers).
|
|
119
|
+
*
|
|
120
|
+
* Signer ships in #1823; verifier (`verifyResponseSignature`) ships in
|
|
121
|
+
* #1826. The wire format is now exercised both directions inside this SDK
|
|
122
|
+
* via round-trip tests. The `v1` tag suffix gives a clean break path if
|
|
123
|
+
* cross-SDK interop testing later surfaces an incompat.
|
|
124
|
+
*/
|
|
125
|
+
export declare const RESPONSE_MANDATORY_COMPONENTS: ReadonlyArray<string>;
|
|
90
126
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/signing/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEtE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,qBAAqB,EAAE,mBAAmB,CAAC;IAC3C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,CAAC,CAAC,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GAAG,cAAc,CAAC,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnH,eAAO,MAAM,mBAAmB,4BAA4B,CAAC;AAC7D,eAAO,MAAM,YAAY,aAA4C,CAAC;AACtE;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,mBAAmB,CAAC;AAC1D,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,MAAM,CAA4C,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/signing/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;AAEtE,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,OAAO,CAAC;IACnB,qBAAqB,EAAE,mBAAmB,CAAC;IAC3C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,+CAA+C;IAC/C,CAAC,CAAC,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC;IAAE,MAAM,EAAE,UAAU,CAAA;CAAE,GAAG,cAAc,CAAC,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnH,eAAO,MAAM,mBAAmB,4BAA4B,CAAC;AAC7D;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,6BAA6B,CAAC;AAC/D,eAAO,MAAM,YAAY,aAA4C,CAAC;AACtE;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,mBAAmB,CAAC;AAC1D,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,eAAO,MAAM,4BAA4B,KAAK,CAAC;AAC/C,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,MAAM,CAA4C,CAAC;AACpG;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,6BAA6B,EAAE,aAAa,CAAC,MAAM,CAA4C,CAAC"}
|
|
@@ -1,9 +1,45 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MANDATORY_COMPONENTS = exports.CLOCK_SKEW_TOLERANCE_SECONDS = exports.MAX_SIGNATURE_WINDOW_SECONDS = exports.ALLOWED_ALGS = exports.REQUEST_SIGNING_TAG = void 0;
|
|
3
|
+
exports.RESPONSE_MANDATORY_COMPONENTS = exports.MANDATORY_COMPONENTS = exports.CLOCK_SKEW_TOLERANCE_SECONDS = exports.MAX_SIGNATURE_WINDOW_SECONDS = exports.ALLOWED_ALGS = exports.RESPONSE_SIGNING_TAG = exports.REQUEST_SIGNING_TAG = void 0;
|
|
4
4
|
exports.REQUEST_SIGNING_TAG = 'adcp/request-signing/v1';
|
|
5
|
+
/**
|
|
6
|
+
* Tag value for the AdCP response-signing profile (RFC 9421 §2.2.9).
|
|
7
|
+
*
|
|
8
|
+
* Signer ships in #1823; verifier (`verifyResponseSignature`) ships in
|
|
9
|
+
* #1826. The wire format is now exercised both directions inside this SDK
|
|
10
|
+
* via round-trip tests. The `v1` suffix gives a clean break path if cross-
|
|
11
|
+
* SDK interop testing later surfaces an incompat — any breaking change
|
|
12
|
+
* ships as `v2` and verifiers reject `v1`.
|
|
13
|
+
*/
|
|
14
|
+
exports.RESPONSE_SIGNING_TAG = 'adcp/response-signing/v1';
|
|
5
15
|
exports.ALLOWED_ALGS = new Set(['ed25519', 'ecdsa-p256-sha256']);
|
|
6
16
|
exports.MAX_SIGNATURE_WINDOW_SECONDS = 300;
|
|
7
17
|
exports.CLOCK_SKEW_TOLERANCE_SECONDS = 60;
|
|
8
18
|
exports.MANDATORY_COMPONENTS = ['@method', '@target-uri', '@authority'];
|
|
19
|
+
/**
|
|
20
|
+
* Minimum derived components covered by a response signature under the AdCP
|
|
21
|
+
* response-signing profile (RFC 9421 §2.2.9).
|
|
22
|
+
*
|
|
23
|
+
* - `@status` — binds the signature to the response status code.
|
|
24
|
+
* - `@authority` — binds it to the request origin the response was emitted
|
|
25
|
+
* for (so a compromised origin can't cross-sign for a sibling tenant on
|
|
26
|
+
* the same fleet).
|
|
27
|
+
* - `@target-uri` — binds the signature to the specific request path + query,
|
|
28
|
+
* preventing a multi-tenant seller from emitting interchangeable signatures
|
|
29
|
+
* across endpoints sharing the same authority. Matches RFC 9421 §B.2.5
|
|
30
|
+
* examples for response signing.
|
|
31
|
+
*
|
|
32
|
+
* `content-type` + `content-digest` are added at signing time when the
|
|
33
|
+
* response carries a body — `content-digest` is opt-out via
|
|
34
|
+
* `coverContentDigest: false` because an unbound body is the most common
|
|
35
|
+
* cross-purpose footgun for response signing. Callers can extend the
|
|
36
|
+
* covered set further via `SignResponseOptions.additionalComponents`
|
|
37
|
+
* (e.g. `@method`, custom headers).
|
|
38
|
+
*
|
|
39
|
+
* Signer ships in #1823; verifier (`verifyResponseSignature`) ships in
|
|
40
|
+
* #1826. The wire format is now exercised both directions inside this SDK
|
|
41
|
+
* via round-trip tests. The `v1` tag suffix gives a clean break path if
|
|
42
|
+
* cross-SDK interop testing later surfaces an incompat.
|
|
43
|
+
*/
|
|
44
|
+
exports.RESPONSE_MANDATORY_COMPONENTS = ['@status', '@authority', '@target-uri'];
|
|
9
45
|
//# sourceMappingURL=types.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/signing/types.ts"],"names":[],"mappings":";;;AAgFa,QAAA,mBAAmB,GAAG,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/lib/signing/types.ts"],"names":[],"mappings":";;;AAgFa,QAAA,mBAAmB,GAAG,yBAAyB,CAAC;AAC7D;;;;;;;;GAQG;AACU,QAAA,oBAAoB,GAAG,0BAA0B,CAAC;AAClD,QAAA,YAAY,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAC;AAMzD,QAAA,4BAA4B,GAAG,GAAG,CAAC;AACnC,QAAA,4BAA4B,GAAG,EAAE,CAAC;AAClC,QAAA,oBAAoB,GAA0B,CAAC,SAAS,EAAE,aAAa,EAAE,YAAY,CAAC,CAAC;AACpG;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACU,QAAA,6BAA6B,GAA0B,CAAC,SAAS,EAAE,YAAY,EAAE,aAAa,CAAC,CAAC"}
|