@adcp/sdk 14.0.0 → 14.2.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/dist/lib/adapters/implicit-account-store.d.mts +12 -7
- package/dist/lib/adapters/implicit-account-store.d.ts +12 -7
- package/dist/lib/adapters/implicit-account-store.js +69 -15
- package/dist/lib/adapters/implicit-account-store.mjs +69 -15
- package/dist/lib/core/AgentClient.d.mts +1 -0
- package/dist/lib/core/AgentClient.d.ts +1 -0
- package/dist/lib/core/AgentClient.js +3 -0
- package/dist/lib/core/AgentClient.mjs +3 -0
- package/dist/lib/core/SingleAgentClient.d.mts +35 -2
- package/dist/lib/core/SingleAgentClient.d.ts +35 -2
- package/dist/lib/core/SingleAgentClient.js +377 -36
- package/dist/lib/core/SingleAgentClient.mjs +387 -38
- package/dist/lib/core/TaskExecutor.d.mts +3 -1
- package/dist/lib/core/TaskExecutor.d.ts +3 -1
- package/dist/lib/core/TaskExecutor.js +17 -12
- package/dist/lib/core/TaskExecutor.mjs +17 -12
- package/dist/lib/core/account-key.d.mts +3 -0
- package/dist/lib/core/account-key.d.ts +3 -0
- package/dist/lib/core/account-key.js +41 -0
- package/dist/lib/core/account-key.mjs +17 -0
- package/dist/lib/core/account-resolution.d.mts +2 -0
- package/dist/lib/core/account-resolution.d.ts +2 -0
- package/dist/lib/core/buyer-account-registry.d.mts +93 -0
- package/dist/lib/core/buyer-account-registry.d.ts +93 -0
- package/dist/lib/core/buyer-account-registry.js +602 -0
- package/dist/lib/core/buyer-account-registry.mjs +578 -0
- package/dist/lib/core/product-cache.d.mts +18 -0
- package/dist/lib/core/product-cache.d.ts +18 -0
- package/dist/lib/core/product-cache.js +137 -0
- package/dist/lib/core/product-cache.mjs +112 -0
- package/dist/lib/errors/index.d.mts +40 -1
- package/dist/lib/errors/index.d.ts +40 -1
- package/dist/lib/errors/index.js +69 -3
- package/dist/lib/errors/index.mjs +64 -3
- package/dist/lib/governance/authorization.d.mts +17 -1
- package/dist/lib/governance/authorization.d.ts +17 -1
- package/dist/lib/governance/authorization.js +55 -7
- package/dist/lib/governance/authorization.mjs +59 -7
- package/dist/lib/governance/index.d.mts +2 -2
- package/dist/lib/governance/index.d.ts +2 -2
- package/dist/lib/governance/index.js +2 -0
- package/dist/lib/governance/index.mjs +3 -1
- package/dist/lib/index.d.mts +7 -4
- package/dist/lib/index.d.ts +7 -4
- package/dist/lib/index.js +29 -0
- package/dist/lib/index.mjs +31 -1
- package/dist/lib/net/agent-transport-fetch.d.mts +4 -0
- package/dist/lib/net/agent-transport-fetch.d.ts +4 -0
- package/dist/lib/net/agent-transport-fetch.js +18 -5
- package/dist/lib/net/agent-transport-fetch.mjs +17 -5
- package/dist/lib/protocols/a2a.js +9 -1
- package/dist/lib/protocols/a2a.mjs +9 -1
- package/dist/lib/protocols/index.js +9 -2
- package/dist/lib/protocols/index.mjs +9 -2
- package/dist/lib/protocols/mcp-modern.js +2 -1
- package/dist/lib/protocols/mcp-modern.mjs +2 -1
- package/dist/lib/protocols/mcp.js +5 -2
- package/dist/lib/protocols/mcp.mjs +5 -2
- package/dist/lib/protocols/rawResponseCapture.d.mts +6 -0
- package/dist/lib/protocols/rawResponseCapture.d.ts +6 -0
- package/dist/lib/protocols/rawResponseCapture.js +41 -29
- package/dist/lib/protocols/rawResponseCapture.mjs +40 -29
- package/dist/lib/protocols/signedRequestRejection.d.mts +9 -0
- package/dist/lib/protocols/signedRequestRejection.d.ts +9 -0
- package/dist/lib/protocols/signedRequestRejection.js +209 -0
- package/dist/lib/protocols/signedRequestRejection.mjs +189 -0
- package/dist/lib/protocols/transportDiagnostics.d.mts +1 -0
- package/dist/lib/protocols/transportDiagnostics.d.ts +1 -0
- package/dist/lib/protocols/transportDiagnostics.js +2 -0
- package/dist/lib/protocols/transportDiagnostics.mjs +1 -0
- package/dist/lib/registry/types.generated.d.mts +112 -45
- package/dist/lib/registry/types.generated.d.ts +112 -45
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/account-provisioning.d.mts +2 -0
- package/dist/lib/server/account-provisioning.d.ts +2 -0
- package/dist/lib/server/account-provisioning.js +30 -0
- package/dist/lib/server/account-provisioning.mjs +6 -0
- package/dist/lib/server/account-reference-warnings.d.mts +12 -0
- package/dist/lib/server/account-reference-warnings.d.ts +12 -0
- package/dist/lib/server/account-reference-warnings.js +48 -0
- package/dist/lib/server/account-reference-warnings.mjs +23 -0
- package/dist/lib/server/auth-signature.js +1 -0
- package/dist/lib/server/auth-signature.mjs +1 -0
- package/dist/lib/server/create-adcp-server.d.mts +34 -0
- package/dist/lib/server/create-adcp-server.d.ts +34 -0
- package/dist/lib/server/create-adcp-server.js +225 -14
- package/dist/lib/server/create-adcp-server.mjs +225 -14
- package/dist/lib/server/decisioning/account.d.mts +2 -0
- package/dist/lib/server/decisioning/account.d.ts +2 -0
- package/dist/lib/server/decisioning/runtime/from-platform.js +49 -10
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +49 -10
- package/dist/lib/server/index.d.mts +2 -2
- package/dist/lib/server/index.d.ts +2 -2
- package/dist/lib/server/index.js +2 -0
- package/dist/lib/server/index.mjs +3 -1
- package/dist/lib/signing/agent-resolver/consistency.d.mts +6 -13
- package/dist/lib/signing/agent-resolver/consistency.d.ts +6 -13
- package/dist/lib/signing/agent-resolver/consistency.js +0 -1
- package/dist/lib/signing/agent-resolver/consistency.mjs +0 -1
- package/dist/lib/signing/agent-resolver/errors.d.mts +3 -1
- package/dist/lib/signing/agent-resolver/errors.d.ts +3 -1
- package/dist/lib/signing/agent-resolver/errors.js +6 -0
- package/dist/lib/signing/agent-resolver/errors.mjs +6 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.mts +11 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.d.ts +11 -0
- package/dist/lib/signing/agent-resolver/fetch-helpers.js +37 -2
- package/dist/lib/signing/agent-resolver/fetch-helpers.mjs +40 -3
- package/dist/lib/signing/agent-resolver/jwks-set.js +24 -3
- package/dist/lib/signing/agent-resolver/jwks-set.mjs +24 -3
- package/dist/lib/signing/agent-resolver/legacy-brand.d.mts +15 -0
- package/dist/lib/signing/agent-resolver/legacy-brand.d.ts +15 -0
- package/dist/lib/signing/agent-resolver/legacy-brand.js +60 -0
- package/dist/lib/signing/agent-resolver/legacy-brand.mjs +36 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.d.mts +13 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.d.ts +13 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.js +108 -0
- package/dist/lib/signing/agent-resolver/operator-authorization.mjs +84 -0
- package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +14 -4
- package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +14 -4
- package/dist/lib/signing/agent-resolver/resolve-agent.js +148 -137
- package/dist/lib/signing/agent-resolver/resolve-agent.mjs +157 -139
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +7 -1
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +7 -1
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +50 -17
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +50 -17
- package/dist/lib/signing/agent-resolver/select-agent.d.mts +14 -15
- package/dist/lib/signing/agent-resolver/select-agent.d.ts +14 -15
- package/dist/lib/signing/agent-resolver/select-agent.js +98 -13
- package/dist/lib/signing/agent-resolver/select-agent.mjs +95 -13
- package/dist/lib/signing/brand-jwks.d.mts +29 -75
- package/dist/lib/signing/brand-jwks.d.ts +29 -75
- package/dist/lib/signing/brand-jwks.js +120 -182
- package/dist/lib/signing/brand-jwks.mjs +120 -182
- package/dist/lib/signing/errors.d.mts +7 -3
- package/dist/lib/signing/errors.d.ts +7 -3
- package/dist/lib/signing/errors.js +7 -2
- package/dist/lib/signing/errors.mjs +7 -2
- package/dist/lib/signing/jwks-https.d.mts +7 -0
- package/dist/lib/signing/jwks-https.d.ts +7 -0
- package/dist/lib/signing/jwks-https.js +31 -8
- package/dist/lib/signing/jwks-https.mjs +31 -8
- package/dist/lib/signing/jwks.d.mts +8 -0
- package/dist/lib/signing/jwks.d.ts +8 -0
- package/dist/lib/signing/middleware.js +2 -1
- package/dist/lib/signing/middleware.mjs +2 -1
- package/dist/lib/signing/publisher-pins.d.mts +11 -0
- package/dist/lib/signing/publisher-pins.d.ts +11 -0
- package/dist/lib/signing/publisher-pins.js +125 -0
- package/dist/lib/signing/publisher-pins.mjs +101 -0
- package/dist/lib/signing/server.d.mts +1 -0
- package/dist/lib/signing/server.d.ts +1 -0
- package/dist/lib/signing/types.d.mts +5 -0
- package/dist/lib/signing/types.d.ts +5 -0
- package/dist/lib/signing/verifier.js +50 -5
- package/dist/lib/signing/verifier.mjs +50 -5
- package/dist/lib/signing/webhook-verifier.d.mts +7 -2
- package/dist/lib/signing/webhook-verifier.d.ts +7 -2
- package/dist/lib/signing/webhook-verifier.js +42 -2
- package/dist/lib/signing/webhook-verifier.mjs +42 -2
- package/dist/lib/testing/storyboard/account-policy.d.mts +2 -0
- package/dist/lib/testing/storyboard/account-policy.d.ts +2 -0
- package/dist/lib/testing/storyboard/account-policy.js +35 -0
- package/dist/lib/testing/storyboard/account-policy.mjs +11 -0
- package/dist/lib/testing/storyboard/context.js +6 -0
- package/dist/lib/testing/storyboard/context.mjs +6 -0
- package/dist/lib/testing/storyboard/request-builder.js +12 -2
- package/dist/lib/testing/storyboard/request-builder.mjs +12 -2
- package/dist/lib/testing/storyboard/runner.js +3 -2
- package/dist/lib/testing/storyboard/runner.mjs +3 -2
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/types/accept-proposal.d.ts +19 -1
- package/dist/lib/types/buy-products.d.ts +19 -1
- package/dist/lib/types/check-governance.d.ts +19 -1
- package/dist/lib/types/comply-test-controller.d.ts +19 -1
- package/dist/lib/types/control-media-buy.d.ts +19 -1
- package/dist/lib/types/core.generated.d.mts +14 -1
- package/dist/lib/types/core.generated.d.ts +14 -1
- package/dist/lib/types/create-media-buy.d.ts +14 -1
- package/dist/lib/types/get-media-buys.d.ts +14 -1
- package/dist/lib/types/get-products.d.ts +19 -1
- package/dist/lib/types/list-products.d.ts +19 -1
- package/dist/lib/types/refine-proposals.d.ts +19 -1
- package/dist/lib/types/request-proposals.d.ts +19 -1
- package/dist/lib/types/schemas.generated.d.ts +12 -3
- package/dist/lib/types/schemas.generated.js +4 -1
- package/dist/lib/types/schemas.generated.mjs +4 -1
- package/dist/lib/types/tools.generated.d.mts +14 -1
- package/dist/lib/types/tools.generated.d.ts +14 -1
- package/dist/lib/types/update-media-buy.d.ts +14 -1
- 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/dist/lib/webhooks/index.d.mts +24 -0
- package/dist/lib/webhooks/index.d.ts +24 -0
- package/dist/lib/webhooks/index.js +50 -24
- package/dist/lib/webhooks/index.mjs +49 -24
- package/dist/lib/wholesale-feed-sync/index.d.mts +2 -0
- package/dist/lib/wholesale-feed-sync/index.d.ts +2 -0
- package/dist/lib/wholesale-feed-sync/index.js +7 -0
- package/dist/lib/wholesale-feed-sync/index.mjs +4 -0
- package/dist/lib/wholesale-feed-sync/mirror.d.mts +97 -0
- package/dist/lib/wholesale-feed-sync/mirror.d.ts +97 -0
- package/dist/lib/wholesale-feed-sync/mirror.js +350 -0
- package/dist/lib/wholesale-feed-sync/mirror.mjs +322 -0
- package/dist/lib/wholesale-feed-sync/sync.d.mts +13 -29
- package/dist/lib/wholesale-feed-sync/sync.d.ts +13 -29
- package/dist/lib/wholesale-feed-sync/sync.js +208 -281
- package/dist/lib/wholesale-feed-sync/sync.mjs +213 -281
- package/dist/lib/wholesale-feed-sync/types.d.mts +4 -3
- package/dist/lib/wholesale-feed-sync/types.d.ts +4 -3
- package/docs/README.md +6 -0
- package/docs/TYPE-SUMMARY.md +2 -2
- package/docs/guides/BUILD-AN-AGENT.md +2 -2
- package/docs/guides/BUYER-QUICKSTART-3.2.md +2 -0
- package/docs/guides/BUYER-STORAGE.md +3 -0
- package/docs/guides/FIRST-CALL-TO-A-SELLER.md +106 -0
- package/docs/guides/SIGNING-GUIDE.md +16 -7
- package/docs/guides/account-resolution.md +132 -10
- package/docs/llms.txt +3 -2
- package/docs/migration-14.0-to-14.1.md +85 -0
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/docs/migration-4.x-to-5.x.md +1 -0
- package/docs/migration-agent-resolution-3.3.md +125 -0
- package/docs/recipes/verifying-inbound-webhooks.md +60 -15
- package/package.json +3 -2
- package/skills/adcp-brand.previous/SKILL.md +0 -200
- package/skills/adcp-creative.previous/SKILL.md +0 -305
- package/skills/adcp-governance.previous/SKILL.md +0 -566
- package/skills/adcp-measurement.previous/SKILL.md +0 -136
- package/skills/adcp-media-buy.previous/SKILL.md +0 -556
- package/skills/adcp-si.previous/SKILL.md +0 -206
- package/skills/adcp-signals.previous/SKILL.md +0 -204
|
@@ -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';
|
package/dist/lib/server/index.js
CHANGED
|
@@ -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.
|
|
9
|
-
*
|
|
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
|
-
|
|
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
|
|
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.
|
|
9
|
-
*
|
|
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
|
-
|
|
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
|
|
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;
|
|
@@ -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;
|
|
@@ -46,6 +46,8 @@ export interface AgentResolverErrorDetail {
|
|
|
46
46
|
export declare class AgentResolverError extends Error {
|
|
47
47
|
readonly code: AgentResolverErrorCode;
|
|
48
48
|
readonly detail: AgentResolverErrorDetail;
|
|
49
|
+
/** Local, cause-aware recovery. Wire codes retain the protocol taxonomy. */
|
|
50
|
+
readonly recovery: 'transient' | 'correctable' | 'terminal';
|
|
49
51
|
readonly [ATTACKER_INFLUENCED]: ReadonlyArray<keyof AgentResolverErrorDetail>;
|
|
50
52
|
constructor(code: AgentResolverErrorCode, message: string, detail?: AgentResolverErrorDetail, attackerInfluencedFields?: ReadonlyArray<keyof AgentResolverErrorDetail>);
|
|
51
53
|
}
|
|
@@ -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;
|
|
@@ -46,6 +46,8 @@ export interface AgentResolverErrorDetail {
|
|
|
46
46
|
export declare class AgentResolverError extends Error {
|
|
47
47
|
readonly code: AgentResolverErrorCode;
|
|
48
48
|
readonly detail: AgentResolverErrorDetail;
|
|
49
|
+
/** Local, cause-aware recovery. Wire codes retain the protocol taxonomy. */
|
|
50
|
+
readonly recovery: 'transient' | 'correctable' | 'terminal';
|
|
49
51
|
readonly [ATTACKER_INFLUENCED]: ReadonlyArray<keyof AgentResolverErrorDetail>;
|
|
50
52
|
constructor(code: AgentResolverErrorCode, message: string, detail?: AgentResolverErrorDetail, attackerInfluencedFields?: ReadonlyArray<keyof AgentResolverErrorDetail>);
|
|
51
53
|
}
|
|
@@ -23,16 +23,22 @@ __export(errors_exports, {
|
|
|
23
23
|
attackerInfluencedFields: () => attackerInfluencedFields
|
|
24
24
|
});
|
|
25
25
|
module.exports = __toCommonJS(errors_exports);
|
|
26
|
+
var import_fetch_helpers = require('./fetch-helpers.js');
|
|
27
|
+
var import_enums = require('../../types/enums.generated.js');
|
|
26
28
|
const ATTACKER_INFLUENCED = /* @__PURE__ */ Symbol.for("adcp.attacker-influenced");
|
|
27
29
|
class AgentResolverError extends Error {
|
|
28
30
|
code;
|
|
29
31
|
detail;
|
|
32
|
+
/** Local, cause-aware recovery. Wire codes retain the protocol taxonomy. */
|
|
33
|
+
recovery;
|
|
30
34
|
[ATTACKER_INFLUENCED];
|
|
31
35
|
constructor(code, message, detail = {}, attackerInfluencedFields2 = []) {
|
|
32
36
|
super(message);
|
|
33
37
|
this.name = "AgentResolverError";
|
|
34
38
|
this.code = code;
|
|
35
39
|
this.detail = detail;
|
|
40
|
+
const discovery = code === "request_signature_capabilities_unreachable" || code === "request_signature_brand_json_unreachable";
|
|
41
|
+
this.recovery = discovery && (0, import_fetch_helpers.isPermanentDiscoveryFailure)(detail) ? "terminal" : import_enums.RequestSigningErrorCodeMetadata[code].recovery;
|
|
36
42
|
this[ATTACKER_INFLUENCED] = attackerInfluencedFields2;
|
|
37
43
|
}
|
|
38
44
|
}
|
|
@@ -1,13 +1,19 @@
|
|
|
1
|
+
import { isPermanentDiscoveryFailure } from "./fetch-helpers.mjs";
|
|
2
|
+
import { RequestSigningErrorCodeMetadata } from "../../types/enums.generated.mjs";
|
|
1
3
|
const ATTACKER_INFLUENCED = /* @__PURE__ */ Symbol.for("adcp.attacker-influenced");
|
|
2
4
|
class AgentResolverError extends Error {
|
|
3
5
|
code;
|
|
4
6
|
detail;
|
|
7
|
+
/** Local, cause-aware recovery. Wire codes retain the protocol taxonomy. */
|
|
8
|
+
recovery;
|
|
5
9
|
[ATTACKER_INFLUENCED];
|
|
6
10
|
constructor(code, message, detail = {}, attackerInfluencedFields2 = []) {
|
|
7
11
|
super(message);
|
|
8
12
|
this.name = "AgentResolverError";
|
|
9
13
|
this.code = code;
|
|
10
14
|
this.detail = detail;
|
|
15
|
+
const discovery = code === "request_signature_capabilities_unreachable" || code === "request_signature_brand_json_unreachable";
|
|
16
|
+
this.recovery = discovery && isPermanentDiscoveryFailure(detail) ? "terminal" : RequestSigningErrorCodeMetadata[code].recovery;
|
|
11
17
|
this[ATTACKER_INFLUENCED] = attackerInfluencedFields2;
|
|
12
18
|
}
|
|
13
19
|
}
|
|
@@ -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,14 @@ 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>;
|
|
43
|
+
/** Coarse causes only: never expose messages, resolved addresses, or topology. */
|
|
44
|
+
export declare function classifyDiscoveryFailure(error: unknown): {
|
|
45
|
+
dns_error: SafeFetchError['transport'];
|
|
46
|
+
http_status?: number;
|
|
47
|
+
};
|
|
48
|
+
export declare function isPermanentDiscoveryFailure(detail: {
|
|
49
|
+
dns_error?: string;
|
|
50
|
+
http_status?: number;
|
|
51
|
+
}): boolean;
|
|
@@ -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,14 @@ 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>;
|
|
43
|
+
/** Coarse causes only: never expose messages, resolved addresses, or topology. */
|
|
44
|
+
export declare function classifyDiscoveryFailure(error: unknown): {
|
|
45
|
+
dns_error: SafeFetchError['transport'];
|
|
46
|
+
http_status?: number;
|
|
47
|
+
};
|
|
48
|
+
export declare function isPermanentDiscoveryFailure(detail: {
|
|
49
|
+
dns_error?: string;
|
|
50
|
+
http_status?: number;
|
|
51
|
+
}): boolean;
|
|
@@ -24,10 +24,13 @@ __export(fetch_helpers_exports, {
|
|
|
24
24
|
MAX_CAPABILITIES_BYTES: () => MAX_CAPABILITIES_BYTES,
|
|
25
25
|
MAX_JWKS_BYTES: () => MAX_JWKS_BYTES,
|
|
26
26
|
SafeFetchError: () => SafeFetchError,
|
|
27
|
+
classifyDiscoveryFailure: () => classifyDiscoveryFailure,
|
|
28
|
+
isPermanentDiscoveryFailure: () => isPermanentDiscoveryFailure,
|
|
27
29
|
safeFetchJson: () => safeFetchJson
|
|
28
30
|
});
|
|
29
31
|
module.exports = __toCommonJS(fetch_helpers_exports);
|
|
30
32
|
var import_net = require('../../net/index.js');
|
|
33
|
+
var import_agent_transport_fetch = require('../../net/agent-transport-fetch.js');
|
|
31
34
|
var import_strict_json = require('./strict-json.js');
|
|
32
35
|
const MAX_CAPABILITIES_BYTES = 65536;
|
|
33
36
|
const MAX_BRAND_JSON_BYTES = 262144;
|
|
@@ -52,14 +55,19 @@ async function safeFetchJson(url, kind, options) {
|
|
|
52
55
|
headers: { accept: "application/json" },
|
|
53
56
|
allowPrivateIp: options.allowPrivateIp === true,
|
|
54
57
|
timeoutMs: options.timeoutMs ?? DEFAULT_TOTAL_TIMEOUT_MS,
|
|
55
|
-
maxBodyBytes: options.maxBodyBytes
|
|
58
|
+
maxBodyBytes: options.maxBodyBytes,
|
|
59
|
+
lookup: options.lookup
|
|
56
60
|
};
|
|
57
61
|
let res;
|
|
58
62
|
try {
|
|
59
63
|
res = await (0, import_net.ssrfSafeFetch)(url, fetchOpts);
|
|
60
64
|
} catch (err) {
|
|
61
65
|
if (err instanceof import_net.SsrfRefusedError) {
|
|
62
|
-
throw new SafeFetchError(
|
|
66
|
+
throw new SafeFetchError(
|
|
67
|
+
kind,
|
|
68
|
+
import_net.SSRF_TRANSIENT_CODES.has(err.code) ? err.code === "body_exceeds_limit" ? "body_cap" : "dns_error" : "ssrf_refused",
|
|
69
|
+
`${kind} fetch refused: ${err.code}`
|
|
70
|
+
);
|
|
63
71
|
}
|
|
64
72
|
const message = err instanceof Error ? err.message : String(err);
|
|
65
73
|
if (/abort|timed?\s*out/i.test(message)) {
|
|
@@ -87,6 +95,31 @@ async function safeFetchJson(url, kind, options) {
|
|
|
87
95
|
fetchedAt: Math.floor(Date.now() / 1e3)
|
|
88
96
|
};
|
|
89
97
|
}
|
|
98
|
+
function classifyDiscoveryFailure(error) {
|
|
99
|
+
const seen = /* @__PURE__ */ new Set();
|
|
100
|
+
for (let depth = 0; error && typeof error === "object" && depth < 8 && !seen.has(error); depth++) {
|
|
101
|
+
seen.add(error);
|
|
102
|
+
if (error instanceof SafeFetchError)
|
|
103
|
+
return { dns_error: error.transport, ...error.httpStatus !== void 0 && { http_status: error.httpStatus } };
|
|
104
|
+
if (error instanceof import_agent_transport_fetch.AgentTransportPolicyError) return { dns_error: "ssrf_refused" };
|
|
105
|
+
if (error instanceof import_net.SsrfRefusedError)
|
|
106
|
+
return {
|
|
107
|
+
dns_error: import_net.SSRF_TRANSIENT_CODES.has(error.code) ? error.code === "body_exceeds_limit" ? "body_cap" : "dns_error" : "ssrf_refused"
|
|
108
|
+
};
|
|
109
|
+
const obj = error;
|
|
110
|
+
const status = obj.httpStatus ?? obj.status ?? obj.statusCode;
|
|
111
|
+
if (typeof status === "number" && status >= 400 && status <= 599)
|
|
112
|
+
return { dns_error: "fetch_failed", http_status: status };
|
|
113
|
+
if (obj.code === "ENOTFOUND" || obj.code === "EAI_AGAIN") return { dns_error: "dns_error" };
|
|
114
|
+
if (obj.name === "AbortError" || obj.name === "TimeoutError" || obj.code === "ETIMEDOUT" || typeof obj.code === "string" && obj.code.startsWith("UND_ERR_") && obj.code.endsWith("_TIMEOUT"))
|
|
115
|
+
return { dns_error: "timeout" };
|
|
116
|
+
error = obj.cause;
|
|
117
|
+
}
|
|
118
|
+
return { dns_error: "fetch_failed" };
|
|
119
|
+
}
|
|
120
|
+
function isPermanentDiscoveryFailure(detail) {
|
|
121
|
+
return detail.dns_error === "ssrf_refused" || detail.http_status !== void 0 && detail.http_status >= 400 && detail.http_status < 500;
|
|
122
|
+
}
|
|
90
123
|
// Annotate the CommonJS export names for ESM import in node:
|
|
91
124
|
0 && (module.exports = {
|
|
92
125
|
DEFAULT_CONNECT_TIMEOUT_MS,
|
|
@@ -95,5 +128,7 @@ async function safeFetchJson(url, kind, options) {
|
|
|
95
128
|
MAX_CAPABILITIES_BYTES,
|
|
96
129
|
MAX_JWKS_BYTES,
|
|
97
130
|
SafeFetchError,
|
|
131
|
+
classifyDiscoveryFailure,
|
|
132
|
+
isPermanentDiscoveryFailure,
|
|
98
133
|
safeFetchJson
|
|
99
134
|
});
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ssrfSafeFetch,
|
|
3
|
+
SsrfRefusedError,
|
|
4
|
+
SSRF_TRANSIENT_CODES
|
|
5
|
+
} from "../../net/index.mjs";
|
|
6
|
+
import { AgentTransportPolicyError } from "../../net/agent-transport-fetch.mjs";
|
|
2
7
|
import { parseStrictJson, StrictJsonError } from "./strict-json.mjs";
|
|
3
8
|
const MAX_CAPABILITIES_BYTES = 65536;
|
|
4
9
|
const MAX_BRAND_JSON_BYTES = 262144;
|
|
@@ -23,14 +28,19 @@ async function safeFetchJson(url, kind, options) {
|
|
|
23
28
|
headers: { accept: "application/json" },
|
|
24
29
|
allowPrivateIp: options.allowPrivateIp === true,
|
|
25
30
|
timeoutMs: options.timeoutMs ?? DEFAULT_TOTAL_TIMEOUT_MS,
|
|
26
|
-
maxBodyBytes: options.maxBodyBytes
|
|
31
|
+
maxBodyBytes: options.maxBodyBytes,
|
|
32
|
+
lookup: options.lookup
|
|
27
33
|
};
|
|
28
34
|
let res;
|
|
29
35
|
try {
|
|
30
36
|
res = await ssrfSafeFetch(url, fetchOpts);
|
|
31
37
|
} catch (err) {
|
|
32
38
|
if (err instanceof SsrfRefusedError) {
|
|
33
|
-
throw new SafeFetchError(
|
|
39
|
+
throw new SafeFetchError(
|
|
40
|
+
kind,
|
|
41
|
+
SSRF_TRANSIENT_CODES.has(err.code) ? err.code === "body_exceeds_limit" ? "body_cap" : "dns_error" : "ssrf_refused",
|
|
42
|
+
`${kind} fetch refused: ${err.code}`
|
|
43
|
+
);
|
|
34
44
|
}
|
|
35
45
|
const message = err instanceof Error ? err.message : String(err);
|
|
36
46
|
if (/abort|timed?\s*out/i.test(message)) {
|
|
@@ -58,6 +68,31 @@ async function safeFetchJson(url, kind, options) {
|
|
|
58
68
|
fetchedAt: Math.floor(Date.now() / 1e3)
|
|
59
69
|
};
|
|
60
70
|
}
|
|
71
|
+
function classifyDiscoveryFailure(error) {
|
|
72
|
+
const seen = /* @__PURE__ */ new Set();
|
|
73
|
+
for (let depth = 0; error && typeof error === "object" && depth < 8 && !seen.has(error); depth++) {
|
|
74
|
+
seen.add(error);
|
|
75
|
+
if (error instanceof SafeFetchError)
|
|
76
|
+
return { dns_error: error.transport, ...error.httpStatus !== void 0 && { http_status: error.httpStatus } };
|
|
77
|
+
if (error instanceof AgentTransportPolicyError) return { dns_error: "ssrf_refused" };
|
|
78
|
+
if (error instanceof SsrfRefusedError)
|
|
79
|
+
return {
|
|
80
|
+
dns_error: SSRF_TRANSIENT_CODES.has(error.code) ? error.code === "body_exceeds_limit" ? "body_cap" : "dns_error" : "ssrf_refused"
|
|
81
|
+
};
|
|
82
|
+
const obj = error;
|
|
83
|
+
const status = obj.httpStatus ?? obj.status ?? obj.statusCode;
|
|
84
|
+
if (typeof status === "number" && status >= 400 && status <= 599)
|
|
85
|
+
return { dns_error: "fetch_failed", http_status: status };
|
|
86
|
+
if (obj.code === "ENOTFOUND" || obj.code === "EAI_AGAIN") return { dns_error: "dns_error" };
|
|
87
|
+
if (obj.name === "AbortError" || obj.name === "TimeoutError" || obj.code === "ETIMEDOUT" || typeof obj.code === "string" && obj.code.startsWith("UND_ERR_") && obj.code.endsWith("_TIMEOUT"))
|
|
88
|
+
return { dns_error: "timeout" };
|
|
89
|
+
error = obj.cause;
|
|
90
|
+
}
|
|
91
|
+
return { dns_error: "fetch_failed" };
|
|
92
|
+
}
|
|
93
|
+
function isPermanentDiscoveryFailure(detail) {
|
|
94
|
+
return detail.dns_error === "ssrf_refused" || detail.http_status !== void 0 && detail.http_status >= 400 && detail.http_status < 500;
|
|
95
|
+
}
|
|
61
96
|
export {
|
|
62
97
|
DEFAULT_CONNECT_TIMEOUT_MS,
|
|
63
98
|
DEFAULT_TOTAL_TIMEOUT_MS,
|
|
@@ -65,5 +100,7 @@ export {
|
|
|
65
100
|
MAX_CAPABILITIES_BYTES,
|
|
66
101
|
MAX_JWKS_BYTES,
|
|
67
102
|
SafeFetchError,
|
|
103
|
+
classifyDiscoveryFailure,
|
|
104
|
+
isPermanentDiscoveryFailure,
|
|
68
105
|
safeFetchJson
|
|
69
106
|
};
|
|
@@ -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 =
|
|
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 >=
|
|
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 =
|
|
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 >=
|
|
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
|
+
}>;
|