@adcp/sdk 14.0.0 → 14.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/dist/lib/adapters/implicit-account-store.d.mts +12 -7
  2. package/dist/lib/adapters/implicit-account-store.d.ts +12 -7
  3. package/dist/lib/adapters/implicit-account-store.js +69 -15
  4. package/dist/lib/adapters/implicit-account-store.mjs +69 -15
  5. package/dist/lib/core/AgentClient.d.mts +1 -0
  6. package/dist/lib/core/AgentClient.d.ts +1 -0
  7. package/dist/lib/core/AgentClient.js +3 -0
  8. package/dist/lib/core/AgentClient.mjs +3 -0
  9. package/dist/lib/core/SingleAgentClient.d.mts +31 -1
  10. package/dist/lib/core/SingleAgentClient.d.ts +31 -1
  11. package/dist/lib/core/SingleAgentClient.js +355 -35
  12. package/dist/lib/core/SingleAgentClient.mjs +365 -37
  13. package/dist/lib/core/TaskExecutor.js +2 -1
  14. package/dist/lib/core/TaskExecutor.mjs +2 -1
  15. package/dist/lib/core/account-key.d.mts +3 -0
  16. package/dist/lib/core/account-key.d.ts +3 -0
  17. package/dist/lib/core/account-key.js +41 -0
  18. package/dist/lib/core/account-key.mjs +17 -0
  19. package/dist/lib/core/account-resolution.d.mts +2 -0
  20. package/dist/lib/core/account-resolution.d.ts +2 -0
  21. package/dist/lib/core/buyer-account-registry.d.mts +65 -0
  22. package/dist/lib/core/buyer-account-registry.d.ts +65 -0
  23. package/dist/lib/core/buyer-account-registry.js +518 -0
  24. package/dist/lib/core/buyer-account-registry.mjs +494 -0
  25. package/dist/lib/core/product-cache.d.mts +18 -0
  26. package/dist/lib/core/product-cache.d.ts +18 -0
  27. package/dist/lib/core/product-cache.js +137 -0
  28. package/dist/lib/core/product-cache.mjs +112 -0
  29. package/dist/lib/errors/index.d.mts +40 -1
  30. package/dist/lib/errors/index.d.ts +40 -1
  31. package/dist/lib/errors/index.js +69 -3
  32. package/dist/lib/errors/index.mjs +64 -3
  33. package/dist/lib/governance/authorization.d.mts +17 -1
  34. package/dist/lib/governance/authorization.d.ts +17 -1
  35. package/dist/lib/governance/authorization.js +55 -7
  36. package/dist/lib/governance/authorization.mjs +59 -7
  37. package/dist/lib/governance/index.d.mts +2 -2
  38. package/dist/lib/governance/index.d.ts +2 -2
  39. package/dist/lib/governance/index.js +2 -0
  40. package/dist/lib/governance/index.mjs +3 -1
  41. package/dist/lib/index.d.mts +5 -3
  42. package/dist/lib/index.d.ts +5 -3
  43. package/dist/lib/index.js +20 -0
  44. package/dist/lib/index.mjs +19 -0
  45. package/dist/lib/protocols/a2a.js +9 -1
  46. package/dist/lib/protocols/a2a.mjs +9 -1
  47. package/dist/lib/protocols/index.js +9 -2
  48. package/dist/lib/protocols/index.mjs +9 -2
  49. package/dist/lib/protocols/mcp-modern.js +2 -1
  50. package/dist/lib/protocols/mcp-modern.mjs +2 -1
  51. package/dist/lib/protocols/mcp.js +5 -2
  52. package/dist/lib/protocols/mcp.mjs +5 -2
  53. package/dist/lib/protocols/rawResponseCapture.d.mts +6 -0
  54. package/dist/lib/protocols/rawResponseCapture.d.ts +6 -0
  55. package/dist/lib/protocols/rawResponseCapture.js +41 -29
  56. package/dist/lib/protocols/rawResponseCapture.mjs +40 -29
  57. package/dist/lib/protocols/signedRequestRejection.d.mts +9 -0
  58. package/dist/lib/protocols/signedRequestRejection.d.ts +9 -0
  59. package/dist/lib/protocols/signedRequestRejection.js +209 -0
  60. package/dist/lib/protocols/signedRequestRejection.mjs +189 -0
  61. package/dist/lib/protocols/transportDiagnostics.d.mts +1 -0
  62. package/dist/lib/protocols/transportDiagnostics.d.ts +1 -0
  63. package/dist/lib/protocols/transportDiagnostics.js +2 -0
  64. package/dist/lib/protocols/transportDiagnostics.mjs +1 -0
  65. package/dist/lib/registry/types.generated.d.mts +112 -45
  66. package/dist/lib/registry/types.generated.d.ts +112 -45
  67. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  68. package/dist/lib/server/account-provisioning.d.mts +2 -0
  69. package/dist/lib/server/account-provisioning.d.ts +2 -0
  70. package/dist/lib/server/account-provisioning.js +30 -0
  71. package/dist/lib/server/account-provisioning.mjs +6 -0
  72. package/dist/lib/server/account-reference-warnings.d.mts +12 -0
  73. package/dist/lib/server/account-reference-warnings.d.ts +12 -0
  74. package/dist/lib/server/account-reference-warnings.js +48 -0
  75. package/dist/lib/server/account-reference-warnings.mjs +23 -0
  76. package/dist/lib/server/auth-signature.js +1 -0
  77. package/dist/lib/server/auth-signature.mjs +1 -0
  78. package/dist/lib/server/create-adcp-server.d.mts +34 -0
  79. package/dist/lib/server/create-adcp-server.d.ts +34 -0
  80. package/dist/lib/server/create-adcp-server.js +225 -14
  81. package/dist/lib/server/create-adcp-server.mjs +225 -14
  82. package/dist/lib/server/decisioning/account.d.mts +2 -0
  83. package/dist/lib/server/decisioning/account.d.ts +2 -0
  84. package/dist/lib/server/decisioning/runtime/from-platform.js +49 -10
  85. package/dist/lib/server/decisioning/runtime/from-platform.mjs +49 -10
  86. package/dist/lib/server/index.d.mts +2 -2
  87. package/dist/lib/server/index.d.ts +2 -2
  88. package/dist/lib/server/index.js +2 -0
  89. package/dist/lib/server/index.mjs +3 -1
  90. package/dist/lib/signing/agent-resolver/consistency.d.mts +6 -13
  91. package/dist/lib/signing/agent-resolver/consistency.d.ts +6 -13
  92. package/dist/lib/signing/agent-resolver/consistency.js +0 -1
  93. package/dist/lib/signing/agent-resolver/consistency.mjs +0 -1
  94. package/dist/lib/signing/agent-resolver/errors.d.mts +1 -1
  95. package/dist/lib/signing/agent-resolver/errors.d.ts +1 -1
  96. package/dist/lib/signing/agent-resolver/fetch-helpers.d.mts +2 -0
  97. package/dist/lib/signing/agent-resolver/fetch-helpers.d.ts +2 -0
  98. package/dist/lib/signing/agent-resolver/fetch-helpers.js +2 -1
  99. package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +2 -1
  100. package/dist/lib/signing/agent-resolver/jwks-set.js +24 -3
  101. package/dist/lib/signing/agent-resolver/jwks-set.mjs +24 -3
  102. package/dist/lib/signing/agent-resolver/legacy-brand.d.mts +15 -0
  103. package/dist/lib/signing/agent-resolver/legacy-brand.d.ts +15 -0
  104. package/dist/lib/signing/agent-resolver/legacy-brand.js +60 -0
  105. package/dist/lib/signing/agent-resolver/legacy-brand.mjs +36 -0
  106. package/dist/lib/signing/agent-resolver/operator-authorization.d.mts +13 -0
  107. package/dist/lib/signing/agent-resolver/operator-authorization.d.ts +13 -0
  108. package/dist/lib/signing/agent-resolver/operator-authorization.js +108 -0
  109. package/dist/lib/signing/agent-resolver/operator-authorization.mjs +84 -0
  110. package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +14 -4
  111. package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +14 -4
  112. package/dist/lib/signing/agent-resolver/resolve-agent.js +101 -132
  113. package/dist/lib/signing/agent-resolver/resolve-agent.mjs +102 -133
  114. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +7 -1
  115. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +7 -1
  116. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +50 -17
  117. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +50 -17
  118. package/dist/lib/signing/agent-resolver/select-agent.d.mts +14 -15
  119. package/dist/lib/signing/agent-resolver/select-agent.d.ts +14 -15
  120. package/dist/lib/signing/agent-resolver/select-agent.js +98 -13
  121. package/dist/lib/signing/agent-resolver/select-agent.mjs +95 -13
  122. package/dist/lib/signing/brand-jwks.d.mts +27 -75
  123. package/dist/lib/signing/brand-jwks.d.ts +27 -75
  124. package/dist/lib/signing/brand-jwks.js +112 -182
  125. package/dist/lib/signing/brand-jwks.mjs +112 -182
  126. package/dist/lib/signing/errors.d.mts +3 -1
  127. package/dist/lib/signing/errors.d.ts +3 -1
  128. package/dist/lib/signing/errors.js +4 -1
  129. package/dist/lib/signing/errors.mjs +4 -1
  130. package/dist/lib/signing/jwks-https.d.mts +7 -0
  131. package/dist/lib/signing/jwks-https.d.ts +7 -0
  132. package/dist/lib/signing/jwks-https.js +31 -8
  133. package/dist/lib/signing/jwks-https.mjs +31 -8
  134. package/dist/lib/signing/jwks.d.mts +8 -0
  135. package/dist/lib/signing/jwks.d.ts +8 -0
  136. package/dist/lib/signing/middleware.js +2 -1
  137. package/dist/lib/signing/middleware.mjs +2 -1
  138. package/dist/lib/signing/publisher-pins.d.mts +11 -0
  139. package/dist/lib/signing/publisher-pins.d.ts +11 -0
  140. package/dist/lib/signing/publisher-pins.js +125 -0
  141. package/dist/lib/signing/publisher-pins.mjs +101 -0
  142. package/dist/lib/signing/server.d.mts +1 -0
  143. package/dist/lib/signing/server.d.ts +1 -0
  144. package/dist/lib/signing/types.d.mts +5 -0
  145. package/dist/lib/signing/types.d.ts +5 -0
  146. package/dist/lib/signing/verifier.js +49 -4
  147. package/dist/lib/signing/verifier.mjs +49 -4
  148. package/dist/lib/signing/webhook-verifier.d.mts +7 -2
  149. package/dist/lib/signing/webhook-verifier.d.ts +7 -2
  150. package/dist/lib/signing/webhook-verifier.js +42 -2
  151. package/dist/lib/signing/webhook-verifier.mjs +43 -3
  152. package/dist/lib/testing/storyboard/account-policy.d.mts +2 -0
  153. package/dist/lib/testing/storyboard/account-policy.d.ts +2 -0
  154. package/dist/lib/testing/storyboard/account-policy.js +35 -0
  155. package/dist/lib/testing/storyboard/account-policy.mjs +11 -0
  156. package/dist/lib/testing/storyboard/context.js +6 -0
  157. package/dist/lib/testing/storyboard/context.mjs +6 -0
  158. package/dist/lib/testing/storyboard/request-builder.js +12 -2
  159. package/dist/lib/testing/storyboard/request-builder.mjs +12 -2
  160. package/dist/lib/testing/storyboard/runner.js +3 -2
  161. package/dist/lib/testing/storyboard/runner.mjs +3 -2
  162. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  163. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  164. package/dist/lib/version.d.mts +3 -3
  165. package/dist/lib/version.d.ts +3 -3
  166. package/dist/lib/version.js +3 -3
  167. package/dist/lib/version.mjs +3 -3
  168. package/dist/lib/wholesale-feed-sync/sync.d.mts +1 -0
  169. package/dist/lib/wholesale-feed-sync/sync.d.ts +1 -0
  170. package/dist/lib/wholesale-feed-sync/sync.js +92 -21
  171. package/dist/lib/wholesale-feed-sync/sync.mjs +92 -21
  172. package/dist/lib/wholesale-feed-sync/types.d.mts +4 -3
  173. package/dist/lib/wholesale-feed-sync/types.d.ts +4 -3
  174. package/docs/TYPE-SUMMARY.md +2 -2
  175. package/docs/guides/BUILD-AN-AGENT.md +2 -2
  176. package/docs/guides/BUYER-QUICKSTART-3.2.md +2 -0
  177. package/docs/guides/FIRST-CALL-TO-A-SELLER.md +104 -0
  178. package/docs/guides/SIGNING-GUIDE.md +16 -7
  179. package/docs/guides/account-resolution.md +86 -0
  180. package/docs/llms.txt +3 -2
  181. package/docs/migration-14.x-rc-worksheet.md +4 -4
  182. package/docs/migration-4.x-to-5.x.md +1 -0
  183. package/docs/migration-agent-resolution-3.3.md +123 -0
  184. package/docs/recipes/verifying-inbound-webhooks.md +56 -15
  185. package/package.json +2 -2
