@adcp/sdk 16.0.0-beta.1 → 16.0.0-beta.3
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 +54 -0
- package/dist/lib/core/ConversationTypes.d.mts +8 -3
- package/dist/lib/core/ConversationTypes.d.ts +8 -3
- package/dist/lib/core/SingleAgentClient.d.mts +15 -4
- package/dist/lib/core/SingleAgentClient.d.ts +15 -4
- package/dist/lib/core/SingleAgentClient.js +29 -8
- package/dist/lib/core/SingleAgentClient.mjs +29 -8
- package/dist/lib/core/TaskExecutor.js +5 -1
- package/dist/lib/core/TaskExecutor.mjs +5 -1
- package/dist/lib/errors/index.d.mts +9 -4
- package/dist/lib/errors/index.d.ts +9 -4
- package/dist/lib/identity-3.3/generated-compat.d.mts +34 -0
- package/dist/lib/identity-3.3/generated-compat.d.ts +34 -0
- package/dist/lib/identity-3.3/generated-compat.js +16 -0
- package/dist/lib/identity-3.3/generated-compat.mjs +0 -0
- package/dist/lib/identity-3.3/index.d.mts +2 -2
- package/dist/lib/identity-3.3/index.d.ts +2 -2
- package/dist/lib/identity-3.3/index.js +4 -0
- package/dist/lib/identity-3.3/index.mjs +5 -1
- package/dist/lib/identity-3.3/lifecycle.d.mts +17 -5
- package/dist/lib/identity-3.3/lifecycle.d.ts +17 -5
- package/dist/lib/identity-3.3/lifecycle.js +32 -5
- package/dist/lib/identity-3.3/lifecycle.mjs +38 -6
- package/dist/lib/identity-3.3/revocation.d.mts +39 -3
- package/dist/lib/identity-3.3/revocation.d.ts +39 -3
- package/dist/lib/identity-3.3/revocation.js +88 -18
- package/dist/lib/identity-3.3/revocation.mjs +89 -19
- package/dist/lib/identity-3.3/server.d.mts +12 -0
- package/dist/lib/identity-3.3/server.d.ts +12 -0
- package/dist/lib/identity-3.3/server.js +103 -43
- package/dist/lib/identity-3.3/server.mjs +111 -45
- package/dist/lib/identity-3.3/trust.d.mts +62 -1
- package/dist/lib/identity-3.3/trust.d.ts +62 -1
- package/dist/lib/identity-3.3/trust.js +126 -21
- package/dist/lib/identity-3.3/trust.mjs +124 -21
- package/dist/lib/identity-3.3/types.d.mts +39 -11
- package/dist/lib/identity-3.3/types.d.ts +39 -11
- package/dist/lib/index.d.mts +3 -3
- package/dist/lib/index.d.ts +3 -3
- package/dist/lib/index.js +8 -0
- package/dist/lib/index.mjs +9 -1
- package/dist/lib/negotiation/types.d.mts +20 -39
- package/dist/lib/negotiation/types.d.ts +20 -39
- package/dist/lib/protocols/index.d.mts +61 -25
- package/dist/lib/protocols/index.d.ts +61 -25
- package/dist/lib/protocols/index.js +11 -6
- package/dist/lib/protocols/index.mjs +5 -2
- package/dist/lib/protocols/mcp-modern.js +1 -0
- package/dist/lib/protocols/mcp-modern.mjs +2 -1
- package/dist/lib/protocols/mcp.js +1 -0
- package/dist/lib/protocols/mcp.mjs +2 -1
- package/dist/lib/protocols/responseSizeLimit.d.mts +91 -5
- package/dist/lib/protocols/responseSizeLimit.d.ts +91 -5
- package/dist/lib/protocols/responseSizeLimit.js +195 -31
- package/dist/lib/protocols/responseSizeLimit.mjs +192 -31
- package/dist/lib/reporting/bigquery/index.js +8 -0
- package/dist/lib/reporting/bigquery/index.mjs +8 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/auth-signature.d.mts +6 -1
- package/dist/lib/server/auth-signature.d.ts +6 -1
- package/dist/lib/server/auth-signature.js +24 -13
- package/dist/lib/server/auth-signature.mjs +29 -13
- package/dist/lib/server/auth.d.mts +2 -2
- package/dist/lib/server/auth.d.ts +2 -2
- package/dist/lib/server/create-adcp-server.js +31 -10
- package/dist/lib/server/create-adcp-server.mjs +37 -11
- package/dist/lib/signing/crypto.d.mts +15 -0
- package/dist/lib/signing/crypto.d.ts +15 -0
- package/dist/lib/signing/crypto.js +83 -3
- package/dist/lib/signing/crypto.mjs +86 -3
- package/dist/lib/signing/fetch-async.js +1 -1
- package/dist/lib/signing/fetch-async.mjs +1 -1
- package/dist/lib/signing/fetch.js +1 -1
- package/dist/lib/signing/fetch.mjs +1 -1
- package/dist/lib/signing/middleware.js +9 -0
- package/dist/lib/signing/middleware.mjs +14 -0
- package/dist/lib/signing/parser.d.mts +8 -5
- package/dist/lib/signing/parser.d.ts +8 -5
- package/dist/lib/signing/parser.js +77 -61
- package/dist/lib/signing/parser.mjs +77 -61
- package/dist/lib/signing/revocation.js +3 -0
- package/dist/lib/signing/revocation.mjs +3 -0
- package/dist/lib/signing/server.d.mts +1 -1
- package/dist/lib/signing/server.d.ts +1 -1
- package/dist/lib/signing/server.js +2 -0
- package/dist/lib/signing/server.mjs +2 -1
- package/dist/lib/signing/signer.js +2 -8
- package/dist/lib/signing/signer.mjs +3 -9
- package/dist/lib/signing/testing.js +2 -6
- package/dist/lib/signing/testing.mjs +3 -7
- package/dist/lib/signing/verifier.js +3 -3
- package/dist/lib/signing/verifier.mjs +4 -4
- package/dist/lib/signing/web-bot-auth.d.mts +84 -10
- package/dist/lib/signing/web-bot-auth.d.ts +84 -10
- package/dist/lib/signing/web-bot-auth.js +278 -88
- package/dist/lib/signing/web-bot-auth.mjs +279 -94
- package/dist/lib/signing/webhook-verifier.js +3 -3
- package/dist/lib/signing/webhook-verifier.mjs +4 -4
- package/dist/lib/substitution/compile.js +2 -1
- package/dist/lib/substitution/compile.mjs +2 -1
- package/dist/lib/substitution/consent-macros.d.mts +4 -0
- package/dist/lib/substitution/consent-macros.d.ts +4 -0
- package/dist/lib/substitution/consent-macros.js +45 -0
- package/dist/lib/substitution/consent-macros.mjs +20 -0
- package/dist/lib/substitution/index.d.mts +1 -1
- package/dist/lib/substitution/index.d.ts +1 -1
- package/dist/lib/substitution/index.js +2 -0
- package/dist/lib/substitution/index.mjs +2 -1
- package/dist/lib/substitution/translate.d.mts +15 -2
- package/dist/lib/substitution/translate.d.ts +15 -2
- package/dist/lib/substitution/translate.js +148 -26
- package/dist/lib/substitution/translate.mjs +147 -26
- package/dist/lib/testing/client.js +2 -1
- package/dist/lib/testing/client.mjs +2 -1
- package/dist/lib/testing/scenarios/capabilities.js +1 -1
- package/dist/lib/testing/scenarios/capabilities.mjs +1 -1
- package/dist/lib/testing/storyboard/request-signing/builder.js +2 -5
- package/dist/lib/testing/storyboard/request-signing/builder.mjs +3 -6
- package/dist/lib/testing/storyboard/signer-grader/grader.js +2 -7
- package/dist/lib/testing/storyboard/signer-grader/grader.mjs +2 -7
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/enums.generated.d.mts +3 -0
- package/dist/lib/types/enums.generated.d.ts +3 -0
- package/dist/lib/types/enums.generated.js +9 -0
- package/dist/lib/types/enums.generated.mjs +6 -0
- package/dist/lib/v2/projection/catalog-snapshot.js +3 -1
- package/dist/lib/v2/projection/catalog-snapshot.mjs +3 -1
- package/dist/lib/v2/projection/creative-delivery.d.mts +31 -9
- package/dist/lib/v2/projection/creative-delivery.d.ts +31 -9
- package/dist/lib/v2/projection/index.d.mts +1 -1
- package/dist/lib/v2/projection/index.d.ts +1 -1
- package/dist/lib/v2/projection/index.js +2 -0
- package/dist/lib/v2/projection/index.mjs +2 -0
- package/dist/lib/v2/projection/legacy-routes.d.mts +10 -0
- package/dist/lib/v2/projection/legacy-routes.d.ts +10 -0
- package/dist/lib/v2/projection/legacy-routes.js +7 -0
- package/dist/lib/v2/projection/legacy-routes.mjs +6 -0
- package/dist/lib/validation/schema-loader.js +25 -0
- package/dist/lib/validation/schema-loader.mjs +24 -0
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +7 -2
- package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +3 -2
- package/docs/guides/REPORTING-LEDGER.md +15 -5
- package/docs/guides/REPORTING-OPERATIONS.md +17 -11
- package/docs/guides/UNIVERSAL-MACRO-COMPILATION.md +38 -0
- package/docs/guides/VALIDATE-YOUR-AGENT.md +12 -0
- package/docs/llms.txt +2 -2
- package/docs/migration-12-to-13.md +8 -0
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-agent-identity-3.3.md +150 -11
- package/package.json +4 -1
|
@@ -407,6 +407,14 @@ projected.format_options, { sellerProduct: storedProduct })`. An option is then
|
|
|
407
407
|
seller-declared exactly when the stored product's own `format_options[]` names
|
|
408
408
|
it, which is the rule the SDK applies after its own discovery.
|
|
409
409
|
|
|
410
|
+
The client reads that origin from the resolver function that
|
|
411
|
+
`canonicalFormatLegacyResolverFromRoutes()` returns. A resolver you build around
|
|
412
|
+
it, for example one that tries the stored routes and then another source, is a
|
|
413
|
+
different function and carries no origin unless you pass it through
|
|
414
|
+
`carryFormatOptionOrigins(composedResolver, routesResolver)`.
|
|
415
|
+
`canonicalFormatLegacyResolverFromCatalogSnapshots(snapshots, fallback)` already
|
|
416
|
+
carries its fallback's origin.
|
|
417
|
+
|
|
410
418
|
Compatibility consumers that must retain top-level `format_ids[]` while
|
|
411
419
|
publishing URL-free canonical declarations can use the additive projection:
|
|
412
420
|
|
|
@@ -11,8 +11,8 @@ below as the publication/deployment gate.
|
|
|
11
11
|
|
|
12
12
|
| Fact | Value |
|
|
13
13
|
| --- | --- |
|
|
14
|
-
| Exact npm package | `@adcp/sdk@16.0.0-beta.
|
|
15
|
-
| npm integrity | registry-derived after publication; run `npm view @adcp/sdk@16.0.0-beta.
|
|
14
|
+
| Exact npm package | `@adcp/sdk@16.0.0-beta.3` |
|
|
15
|
+
| npm integrity | registry-derived after publication; run `npm view @adcp/sdk@16.0.0-beta.3 dist.integrity` |
|
|
16
16
|
| Node.js runtime | `^20.19.0 || >=22.12.0` |
|
|
17
17
|
| Default AdCP wire release | `3.2.4` |
|
|
18
18
|
| Maintained wire releases | `v2.5`, `v2.6`, `v3`, `3.0.0`, `3.0`, `3.0.1`, `3.0.2`, `3.0.3`, `3.0.4`, `3.0.5`, `3.0.6`, `3.0.7`, `3.0.8`, `3.0.9`, `3.0.10`, `3.0.11`, `3.0.12`, `3.0.13`, `3.0.14`, `3.0.15`, `3.0.16`, `3.0.17`, `3.0.18`, `3.0.19`, `3.0.20`, `3.0.21`, `3.0.22`, `3.0.23`, `3.0.24`, `3.0.25`, `3.1.0`, `3.1`, `3.1.1`, `3.1.2`, `3.1.3`, `3.1.4`, `3.1.5`, `3.1.6`, `3.1.7`, `3.1.8`, `3.1.9`, `3.1.10`, `3.1.11`, `3.1.12`, `3.1.13`, `3.1.14`, `3.1.15`, `3.1.16`, `3.1.17`, `3.1.18`, `3.1.19`, `3.1.20`, `3.1.21`, `3.1.22`, `3.1.23`, `3.1.24`, `3.2.1`, `3.2`, `3.2.2`, `3.2.3`, `3.2.4` |
|
|
@@ -21,8 +21,8 @@ below as the publication/deployment gate.
|
|
|
21
21
|
Install exact production inputs rather than a moving range or dist-tag:
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
npm install --save-exact '@adcp/sdk@16.0.0-beta.
|
|
25
|
-
npm view '@adcp/sdk@16.0.0-beta.
|
|
24
|
+
npm install --save-exact '@adcp/sdk@16.0.0-beta.3'
|
|
25
|
+
npm view '@adcp/sdk@16.0.0-beta.3' dist.integrity
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
### Required and optional peers
|
|
@@ -113,7 +113,7 @@ const client = new SingleAgentClient({
|
|
|
113
113
|
experimentalIdentity33: true,
|
|
114
114
|
webhookSigningProfile: 'web-bot-auth',
|
|
115
115
|
webhookVerification: {
|
|
116
|
-
webBotAuth: { directory,
|
|
116
|
+
webBotAuth: { directory, revocation: revocations },
|
|
117
117
|
},
|
|
118
118
|
});
|
|
119
119
|
```
|
|
@@ -149,8 +149,22 @@ to sign a list of revoked key thumbprints and optional reasons/dates.
|
|
|
149
149
|
`createSignedOriginRevocationList` provides the same authoring API. The SDK
|
|
150
150
|
supports Ed25519 and P-256 identity keys. Observed key revocations are permanent;
|
|
151
151
|
refresh failures use the last verified list only within the published grace
|
|
152
|
-
window.
|
|
153
|
-
|
|
152
|
+
window. Staleness follows the list's signed `next_update`, never the polling
|
|
153
|
+
interval: the verifier re-polls at least every polling interval (at most 30
|
|
154
|
+
minutes) and fails closed only after `next_update` plus four polling
|
|
155
|
+
intervals. Publishers MUST NOT declare `next_update` more than 30 minutes ahead
|
|
156
|
+
(the authoring helper refuses it), but a verifier tolerates a longer cadence
|
|
157
|
+
from other implementations: each successful fetch of such a list stays valid
|
|
158
|
+
for at most 30 minutes plus grace, so an outage cannot extend acceptance past
|
|
159
|
+
that. A list whose `updated` is more than 60 seconds ahead of the verifier
|
|
160
|
+
clock, or whose `next_update` has passed, is refused. `OriginRevocationResolver.status()` reports `revoked`, `current`
|
|
161
|
+
(including within grace), `absent` (the origin answers 404/410: the identity is
|
|
162
|
+
established but cannot be bound for spend) or `unknown` (no verifiable list and
|
|
163
|
+
grace has passed: the identity is not established, so the request is handled as
|
|
164
|
+
unverified). History-store failures throw `revocation_persistence_failed`, an
|
|
165
|
+
infrastructure outage handled by the application layer. `isRevoked()` remains as
|
|
166
|
+
a compatibility wrapper that throws `revocation_unavailable` for `absent` and
|
|
167
|
+
`unknown`.
|
|
154
168
|
|
|
155
169
|
For positively negotiated 3.3 sellers advertising signed webhooks, experimental
|
|
156
170
|
clients omit injected reporting/task webhook HMAC authentication even when a
|
|
@@ -220,8 +234,8 @@ const server = createAdcpServerFromPlatform(platform, {
|
|
|
220
234
|
assertLegacyOriginAllowed: url => lifecycle.assertLegacyAllowed(url),
|
|
221
235
|
webBotAuth: {
|
|
222
236
|
directory,
|
|
223
|
-
|
|
224
|
-
resolvePrincipal: createIdentity33PrincipalResolver({ lifecycle }),
|
|
237
|
+
// Revocation and binding run after verification, in the identity layer.
|
|
238
|
+
resolvePrincipal: createIdentity33PrincipalResolver({ lifecycle, revocation: revocations }),
|
|
225
239
|
},
|
|
226
240
|
},
|
|
227
241
|
});
|
|
@@ -268,17 +282,58 @@ redirects, 2 MiB, depth 32, and no duplicate JSON keys. Exactly one canonical
|
|
|
268
282
|
origin must carry the required role. Cache lifetime is the configured revocation
|
|
269
283
|
poll interval (60–1800 seconds), negatives at most 60 seconds. Failures are not
|
|
270
284
|
absence. Share authoritative-history state when retaining legacy fallback.
|
|
285
|
+
Fetches to an operator's own hosts are rate-limited per (operator, host);
|
|
286
|
+
`authoritative_location` hops to hosts outside the operator's registrable domain
|
|
287
|
+
share one separate per-host budget. A hop therefore never spends the target
|
|
288
|
+
operator's own budget, and many operators cannot multiply fetches to one host.
|
|
289
|
+
A host-rate refusal is a retryable outage that is not cached as the operator's
|
|
290
|
+
failure.
|
|
291
|
+
|
|
292
|
+
A record that cannot be read (transport error, outage, rate, invalid content)
|
|
293
|
+
raises `TrustRecordUnavailableError`; a current record that does not list the
|
|
294
|
+
origin with the required role raises `TrustMembershipError`. Both extend
|
|
295
|
+
`IdentityAuthorizationError`. For a bound origin:
|
|
296
|
+
|
|
297
|
+
- **Delisted:** the last record read does not list the origin with the role
|
|
298
|
+
(operators retire agents by publishing an empty `agents[]`). The origin is
|
|
299
|
+
identity-established for every request, task polling and cancellation
|
|
300
|
+
included: the principal resolver demotes it to the per-origin anonymous
|
|
301
|
+
scope with no credential and no registry-resolved `ctx.agent`, and it gets
|
|
302
|
+
the anonymous tool policy plus `get_principal` (which reports
|
|
303
|
+
`unconfigured`). The binding is kept: `open` onboarding cannot re-bind it and
|
|
304
|
+
RFC 9421 stays refused for the origin. Spend gets `PERMISSION_DENIED` with no
|
|
305
|
+
details. A known delisting stays a delisting through a later failed refresh.
|
|
306
|
+
- **Unreachable:** a record that cannot be read, including a 404/410 after a
|
|
307
|
+
record was read (or for any bound origin, on every replica), is a discovery
|
|
308
|
+
failure, never a removal; the last record read stays authoritative.
|
|
309
|
+
Spend-committing calls get a retryable `SERVICE_UNAVAILABLE`. As seller
|
|
310
|
+
policy, reads and identity configuration continue under the binding while
|
|
311
|
+
the last record read listed the origin and is within
|
|
312
|
+
`TrustEvaluator({ maxOutageContinuationSeconds })` (default four polling
|
|
313
|
+
intervals) of its freshness; after that nothing is served (`503`).
|
|
314
|
+
|
|
315
|
+
After every signature verifies, authorization outcomes use the standard AdCP
|
|
316
|
+
error envelope, never a 403 with `Accept-Signature`. That includes a principal
|
|
317
|
+
resolver that throws: a transient (or uncoded) error is an outage answered
|
|
318
|
+
`503 SERVICE_UNAVAILABLE` by the server, and any other coded error is
|
|
319
|
+
`PERMISSION_DENIED`, delivered on the tool call (other requests are refused with
|
|
320
|
+
that envelope and no challenge).
|
|
271
321
|
|
|
272
322
|
Demand grants come from the verified brand or house record. Implicit authority
|
|
273
323
|
requires brand, account operator, and signer operator to share a registrable
|
|
274
324
|
domain. Otherwise only a direct grant with the account operator equal to the
|
|
275
|
-
signer,
|
|
325
|
+
signer, a direct grant from a self-operated brand (the brand is its own account
|
|
326
|
+
operator) to the signer's operator, or a two-link chain through the account
|
|
327
|
+
operator, is accepted. The
|
|
276
328
|
intersection must cover the actual brand IDs, countries, scope, signer-origin
|
|
277
329
|
narrowing and temporal window. A restrictive published grant cannot be
|
|
278
330
|
superseded by seller fallback. A trust 200 disables brand.json authority;
|
|
279
331
|
authoritative absence alone permits explicit legacy policy. An established
|
|
280
332
|
identity lacking a grant gets `PERMISSION_DENIED` with
|
|
281
333
|
`{ scope: 'agent', reason: 'grant_absent' }`. No account or live buy is changed.
|
|
334
|
+
A grantor that once served trust.json and is now unreachable (404/410
|
|
335
|
+
included) never falls back to brand.json `authorized_operators[]`, and it is
|
|
336
|
+
not a grant removal: spend gets a retryable `SERVICE_UNAVAILABLE`.
|
|
282
337
|
|
|
283
338
|
Origin key revocations use `/.well-known/governance-revocations.json`, signed
|
|
284
339
|
with `typ: adcp-gov-revocation+jws`, as ratified R3 specifies. This origin key
|
|
@@ -291,9 +346,10 @@ Permanent revocation storage reserves separate bounded capacity for audited boun
|
|
|
291
346
|
origins and anonymous/self-service origins, so first-contact traffic cannot exhaust the bound
|
|
292
347
|
pool. Storage failures deny reads and mutations without outage grace; inspect the
|
|
293
348
|
non-enumerable error cause and raise `createIdentity33StateStores.revocationLimits`
|
|
294
|
-
when capacity is exhausted. Existing facts must remain stored.
|
|
295
|
-
|
|
296
|
-
|
|
349
|
+
when capacity is exhausted. Existing facts must remain stored. When the shared
|
|
350
|
+
refresh limiter is full (attacker-selected origins can occupy it), an origin
|
|
351
|
+
whose last verified list is still inside `next_update` plus grace keeps that
|
|
352
|
+
status, exactly as if its own fetch had failed; past grace it fails closed.
|
|
297
353
|
|
|
298
354
|
## Authoring and pinned sources
|
|
299
355
|
|
|
@@ -324,12 +380,55 @@ released schemas:
|
|
|
324
380
|
|
|
325
381
|
Ratified R2 defaults replay to 429. Older vector negative/002 expects 403;
|
|
326
382
|
`replayStatus: 403` is an explicit compatibility test option, not the default.
|
|
383
|
+
|
|
384
|
+
Verifier outcomes follow DR-0023 and WBA §5.5/§6.10. `verifyWebBotAuth` needs
|
|
385
|
+
only key discovery and a replay store and returns the verified origins;
|
|
386
|
+
revocation, bindings and the origin-binding fence run afterwards in the
|
|
387
|
+
identity layer (`createIdentity33PrincipalResolver({ lifecycle, revocation })`),
|
|
388
|
+
so verification can run in a CDN or middleware in front of the AdCP server.
|
|
389
|
+
|
|
390
|
+
- Signature-path errors are WBA statuses and headers only: 400 for a field that
|
|
391
|
+
does not parse, 403 with `Accept-Signature` for a signature that does not
|
|
392
|
+
verify, 429 for a replayed nonce. Any AdCP body is the generic authentication
|
|
393
|
+
error (`AUTH_INVALID`); the specific reason is logged, never sent.
|
|
394
|
+
- A key-directory fetch failure (transport error or any non-200, 404/410/5xx
|
|
395
|
+
included) is a discovery failure. It never evicts a cached, unexpired
|
|
396
|
+
directory, which keeps verifying. Without one the request is unverified and
|
|
397
|
+
answered 403 with `Accept-Signature` (the SDK's default unverified-request
|
|
398
|
+
policy). A fetched directory without the key is a signature failure.
|
|
399
|
+
- Plain JWKS directories without Appendix B signatures are accepted, with every
|
|
400
|
+
key checked against its RFC 7638 thumbprint; pass
|
|
401
|
+
`requireSignedDirectories: true` to the resolver to refuse them. An unsigned
|
|
402
|
+
directory keeps verifying through failed refreshes for at most
|
|
403
|
+
`maxUnsignedDirectoryAgeSeconds` (default one day).
|
|
404
|
+
- A revoked key is 403 with the generic authentication error and no
|
|
405
|
+
`Accept-Signature`: the signer must stop using that key. Revocation status
|
|
406
|
+
`unknown` (stale past grace) leaves the identity unverified (403 with
|
|
407
|
+
`Accept-Signature`). An origin that serves no revocation list (`absent`) is
|
|
408
|
+
identity-established and cannot be bound for spend.
|
|
409
|
+
- Replay-store and revocation-history-store failures are infrastructure
|
|
410
|
+
outages, raised as `WebBotAuthUnavailableError`. The server integrations
|
|
411
|
+
answer them at the application layer with 503 `SERVICE_UNAVAILABLE` and
|
|
412
|
+
`Retry-After`, never as a signature outcome.
|
|
413
|
+
- `webBotAuth.isRevoked`, `requireFreshRevocation` and `deferAuthorizationErrors`
|
|
414
|
+
are deprecated. A server needs either a revocation-aware principal resolver or
|
|
415
|
+
the deprecated `isRevoked`, and the webhook receiver either `revocation` or
|
|
416
|
+
`isRevoked`. The deprecated path cannot express "established but not
|
|
417
|
+
bindable", so it refuses an origin that serves no list (unverified).
|
|
418
|
+
- Clients act on the HTTP status and `Accept-Signature`, not the generic body:
|
|
419
|
+
re-sign on 403 with `Accept-Signature`, stop using the key on 403 without it,
|
|
420
|
+
back off on 429 or 503.
|
|
421
|
+
- `@target-uri` and `@authority` are taken from the target URI as received
|
|
422
|
+
(RFC 9421 §2.2.2), never canonicalized; canonical origins identify the signer
|
|
423
|
+
only. Default nonces are 64 bytes (draft §4.2). Ed25519, ECDSA P-256 and
|
|
424
|
+
RSA-PSS-SHA512 keys are supported. `test/fixtures/wba-interop/` holds fixtures
|
|
425
|
+
verified in both directions against Cloudflare's `web-bot-auth`.
|
|
327
426
|
Older #7894 governance vectors propose a superseded migration and are retained
|
|
328
427
|
with their non-applicability recorded in `test/fixtures/wba-profile/PINNED.json`.
|
|
329
428
|
The buyer default onboarding field is `profiles.adcp.onboarding`, matching the
|
|
330
429
|
schema; the design's `record_profiles` wording names the schema definition.
|
|
331
430
|
|
|
332
|
-
|
|
431
|
+
Process-local authority history is bounded and never evicts remembered operators. Public deployments must supply `authorityHistory` from the shared state stores so history survives restarts and cache eviction. See [Public deployment limits](#public-deployment-limits) for admission and legacy-fallback behavior.
|
|
333
432
|
|
|
334
433
|
Open `sync_principal` commits the newly approved origin binding before the caller notification-configuration handler runs. A later configuration failure does not undo that binding; retry applies configuration to the same principal. This allocation never grants spend authority: every mutating request still passes tier, relationship and grant checks before provisioning or idempotency.
|
|
335
434
|
|
|
@@ -350,6 +449,46 @@ The standard principal resolver automatically fences RFC signatures for already-
|
|
|
350
449
|
|
|
351
450
|
Signing capabilities include the experimental `wba_draft_revision` field next to `profiles`, identifying `draft-ietf-webbotauth-httpsig-protocol-00` as required by ratified R2. Reporting and artifact callback choices are persisted by destination before dispatch, including update calls; their receivers pass the trusted request URL and `taskType` (`media_buy_delivery` or `artifact_delivery`) to `verifyAndParseWebhook`. These deliveries preserve the original payload in `result` after authentication and schema validation; `envelope` adds SDK routing/status metadata. PostgreSQL migrations also add optional `delivery_kind`.
|
|
352
451
|
|
|
353
|
-
Revocation stores allocate no permanent row for an empty list. Each audited/unbound pool reserves a tenant-wide CAS budget (10,000 origins and 100,000 keys; each operator is limited to 256 origins and 16,384 keys per pool). Audited bindings promote existing facts without deleting them; self-service `openAccess` bindings stay in the unbound pool. Failed writes may conservatively reserve capacity; facts are never evicted to regain it. Store/quota failures return `SERVICE_UNAVAILABLE` for every operation. In-memory revocation storage is for development/tests; production sellers use shared persistent stores.
|
|
452
|
+
Revocation stores allocate no permanent row for an empty list. Each audited/unbound pool reserves a tenant-wide CAS budget (10,000 origins and 100,000 keys; each operator is limited to 256 origins and 16,384 keys per pool). Audited bindings promote existing facts without deleting them; self-service `openAccess` bindings stay in the unbound pool. Failed writes may conservatively reserve capacity; facts are never evicted to regain it. Store/quota failures return `SERVICE_UNAVAILABLE` for every operation. In-memory revocation storage is for development/tests and is bounded per origin, per operator (registrable domain, default 16,384 keys) and in total, so wildcard subdomains of one operator cannot fill it alone (several operators still can, and a refused merge fails closed); production sellers use shared persistent stores.
|
|
354
453
|
|
|
355
454
|
Unbound callers use an internal per-origin anonymous scope to isolate task/proposal state; this is not a durable principal and is never returned by `get_principal`. Only the explicit anonymous tool policy is allowed.
|
|
455
|
+
|
|
456
|
+
### Public deployment limits
|
|
457
|
+
|
|
458
|
+
- **Durable authority history is required for public deployments.** Without
|
|
459
|
+
`authorityHistory`, the trust evaluator remembers which operators have served
|
|
460
|
+
a trust record only in process memory. Nothing is evicted, so no operator's
|
|
461
|
+
legacy `authorized_operators[]` fallback changes because of others, but the
|
|
462
|
+
memory is bounded: `maxEntries` (default 1,000) in total, at most half of
|
|
463
|
+
that (`maxPrivateAuthoritativeOperators`) for PSL PRIVATE-section names, and
|
|
464
|
+
`maxAuthoritativeOperatorsPerPrivateSuffix` (default 32) per hosting provider
|
|
465
|
+
(the provider's ICANN registrable domain, so every `*.vercel.app`,
|
|
466
|
+
`*.s3.<region>.amazonaws.com` or `*.<project>.platformsh.site` operator
|
|
467
|
+
shares one budget). An operator over budget cannot have its trust record
|
|
468
|
+
accepted in that process: 32 subdomains under one provider block later operators on that
|
|
469
|
+
provider, and a full `maxEntries` refuses every new trust record publisher.
|
|
470
|
+
When an operator fits its budget, a history slot is reserved on any 200,
|
|
471
|
+
before the body is validated, so a removed or invalid record still prevents
|
|
472
|
+
a legacy downgrade for that remembered operator. An operator refused for
|
|
473
|
+
lack of budget is not remembered: its trust record remains unavailable,
|
|
474
|
+
but a later 404/410 is treated as absence and may invoke explicit legacy
|
|
475
|
+
authorization, as after a process restart. With durable `authorityHistory`,
|
|
476
|
+
every 200 is recorded, the in-memory set is only a cache, and none of these
|
|
477
|
+
admission limits refuse records.
|
|
478
|
+
- **The unbound revocation pool can fill.** With the default CAS limits
|
|
479
|
+
(100,000 keys per pool, 16,384 per operator), about seven registrable domains,
|
|
480
|
+
including free PSL PRIVATE-section names, can exhaust the unbound pool. New
|
|
481
|
+
unbound origins with revoked keys then fail closed with `SERVICE_UNAVAILABLE`
|
|
482
|
+
until capacity is raised; the bound pool is unaffected.
|
|
483
|
+
- **Delisted origins have no exception.** A bound origin whose operator
|
|
484
|
+
delists it is identity-established for every request, including polling and
|
|
485
|
+
cancelling tasks it created while it was listed.
|
|
486
|
+
- **Duplicate structured-field keys are rejected.** Signature-Input,
|
|
487
|
+
Signature and Signature-Agent with a duplicated dictionary member or a
|
|
488
|
+
duplicated parameter (for example `created=1;created=2`) are malformed: 400
|
|
489
|
+
under Web Bot Auth, `request_signature_header_malformed` under RFC 9421. RFC
|
|
490
|
+
8941 parsers keep the last value, which other implementations may not.
|
|
491
|
+
- **`createExpressVerifier` does not implement Web Bot Auth.** It answers a
|
|
492
|
+
request carrying `Signature-Agent` or the `web-bot-auth` tag with 403 (no
|
|
493
|
+
challenge) instead of verifying it under RFC 9421. Use `createAdcpServer`
|
|
494
|
+
`signedRequests.webBotAuth` or `verifySignatureAsAuthenticator({ webBotAuth })`.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adcp/sdk",
|
|
3
|
-
"version": "16.0.0-beta.
|
|
3
|
+
"version": "16.0.0-beta.3",
|
|
4
4
|
"description": "AdCP SDK — client, server, and compliance harnesses for the AdContext Protocol (MCP + A2A)",
|
|
5
5
|
"workspaces": [
|
|
6
6
|
".",
|
|
@@ -859,6 +859,7 @@
|
|
|
859
859
|
"esbuild": "^0.28.2",
|
|
860
860
|
"esbuild-fix-imports-plugin": "^1.0.23",
|
|
861
861
|
"eslint": "^10.9.1",
|
|
862
|
+
"http-message-sig": "0.3.0",
|
|
862
863
|
"json-schema-to-typescript": "^15.0.4",
|
|
863
864
|
"json-schema-to-zod": "^2.8.1",
|
|
864
865
|
"openapi-typescript": "^7.13.0",
|
|
@@ -873,6 +874,8 @@
|
|
|
873
874
|
"typedoc-plugin-markdown": "^4.13.0",
|
|
874
875
|
"typescript": "^5.9.3",
|
|
875
876
|
"typescript-eslint": "^8.68.0",
|
|
877
|
+
"web-bot-auth": "0.2.0",
|
|
878
|
+
"workerd": "1.20260730.1",
|
|
876
879
|
"zod": "^4.4.3",
|
|
877
880
|
"zod-openapi": "^5.4.3"
|
|
878
881
|
},
|