@@ -83,8 +83,8 @@ export { createPinAndBindFetch, WEBHOOK_SSRF_POLICY, LOOPBACK_OK_WEBHOOK_SSRF_PO
83
83
  export type { PinAndBindFetchOptions, DnsLookupAll } from './pin-and-bind-fetch.mjs';
84
84
  export { checkGovernance, createAdcpGovernanceEnforcementMiddleware, governanceDeniedError, governanceUnavailableError, } from './governance.mjs';
85
85
  export type { AdcpGovernanceEnforcementMiddleware, CheckGovernanceOptions, GovernanceCallResult, GovernanceApproved, GovernanceDenied, GovernanceConditions, } from './governance.mjs';
86
- export { GovernanceAuthorizationError, GovernanceReplayStoreAdapter, InMemoryGovernanceReplayStore, buildGovernanceExecutionCommitment, buildGovernanceExecutionRequest, computeGovernedPayloadHash, createGovernanceEnforcementMiddleware, verifyGovernanceAuthorization, } from '../governance/index.mjs';
87
- export type { BuildGovernanceExecutionRequestInput, GovernanceAuthorizationClaims, GovernanceAuthorizationErrorCode, GovernanceAuthorizationResult, GovernanceAuthorizationSuccess, GovernanceCommitment, GovernanceEnforcementMiddleware, GovernanceEnforcementMiddlewareConfig, GovernanceEnforcementMiddlewareInput, GovernanceReplayStore, GovernanceReplayBinding, GovernanceRevocationResolver, GovernanceRevocationStatus, VerifyGovernanceAuthorizationOptions, } from '../governance/index.mjs';
86
+ export { GovernanceAuthorizationError, GovernanceReplayStoreAdapter, InMemoryGovernanceReplayStore, buildGovernanceExecutionCommitment, buildGovernanceExecutionRequest, computeGovernedPayloadHash, createGovernanceEnforcementMiddleware, verifyGovernanceAuthorization, createGovernanceAgentJwksResolver, } from '../governance/index.mjs';
87
+ export type { BuildGovernanceExecutionRequestInput, GovernanceAuthorizationClaims, GovernanceAuthorizationErrorCode, GovernanceAuthorizationResult, GovernanceAuthorizationSuccess, GovernanceCommitment, GovernanceEnforcementMiddleware, GovernanceEnforcementMiddlewareConfig, GovernanceEnforcementMiddlewareInput, GovernanceReplayStore, GovernanceReplayBinding, GovernanceRevocationResolver, GovernanceRevocationStatus, VerifyGovernanceAuthorizationOptions, GovernanceBuyerIdentity, } from '../governance/index.mjs';
88
88
  export { clearDefaultResolvedListCache, createResolvedListCache, DEFAULT_RESOLVE_LIST_PAGE_SIZE, defaultResolvedListCache, resolvePropertyList, resolveCollectionList, resolvedListCacheKey, matchesPropertyList, matchesCollectionList, } from './targeting-helpers.mjs';
89
89
  export type { ResolvedListCache, ResolvedListCacheEntry, ResolvedListCacheValue, ResolvedListKind, ResolvedPropertyList, ResolvedCollectionList, ResolvedCollection, ResolveListCallTool, ResolveListOptions, } from './targeting-helpers.mjs';
90
90
  export * from './decisioning/index.mjs';
@@ -83,8 +83,8 @@ export { createPinAndBindFetch, WEBHOOK_SSRF_POLICY, LOOPBACK_OK_WEBHOOK_SSRF_PO
83
83
  export type { PinAndBindFetchOptions, DnsLookupAll } from './pin-and-bind-fetch';
84
84
  export { checkGovernance, createAdcpGovernanceEnforcementMiddleware, governanceDeniedError, governanceUnavailableError, } from './governance';
85
85
  export type { AdcpGovernanceEnforcementMiddleware, CheckGovernanceOptions, GovernanceCallResult, GovernanceApproved, GovernanceDenied, GovernanceConditions, } from './governance';
86
- export { GovernanceAuthorizationError, GovernanceReplayStoreAdapter, InMemoryGovernanceReplayStore, buildGovernanceExecutionCommitment, buildGovernanceExecutionRequest, computeGovernedPayloadHash, createGovernanceEnforcementMiddleware, verifyGovernanceAuthorization, } from '../governance';
87
- export type { BuildGovernanceExecutionRequestInput, GovernanceAuthorizationClaims, GovernanceAuthorizationErrorCode, GovernanceAuthorizationResult, GovernanceAuthorizationSuccess, GovernanceCommitment, GovernanceEnforcementMiddleware, GovernanceEnforcementMiddlewareConfig, GovernanceEnforcementMiddlewareInput, GovernanceReplayStore, GovernanceReplayBinding, GovernanceRevocationResolver, GovernanceRevocationStatus, VerifyGovernanceAuthorizationOptions, } from '../governance';
86
+ export { GovernanceAuthorizationError, GovernanceReplayStoreAdapter, InMemoryGovernanceReplayStore, buildGovernanceExecutionCommitment, buildGovernanceExecutionRequest, computeGovernedPayloadHash, createGovernanceEnforcementMiddleware, verifyGovernanceAuthorization, createGovernanceAgentJwksResolver, } from '../governance';
87
+ export type { BuildGovernanceExecutionRequestInput, GovernanceAuthorizationClaims, GovernanceAuthorizationErrorCode, GovernanceAuthorizationResult, GovernanceAuthorizationSuccess, GovernanceCommitment, GovernanceEnforcementMiddleware, GovernanceEnforcementMiddlewareConfig, GovernanceEnforcementMiddlewareInput, GovernanceReplayStore, GovernanceReplayBinding, GovernanceRevocationResolver, GovernanceRevocationStatus, VerifyGovernanceAuthorizationOptions, GovernanceBuyerIdentity, } from '../governance';
88
88
  export { clearDefaultResolvedListCache, createResolvedListCache, DEFAULT_RESOLVE_LIST_PAGE_SIZE, defaultResolvedListCache, resolvePropertyList, resolveCollectionList, resolvedListCacheKey, matchesPropertyList, matchesCollectionList, } from './targeting-helpers';
89
89
  export type { ResolvedListCache, ResolvedListCacheEntry, ResolvedListCacheValue, ResolvedListKind, ResolvedPropertyList, ResolvedCollectionList, ResolvedCollection, ResolveListCallTool, ResolveListOptions, } from './targeting-helpers';
90
90
  export * from './decisioning';
@@ -112,6 +112,7 @@ __export(server_exports, {
112
112
  createDerivedAccountStore: () => import_derived_account_store.createDerivedAccountStore,
113
113
  createDynamicRegistry: () => import_dynamic_registry.createDynamicRegistry,
114
114
  createExpressAdapter: () => import_express_adapter.createExpressAdapter,
115
+ createGovernanceAgentJwksResolver: () => import_governance2.createGovernanceAgentJwksResolver,
115
116
  createGovernanceEnforcementMiddleware: () => import_governance2.createGovernanceEnforcementMiddleware,
116
117
  createIdempotencyStore: () => import_idempotency.createIdempotencyStore,
117
118
  createLazyBackend: () => import_idempotency.createLazyBackend,
@@ -439,6 +440,7 @@ var import_media_buy_action_resolver = require('./media-buy-action-resolver.js')
439
440
  createDerivedAccountStore,
440
441
  createDynamicRegistry,
441
442
  createExpressAdapter,
443
+ createGovernanceAgentJwksResolver,
442
444
  createGovernanceEnforcementMiddleware,
443
445
  createIdempotencyStore,
444
446
  createLazyBackend,
@@ -234,7 +234,8 @@ import {
234
234
  buildGovernanceExecutionRequest,
235
235
  computeGovernedPayloadHash,
236
236
  createGovernanceEnforcementMiddleware,
237
- verifyGovernanceAuthorization
237
+ verifyGovernanceAuthorization,
238
+ createGovernanceAgentJwksResolver
238
239
  } from "../governance/index.mjs";
239
240
  import {
240
241
  clearDefaultResolvedListCache,
@@ -387,6 +388,7 @@ export {
387
388
  createDerivedAccountStore,
388
389
  createDynamicRegistry,
389
390
  createExpressAdapter,
391
+ createGovernanceAgentJwksResolver,
390
392
  createGovernanceEnforcementMiddleware,
391
393
  createIdempotencyStore,
392
394
  createLazyBackend,
@@ -5,9 +5,8 @@
5
5
  *
6
6
  * `request_signature_key_origin_mismatch` — the resolved `jwks_uri` host
7
7
  * does not match the operator's declared `identity.key_origins.{purpose}`
8
- * value. Skipped only for the specific (agent, purpose, role) tuple
9
- * whose JWKS source was a publisher `adagents.json signing_keys` pin —
10
- * operator-side use of the same purpose is still checked.
8
+ * value. Publisher pins never skip this check because they only narrow
9
+ * keys in the operator's JWKS.
11
10
  *
12
11
  * `request_signature_key_origin_missing` — the agent's capabilities
13
12
  * declare a signing posture for a purpose (e.g. `request_signing.supported_for`
@@ -36,24 +35,18 @@ export interface KeyOriginMissing {
36
35
  export type ConsistencyResult = {
37
36
  ok: true;
38
37
  } | KeyOriginMismatch | KeyOriginMissing;
39
- /**
40
- * Inputs for the per-purpose origin check. The caller is responsible for
41
- * deciding whether `publisherPinned` is true — the carve-out applies only
42
- * to (agent, webhook-signing, sell-side) tuples whose JWKS came from an
43
- * `adagents.json signing_keys` pin. For request-signing, governance-signing,
44
- * TMP-signing, and buyer-side webhook receivers, `publisherPinned` MUST
45
- * always be false.
46
- */
38
+ /** Inputs for the per-purpose origin check. Publisher pin markers are ignored. */
47
39
  export interface OriginCheckInput {
48
40
  purpose: IdentityKeyOriginPurpose;
49
41
  declaredOrigin: string | undefined;
50
42
  resolvedJwksUri: string;
51
- publisherPinned: boolean;
43
+ /** @deprecated Pins narrow JWKS keys and never bypass origin checks. */
44
+ publisherPinned?: boolean;
52
45
  }
53
46
  /**
54
47
  * Check origin consistency for a single (purpose, jwksUri) pair against the
55
48
  * declared `identity.key_origins.{purpose}` value. Returns `{ ok: true }`
56
- * when the check passes or is skipped (publisher pin); a typed mismatch
49
+ * when the check passes; a typed mismatch
57
50
  * result on failure. `key_origin_missing` is NOT raised here — that is a
58
51
  * separate check (`checkRequiredOrigins`) because it depends on which
59
52
  * purposes the agent has declared signing for.
@@ -5,9 +5,8 @@
5
5
  *
6
6
  * `request_signature_key_origin_mismatch` — the resolved `jwks_uri` host
7
7
  * does not match the operator's declared `identity.key_origins.{purpose}`
8
- * value. Skipped only for the specific (agent, purpose, role) tuple
9
- * whose JWKS source was a publisher `adagents.json signing_keys` pin —
10
- * operator-side use of the same purpose is still checked.
8
+ * value. Publisher pins never skip this check because they only narrow
9
+ * keys in the operator's JWKS.
11
10
  *
12
11
  * `request_signature_key_origin_missing` — the agent's capabilities
13
12
  * declare a signing posture for a purpose (e.g. `request_signing.supported_for`
@@ -36,24 +35,18 @@ export interface KeyOriginMissing {
36
35
  export type ConsistencyResult = {
37
36
  ok: true;
38
37
  } | KeyOriginMismatch | KeyOriginMissing;
39
- /**
40
- * Inputs for the per-purpose origin check. The caller is responsible for
41
- * deciding whether `publisherPinned` is true — the carve-out applies only
42
- * to (agent, webhook-signing, sell-side) tuples whose JWKS came from an
43
- * `adagents.json signing_keys` pin. For request-signing, governance-signing,
44
- * TMP-signing, and buyer-side webhook receivers, `publisherPinned` MUST
45
- * always be false.
46
- */
38
+ /** Inputs for the per-purpose origin check. Publisher pin markers are ignored. */
47
39
  export interface OriginCheckInput {
48
40
  purpose: IdentityKeyOriginPurpose;
49
41
  declaredOrigin: string | undefined;
50
42
  resolvedJwksUri: string;
51
- publisherPinned: boolean;
43
+ /** @deprecated Pins narrow JWKS keys and never bypass origin checks. */
44
+ publisherPinned?: boolean;
52
45
  }
53
46
  /**
54
47
  * Check origin consistency for a single (purpose, jwksUri) pair against the
55
48
  * declared `identity.key_origins.{purpose}` value. Returns `{ ok: true }`
56
- * when the check passes or is skipped (publisher pin); a typed mismatch
49
+ * when the check passes; a typed mismatch
57
50
  * result on failure. `key_origin_missing` is NOT raised here — that is a
58
51
  * separate check (`checkRequiredOrigins`) because it depends on which
59
52
  * purposes the agent has declared signing for.
@@ -25,7 +25,6 @@ __export(consistency_exports, {
25
25
  module.exports = __toCommonJS(consistency_exports);
26
26
  var import_canonicalize = require('./canonicalize.js');
27
27
  function checkOriginConsistency(input) {
28
- if (input.publisherPinned) return { ok: true };
29
28
  if (!input.declaredOrigin) return { ok: true };
30
29
  let expected;
31
30
  let actual;
@@ -1,6 +1,5 @@
1
1
  import { canonicalizeOrigin } from "./canonicalize.mjs";
2
2
  function checkOriginConsistency(input) {
3
- if (input.publisherPinned) return { ok: true };
4
3
  if (!input.declaredOrigin) return { ok: true };
5
4
  let expected;
6
5
  let actual;
@@ -17,7 +17,7 @@
17
17
  * `address` or `hostname` fields the underlying error carries.
18
18
  */
19
19
  export declare const ATTACKER_INFLUENCED: unique symbol;
20
- export type AgentResolverErrorCode = 'request_signature_brand_json_url_missing' | 'request_signature_capabilities_unreachable' | 'request_signature_brand_json_unreachable' | 'request_signature_brand_json_malformed' | 'request_signature_brand_origin_mismatch' | 'request_signature_agent_not_in_brand_json' | 'request_signature_brand_json_ambiguous' | 'request_signature_key_origin_mismatch' | 'request_signature_key_origin_missing' | 'request_signature_jwks_unavailable' | 'request_signature_jwks_untrusted' | 'request_signature_key_purpose_invalid';
20
+ export type AgentResolverErrorCode = 'request_signature_brand_json_url_missing' | 'request_signature_key_unknown' | 'request_signature_capabilities_unreachable' | 'request_signature_brand_json_unreachable' | 'request_signature_brand_json_malformed' | 'request_signature_brand_origin_mismatch' | 'request_signature_agent_not_in_brand_json' | 'request_signature_brand_json_ambiguous' | 'request_signature_key_origin_mismatch' | 'request_signature_key_origin_missing' | 'request_signature_jwks_unavailable' | 'request_signature_jwks_untrusted' | 'request_signature_key_purpose_invalid';
21
21
  export interface AgentResolverErrorDetail {
22
22
  agent_url?: string;
23
23
  brand_json_url?: string;
@@ -17,7 +17,7 @@
17
17
  * `address` or `hostname` fields the underlying error carries.
18
18
  */
19
19
  export declare const ATTACKER_INFLUENCED: unique symbol;
20
- export type AgentResolverErrorCode = 'request_signature_brand_json_url_missing' | 'request_signature_capabilities_unreachable' | 'request_signature_brand_json_unreachable' | 'request_signature_brand_json_malformed' | 'request_signature_brand_origin_mismatch' | 'request_signature_agent_not_in_brand_json' | 'request_signature_brand_json_ambiguous' | 'request_signature_key_origin_mismatch' | 'request_signature_key_origin_missing' | 'request_signature_jwks_unavailable' | 'request_signature_jwks_untrusted' | 'request_signature_key_purpose_invalid';
20
+ export type AgentResolverErrorCode = 'request_signature_brand_json_url_missing' | 'request_signature_key_unknown' | 'request_signature_capabilities_unreachable' | 'request_signature_brand_json_unreachable' | 'request_signature_brand_json_malformed' | 'request_signature_brand_origin_mismatch' | 'request_signature_agent_not_in_brand_json' | 'request_signature_brand_json_ambiguous' | 'request_signature_key_origin_mismatch' | 'request_signature_key_origin_missing' | 'request_signature_jwks_unavailable' | 'request_signature_jwks_untrusted' | 'request_signature_key_purpose_invalid';
21
21
  export interface AgentResolverErrorDetail {
22
22
  agent_url?: string;
23
23
  brand_json_url?: string;
@@ -8,6 +8,7 @@
8
8
  * `hostname` fields MUST NOT propagate onto `AgentResolverError.detail`
9
9
  * (internal-topology leak). We surface the `code` only.
10
10
  */
11
+ import { type SsrfDnsLookup } from '../../net/index.mjs';
11
12
  export declare const MAX_CAPABILITIES_BYTES = 65536;
12
13
  export declare const MAX_BRAND_JSON_BYTES = 262144;
13
14
  export declare const MAX_JWKS_BYTES = 65536;
@@ -37,4 +38,5 @@ export declare function safeFetchJson(url: string, kind: FetchKind, options: {
37
38
  allowPrivateIp?: boolean;
38
39
  timeoutMs?: number;
39
40
  maxBodyBytes: number;
41
+ lookup?: SsrfDnsLookup;
40
42
  }): Promise<SafeFetchJsonResult>;
@@ -8,6 +8,7 @@
8
8
  * `hostname` fields MUST NOT propagate onto `AgentResolverError.detail`
9
9
  * (internal-topology leak). We surface the `code` only.
10
10
  */
11
+ import { type SsrfDnsLookup } from '../../net';
11
12
  export declare const MAX_CAPABILITIES_BYTES = 65536;
12
13
  export declare const MAX_BRAND_JSON_BYTES = 262144;
13
14
  export declare const MAX_JWKS_BYTES = 65536;
@@ -37,4 +38,5 @@ export declare function safeFetchJson(url: string, kind: FetchKind, options: {
37
38
  allowPrivateIp?: boolean;
38
39
  timeoutMs?: number;
39
40
  maxBodyBytes: number;
41
+ lookup?: SsrfDnsLookup;
40
42
  }): Promise<SafeFetchJsonResult>;
@@ -52,7 +52,8 @@ async function safeFetchJson(url, kind, options) {
52
52
  headers: { accept: "application/json" },
53
53
  allowPrivateIp: options.allowPrivateIp === true,
54
54
  timeoutMs: options.timeoutMs ?? DEFAULT_TOTAL_TIMEOUT_MS,
55
- maxBodyBytes: options.maxBodyBytes
55
+ maxBodyBytes: options.maxBodyBytes,
56
+ lookup: options.lookup
56
57
  };
57
58
  let res;
58
59
  try {
@@ -23,7 +23,8 @@ async function safeFetchJson(url, kind, options) {
23
23
  headers: { accept: "application/json" },
24
24
  allowPrivateIp: options.allowPrivateIp === true,
25
25
  timeoutMs: options.timeoutMs ?? DEFAULT_TOTAL_TIMEOUT_MS,
26
- maxBodyBytes: options.maxBodyBytes
26
+ maxBodyBytes: options.maxBodyBytes,
27
+ lookup: options.lookup
27
28
  };
28
29
  let res;
29
30
  try {
@@ -58,10 +58,11 @@ function createAgentJwksSet(agentUrl, options) {
58
58
  }
59
59
  const now = options.now ?? (() => Date.now() / 1e3);
60
60
  let cache;
61
- let lastRefetchAt = 0;
61
+ let lastRefetchAt = Number.NEGATIVE_INFINITY;
62
62
  let inFlight;
63
63
  const refresh = async () => {
64
64
  if (inFlight) return inFlight;
65
+ lastRefetchAt = now();
65
66
  inFlight = (async () => {
66
67
  const resolution = await (0, import_resolve_agent.resolveAgent)(agentUrl, options);
67
68
  const refreshedAt = now();
@@ -85,7 +86,21 @@ function createAgentJwksSet(agentUrl, options) {
85
86
  return inFlight;
86
87
  };
87
88
  const ensureFresh = async () => {
88
- if (!cache || now() - cache.fetchedAt >= cacheMaxAge || cache.resolution.operatorAuthorizationValidUntil !== void 0 && now() >= cache.resolution.operatorAuthorizationValidUntil) {
89
+ if (!cache || now() - cache.fetchedAt >= Math.min(
90
+ cacheMaxAge,
91
+ 1800,
92
+ Math.max(30, headerLifetime(cache.resolution.brandJsonCacheControl)),
93
+ Math.max(60, headerLifetime(cache.resolution.jwksCacheControl))
94
+ ) || cache.resolution.operatorAuthorizationValidUntil !== void 0 && now() >= cache.resolution.operatorAuthorizationValidUntil) {
95
+ if (!inFlight && now() - lastRefetchAt < 30) {
96
+ const expired = cache?.resolution.operatorAuthorizationValidUntil !== void 0 && now() >= cache.resolution.operatorAuthorizationValidUntil;
97
+ throw new import_errors.AgentResolverError(
98
+ expired ? "request_signature_brand_origin_mismatch" : "request_signature_brand_json_unreachable",
99
+ "Expired operator mapping cannot be used during the discovery cooldown",
100
+ { agent_url: agentUrl },
101
+ ["agent_url"]
102
+ );
103
+ }
89
104
  return refresh();
90
105
  }
91
106
  return cache;
@@ -95,7 +110,7 @@ function createAgentJwksSet(agentUrl, options) {
95
110
  try {
96
111
  return await fresh.getKey(protectedHeader, token);
97
112
  } catch (err) {
98
- if (now() - lastRefetchAt < kidCooldown) throw err;
113
+ if (now() - lastRefetchAt < Math.max(30, kidCooldown)) throw err;
99
114
  const refreshed = await refresh();
100
115
  return refreshed.getKey(protectedHeader, token);
101
116
  }
@@ -118,6 +133,12 @@ function assertAllJwksAllowed(jwks, allowedAlgs, agentUrl) {
118
133
  function filterJwksToAllowedAlgs(jwks, allowedAlgs) {
119
134
  return jwks.keys.filter((jwk) => typeof jwk.alg !== "string" || allowedAlgs.has(jwk.alg));
120
135
  }
136
+ function headerLifetime(value) {
137
+ if (!value) return Infinity;
138
+ if (/\bno-cache\b|\bno-store\b/i.test(value)) return 0;
139
+ const match = /(?:^|,)\s*max-age\s*=\s*"?(\d+)/i.exec(value);
140
+ return match ? Number(match[1]) : Infinity;
141
+ }
121
142
  // Annotate the CommonJS export names for ESM import in node:
122
143
  0 && (module.exports = {
123
144
  createAgentJwksSet,
@@ -34,10 +34,11 @@ function createAgentJwksSet(agentUrl, options) {
34
34
  }
35
35
  const now = options.now ?? (() => Date.now() / 1e3);
36
36
  let cache;
37
- let lastRefetchAt = 0;
37
+ let lastRefetchAt = Number.NEGATIVE_INFINITY;
38
38
  let inFlight;
39
39
  const refresh = async () => {
40
40
  if (inFlight) return inFlight;
41
+ lastRefetchAt = now();
41
42
  inFlight = (async () => {
42
43
  const resolution = await resolveAgent(agentUrl, options);
43
44
  const refreshedAt = now();
@@ -61,7 +62,21 @@ function createAgentJwksSet(agentUrl, options) {
61
62
  return inFlight;
62
63
  };
63
64
  const ensureFresh = async () => {
64
- if (!cache || now() - cache.fetchedAt >= cacheMaxAge || cache.resolution.operatorAuthorizationValidUntil !== void 0 && now() >= cache.resolution.operatorAuthorizationValidUntil) {
65
+ if (!cache || now() - cache.fetchedAt >= Math.min(
66
+ cacheMaxAge,
67
+ 1800,
68
+ Math.max(30, headerLifetime(cache.resolution.brandJsonCacheControl)),
69
+ Math.max(60, headerLifetime(cache.resolution.jwksCacheControl))
70
+ ) || cache.resolution.operatorAuthorizationValidUntil !== void 0 && now() >= cache.resolution.operatorAuthorizationValidUntil) {
71
+ if (!inFlight && now() - lastRefetchAt < 30) {
72
+ const expired = cache?.resolution.operatorAuthorizationValidUntil !== void 0 && now() >= cache.resolution.operatorAuthorizationValidUntil;
73
+ throw new AgentResolverError(
74
+ expired ? "request_signature_brand_origin_mismatch" : "request_signature_brand_json_unreachable",
75
+ "Expired operator mapping cannot be used during the discovery cooldown",
76
+ { agent_url: agentUrl },
77
+ ["agent_url"]
78
+ );
79
+ }
65
80
  return refresh();
66
81
  }
67
82
  return cache;
@@ -71,7 +86,7 @@ function createAgentJwksSet(agentUrl, options) {
71
86
  try {
72
87
  return await fresh.getKey(protectedHeader, token);
73
88
  } catch (err) {
74
- if (now() - lastRefetchAt < kidCooldown) throw err;
89
+ if (now() - lastRefetchAt < Math.max(30, kidCooldown)) throw err;
75
90
  const refreshed = await refresh();
76
91
  return refreshed.getKey(protectedHeader, token);
77
92
  }
@@ -94,6 +109,12 @@ function assertAllJwksAllowed(jwks, allowedAlgs, agentUrl) {
94
109
  function filterJwksToAllowedAlgs(jwks, allowedAlgs) {
95
110
  return jwks.keys.filter((jwk) => typeof jwk.alg !== "string" || allowedAlgs.has(jwk.alg));
96
111
  }
112
+ function headerLifetime(value) {
113
+ if (!value) return Infinity;
114
+ if (/\bno-cache\b|\bno-store\b/i.test(value)) return 0;
115
+ const match = /(?:^|,)\s*max-age\s*=\s*"?(\d+)/i.exec(value);
116
+ return match ? Number(match[1]) : Infinity;
117
+ }
97
118
  export {
98
119
  createAgentJwksSet,
99
120
  getAgentJwks
@@ -0,0 +1,15 @@
1
+ import type { SsrfDnsLookup } from '../../net/index.mjs';
2
+ /** 3.x webhook compatibility only; explicit capability URLs never use this path. */
3
+ export declare function fetchLegacyBrandJson(agentUrl: string, options: {
4
+ allowPrivateIp?: boolean;
5
+ timeoutMs?: number;
6
+ maxBodyBytes: number;
7
+ lookup?: SsrfDnsLookup;
8
+ }): Promise<{
9
+ body: unknown;
10
+ url: string;
11
+ fetchedAt: number;
12
+ headers: {
13
+ 'cache-control': string | undefined;
14
+ };
15
+ }>;
@@ -0,0 +1,15 @@
1
+ import type { SsrfDnsLookup } from '../../net';
2
+ /** 3.x webhook compatibility only; explicit capability URLs never use this path. */
3
+ export declare function fetchLegacyBrandJson(agentUrl: string, options: {
4
+ allowPrivateIp?: boolean;
5
+ timeoutMs?: number;
6
+ maxBodyBytes: number;
7
+ lookup?: SsrfDnsLookup;
8
+ }): Promise<{
9
+ body: unknown;
10
+ url: string;
11
+ fetchedAt: number;
12
+ headers: {
13
+ 'cache-control': string | undefined;
14
+ };
15
+ }>;
@@ -0,0 +1,60 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var legacy_brand_exports = {};
20
+ __export(legacy_brand_exports, {
21
+ fetchLegacyBrandJson: () => fetchLegacyBrandJson
22
+ });
23
+ module.exports = __toCommonJS(legacy_brand_exports);
24
+ var import_brand_jwks = require('../brand-jwks.js');
25
+ var import_etld = require('./etld.js');
26
+ var import_fetch_helpers = require('./fetch-helpers.js');
27
+ async function fetchLegacyBrandJson(agentUrl, options) {
28
+ const agent = new URL(agentUrl);
29
+ let startUrl = `${agent.origin}/.well-known/brand.json`;
30
+ const fetch = (url) => (0, import_brand_jwks.fetchBrandJson)({ ...options, startUrl: url, domainDerived: true, maxRedirects: 1 });
31
+ let result;
32
+ try {
33
+ try {
34
+ result = await fetch(startUrl);
35
+ } catch (err) {
36
+ if (!(err instanceof import_brand_jwks.BrandJsonResolverError) || err.httpStatus !== 404 && err.httpStatus !== 410) throw err;
37
+ const domain = (0, import_etld.eTldPlusOne)(agentUrl);
38
+ if (domain === agent.hostname) throw err;
39
+ startUrl = `https://${domain}/.well-known/brand.json`;
40
+ result = await fetch(startUrl);
41
+ }
42
+ } catch (err) {
43
+ throw new import_fetch_helpers.SafeFetchError(
44
+ "brand.json",
45
+ "fetch_failed",
46
+ err instanceof import_brand_jwks.BrandJsonResolverError && err.code === "invalid_body" ? "brand.json body failed strict-JSON parse" : "Legacy brand.json discovery failed",
47
+ err instanceof import_brand_jwks.BrandJsonResolverError ? err.httpStatus : void 0
48
+ );
49
+ }
50
+ return {
51
+ body: result.data,
52
+ url: result.finalUrl,
53
+ fetchedAt: Math.floor(Date.now() / 1e3),
54
+ headers: { "cache-control": result.cacheControl }
55
+ };
56
+ }
57
+ // Annotate the CommonJS export names for ESM import in node:
58
+ 0 && (module.exports = {
59
+ fetchLegacyBrandJson
60
+ });
@@ -0,0 +1,36 @@
1
+ import { fetchBrandJson, BrandJsonResolverError } from "../brand-jwks.mjs";
2
+ import { eTldPlusOne } from "./etld.mjs";
3
+ import { SafeFetchError } from "./fetch-helpers.mjs";
4
+ async function fetchLegacyBrandJson(agentUrl, options) {
5
+ const agent = new URL(agentUrl);
6
+ let startUrl = `${agent.origin}/.well-known/brand.json`;
7
+ const fetch = (url) => fetchBrandJson({ ...options, startUrl: url, domainDerived: true, maxRedirects: 1 });
8
+ let result;
9
+ try {
10
+ try {
11
+ result = await fetch(startUrl);
12
+ } catch (err) {
13
+ if (!(err instanceof BrandJsonResolverError) || err.httpStatus !== 404 && err.httpStatus !== 410) throw err;
14
+ const domain = eTldPlusOne(agentUrl);
15
+ if (domain === agent.hostname) throw err;
16
+ startUrl = `https://${domain}/.well-known/brand.json`;
17
+ result = await fetch(startUrl);
18
+ }
19
+ } catch (err) {
20
+ throw new SafeFetchError(
21
+ "brand.json",
22
+ "fetch_failed",
23
+ err instanceof BrandJsonResolverError && err.code === "invalid_body" ? "brand.json body failed strict-JSON parse" : "Legacy brand.json discovery failed",
24
+ err instanceof BrandJsonResolverError ? err.httpStatus : void 0
25
+ );
26
+ }
27
+ return {
28
+ body: result.data,
29
+ url: result.finalUrl,
30
+ fetchedAt: Math.floor(Date.now() / 1e3),
31
+ headers: { "cache-control": result.cacheControl }
32
+ };
33
+ }
34
+ export {
35
+ fetchLegacyBrandJson
36
+ };
@@ -0,0 +1,13 @@
1
+ /** Optional receiver account authorization, separate from agent origin binding. */
2
+ import type { ResolveAgentOptions } from './resolve-agent.mjs';
3
+ interface ActiveOperatorDelegation {
4
+ validUntil?: number;
5
+ }
6
+ /**
7
+ * Evaluate the complete cross-origin delegation tuple. Domain matching is
8
+ * against the exact agent eTLD+1 to match step 3 of the
9
+ * discovery algorithm; brand, activity, country, and time remain independent
10
+ * authorization dimensions and must all match the same entry.
11
+ */
12
+ export declare function checkDelegatedOperatorAuthorization(brandJson: unknown, agentEtld1: string, now: number, options: Pick<ResolveAgentOptions, 'requiredOperatorBrand' | 'requiredOperatorScope' | 'requiredOperatorCountry' | 'allowPrivateIp'>): ActiveOperatorDelegation | undefined;
13
+ export {};
@@ -0,0 +1,13 @@
1
+ /** Optional receiver account authorization, separate from agent origin binding. */
2
+ import type { ResolveAgentOptions } from './resolve-agent';
3
+ interface ActiveOperatorDelegation {
4
+ validUntil?: number;
5
+ }
6
+ /**
7
+ * Evaluate the complete cross-origin delegation tuple. Domain matching is
8
+ * against the exact agent eTLD+1 to match step 3 of the
9
+ * discovery algorithm; brand, activity, country, and time remain independent
10
+ * authorization dimensions and must all match the same entry.
11
+ */
12
+ export declare function checkDelegatedOperatorAuthorization(brandJson: unknown, agentEtld1: string, now: number, options: Pick<ResolveAgentOptions, 'requiredOperatorBrand' | 'requiredOperatorScope' | 'requiredOperatorCountry' | 'allowPrivateIp'>): ActiveOperatorDelegation | undefined;
13
+ export {};
@@ -0,0 +1,108 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var operator_authorization_exports = {};
20
+ __export(operator_authorization_exports, {
21
+ checkDelegatedOperatorAuthorization: () => checkDelegatedOperatorAuthorization
22
+ });
23
+ module.exports = __toCommonJS(operator_authorization_exports);
24
+ const AUTHORIZED_OPERATOR_SCOPES = /* @__PURE__ */ new Set([
25
+ "all",
26
+ "media_buying",
27
+ "creative_generation",
28
+ "rights_clearance",
29
+ "governance",
30
+ "measurement",
31
+ "agent_operations"
32
+ ]);
33
+ const AUTHORIZED_OPERATOR_DOMAIN = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/;
34
+ function checkDelegatedOperatorAuthorization(brandJson, agentEtld1, now, options) {
35
+ if (!brandJson || typeof brandJson !== "object") return void 0;
36
+ const operators = brandJson.authorized_operators;
37
+ if (!Array.isArray(operators)) return void 0;
38
+ let latestValidUntil;
39
+ let matched = false;
40
+ for (const op of operators) {
41
+ if (!op || typeof op !== "object" || Array.isArray(op)) continue;
42
+ const candidate = op;
43
+ const domain = candidate.domain;
44
+ const brands = candidate.brands;
45
+ if (typeof domain !== "string" || !AUTHORIZED_OPERATOR_DOMAIN.test(domain) || !isValidBrandGrant(brands)) {
46
+ continue;
47
+ }
48
+ if (domain !== agentEtld1) continue;
49
+ const scopes = candidate.scopes;
50
+ if (scopes !== void 0 && !isValidScopeGrant(scopes)) continue;
51
+ const countries = candidate.countries;
52
+ if (countries !== void 0 && !isValidCountryGrant(countries)) continue;
53
+ const validFrom = parseOptionalRfc3339(candidate.valid_from);
54
+ const validUntil = parseOptionalRfc3339(candidate.valid_until);
55
+ if (validFrom === null || validUntil === null) continue;
56
+ if (validFrom !== void 0 && validUntil !== void 0 && validFrom >= validUntil) continue;
57
+ if (validFrom !== void 0 && now < validFrom) continue;
58
+ if (validUntil !== void 0 && now >= validUntil) continue;
59
+ if (!matchesGrant(brands, options.requiredOperatorBrand, "*")) continue;
60
+ if (scopes !== void 0 && !matchesGrant(scopes, options.requiredOperatorScope, "all")) continue;
61
+ if (countries !== void 0 && !matchesGrant(countries, options.requiredOperatorCountry)) continue;
62
+ matched = true;
63
+ if (validUntil === void 0) return {};
64
+ latestValidUntil = Math.max(latestValidUntil ?? Number.NEGATIVE_INFINITY, validUntil);
65
+ }
66
+ return matched ? { validUntil: latestValidUntil } : void 0;
67
+ }
68
+ function isValidBrandGrant(value) {
69
+ return Array.isArray(value) && value.length > 0 && value.every((item) => typeof item === "string" && (item === "*" || /^[a-z0-9_]+$/.test(item)));
70
+ }
71
+ function isValidScopeGrant(value) {
72
+ return Array.isArray(value) && value.length > 0 && new Set(value).size === value.length && value.every((item) => typeof item === "string" && AUTHORIZED_OPERATOR_SCOPES.has(item));
73
+ }
74
+ function isValidCountryGrant(value) {
75
+ return Array.isArray(value) && value.every((item) => typeof item === "string" && /^[A-Z]{2}$/.test(item));
76
+ }
77
+ function matchesGrant(grants, required, wildcard) {
78
+ if (wildcard !== void 0 && grants.includes(wildcard)) return true;
79
+ return required !== void 0 && grants.includes(required);
80
+ }
81
+ function parseOptionalRfc3339(value) {
82
+ if (value === void 0) return void 0;
83
+ if (typeof value !== "string") return null;
84
+ const match = /^(\d{4})-(\d{2})-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(?:\.(\d+))?([Zz]|([+-])(\d{2}):(\d{2}))$/.exec(
85
+ value
86
+ );
87
+ if (!match) return null;
88
+ const year = Number(match[1]);
89
+ const month = Number(match[2]);
90
+ const day = Number(match[3]);
91
+ const hour = Number(match[4]);
92
+ const minute = Number(match[5]);
93
+ const second = Number(match[6]);
94
+ const offsetHour = match[10] === void 0 ? 0 : Number(match[10]);
95
+ const offsetMinute = match[11] === void 0 ? 0 : Number(match[11]);
96
+ if (month < 1 || month > 12 || day < 1 || day > daysInMonth(year, month) || hour > 23 || minute > 59 || second > 59 || offsetHour > 23 || offsetMinute > 59) {
97
+ return null;
98
+ }
99
+ const parsed = Date.parse(value) / 1e3;
100
+ return Number.isFinite(parsed) ? parsed : null;
101
+ }
102
+ function daysInMonth(year, month) {
103
+ return new Date(Date.UTC(year, month, 0)).getUTCDate();
104
+ }
105
+ // Annotate the CommonJS export names for ESM import in node:
106
+ 0 && (module.exports = {
107
+ checkDelegatedOperatorAuthorization
108
+ });