@adcp/sdk 14.0.0-beta.14 → 14.0.0-beta.15
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/auth/oauth/authorization-required.d.mts +25 -11
- package/dist/lib/auth/oauth/authorization-required.d.ts +25 -11
- package/dist/lib/auth/oauth/authorization-required.js +18 -4
- package/dist/lib/auth/oauth/authorization-required.mjs +17 -4
- package/dist/lib/auth/oauth/index.d.mts +1 -1
- package/dist/lib/auth/oauth/index.d.ts +1 -1
- package/dist/lib/auth/oauth/index.js +2 -0
- package/dist/lib/auth/oauth/index.mjs +2 -0
- package/dist/lib/auth/oauth/resource-url.d.mts +8 -0
- package/dist/lib/auth/oauth/resource-url.d.ts +8 -0
- package/dist/lib/auth/oauth/resource-url.js +42 -0
- package/dist/lib/auth/oauth/resource-url.mjs +40 -0
- package/dist/lib/core/ConversationTypes.d.mts +10 -0
- package/dist/lib/core/ConversationTypes.d.ts +10 -0
- package/dist/lib/core/SingleAgentClient.d.mts +5 -2
- package/dist/lib/core/SingleAgentClient.d.ts +5 -2
- package/dist/lib/core/SingleAgentClient.js +133 -28
- package/dist/lib/core/SingleAgentClient.mjs +138 -29
- package/dist/lib/core/TaskExecutor.d.mts +1 -0
- package/dist/lib/core/TaskExecutor.d.ts +1 -0
- package/dist/lib/core/TaskExecutor.js +7 -1
- package/dist/lib/core/TaskExecutor.mjs +7 -1
- package/dist/lib/core/webhook-registration.d.mts +8 -1
- package/dist/lib/core/webhook-registration.d.ts +8 -1
- package/dist/lib/core/webhook-registration.js +65 -5
- package/dist/lib/core/webhook-registration.mjs +61 -4
- package/dist/lib/errors/index.d.mts +9 -0
- package/dist/lib/errors/index.d.ts +9 -0
- package/dist/lib/errors/index.js +33 -0
- package/dist/lib/errors/index.mjs +32 -0
- package/dist/lib/index.d.mts +3 -2
- package/dist/lib/index.d.ts +3 -2
- package/dist/lib/index.js +4 -0
- package/dist/lib/index.mjs +4 -0
- package/dist/lib/media-buy/compatibility.js +14 -2
- package/dist/lib/media-buy/compatibility.mjs +14 -2
- package/dist/lib/protocols/index.js +23 -7
- package/dist/lib/protocols/index.mjs +24 -8
- package/dist/lib/protocols/mcp.js +8 -6
- package/dist/lib/protocols/mcp.mjs +9 -7
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/server/decisioning/async-outcome.d.mts +11 -0
- package/dist/lib/server/decisioning/async-outcome.d.ts +11 -0
- package/dist/lib/server/decisioning/context.d.mts +11 -1
- package/dist/lib/server/decisioning/context.d.ts +11 -1
- package/dist/lib/server/decisioning/index.d.mts +3 -2
- package/dist/lib/server/decisioning/index.d.ts +3 -2
- package/dist/lib/server/decisioning/index.js +9 -0
- package/dist/lib/server/decisioning/index.mjs +10 -0
- package/dist/lib/server/decisioning/runtime/from-platform.d.mts +5 -2
- package/dist/lib/server/decisioning/runtime/from-platform.d.ts +5 -2
- package/dist/lib/server/decisioning/runtime/from-platform.js +40 -8
- package/dist/lib/server/decisioning/runtime/from-platform.mjs +40 -8
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.mts +8 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.d.ts +8 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.js +10 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-registry.mjs +9 -1
- package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.mts +79 -0
- package/dist/lib/server/decisioning/runtime/postgres-task-settlement.d.ts +79 -0
- package/dist/lib/server/decisioning/runtime/postgres-task-settlement.js +391 -0
- package/dist/lib/server/decisioning/runtime/postgres-task-settlement.mjs +369 -0
- package/dist/lib/server/decisioning/runtime/task-registry.d.mts +2 -0
- package/dist/lib/server/decisioning/runtime/task-registry.d.ts +2 -0
- package/dist/lib/server/decisioning/runtime/task-registry.js +2 -1
- package/dist/lib/server/decisioning/runtime/task-registry.mjs +2 -1
- package/dist/lib/server/decisioning/runtime/to-context.js +15 -11
- package/dist/lib/server/decisioning/runtime/to-context.mjs +15 -11
- package/dist/lib/server/index.d.mts +2 -2
- package/dist/lib/server/index.d.ts +2 -2
- package/dist/lib/server/index.js +4 -0
- package/dist/lib/server/index.mjs +4 -0
- package/dist/lib/server/webhook-delivery/index.d.mts +2 -2
- package/dist/lib/server/webhook-delivery/index.d.ts +2 -2
- package/dist/lib/server/webhook-delivery/index.js +4 -0
- package/dist/lib/server/webhook-delivery/index.mjs +5 -1
- package/dist/lib/server/webhook-delivery/pg.d.mts +3 -1
- package/dist/lib/server/webhook-delivery/pg.d.ts +3 -1
- package/dist/lib/server/webhook-delivery/pg.js +25 -2
- package/dist/lib/server/webhook-delivery/pg.mjs +25 -2
- package/dist/lib/server/webhook-delivery/recovery.d.mts +44 -0
- package/dist/lib/server/webhook-delivery/recovery.d.ts +44 -0
- package/dist/lib/server/webhook-delivery/recovery.js +146 -43
- package/dist/lib/server/webhook-delivery/recovery.mjs +144 -43
- package/dist/lib/signing/agent-resolver/index.d.mts +1 -1
- package/dist/lib/signing/agent-resolver/index.d.ts +1 -1
- package/dist/lib/signing/agent-resolver/resolve-agent.d.mts +9 -0
- package/dist/lib/signing/agent-resolver/resolve-agent.d.ts +9 -0
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +4 -1
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +4 -1
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +17 -4
- package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +17 -4
- package/dist/lib/signing/jwks.d.mts +7 -0
- package/dist/lib/signing/jwks.d.ts +7 -0
- package/dist/lib/signing/server.d.mts +2 -2
- package/dist/lib/signing/server.d.ts +2 -2
- package/dist/lib/signing/webhook-verifier.d.mts +6 -0
- package/dist/lib/signing/webhook-verifier.d.ts +6 -0
- package/dist/lib/signing/webhook-verifier.js +38 -4
- package/dist/lib/signing/webhook-verifier.mjs +38 -4
- package/dist/lib/testing/client.d.mts +1 -0
- package/dist/lib/testing/client.d.ts +1 -0
- package/dist/lib/testing/client.js +6 -2
- package/dist/lib/testing/client.mjs +6 -2
- package/dist/lib/testing/compliance/comply.d.mts +2 -2
- package/dist/lib/testing/compliance/comply.d.ts +2 -2
- package/dist/lib/testing/compliance/comply.js +41 -31
- package/dist/lib/testing/compliance/comply.mjs +44 -21
- package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.mts +1 -7
- package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.d.ts +1 -7
- package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.js +6 -42
- package/dist/lib/testing/storyboard/oauth-metadata-graph/grader.mjs +10 -40
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/utils/adcp-version-config.d.mts +2 -0
- package/dist/lib/utils/adcp-version-config.d.ts +2 -0
- package/dist/lib/utils/adcp-version-config.js +5 -0
- package/dist/lib/utils/adcp-version-config.mjs +4 -0
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/llms.txt +3 -1
- package/docs/migration-12-to-14.md +6 -5
- package/docs/migration-13-to-14.md +48 -7
- package/docs/migration-task-registry-scoping.md +164 -11
- package/package.json +1 -1
- package/skills/build-decisioning-platform/advanced/REFERENCE.md +1 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AuthenticationRequiredError } from '../../errors/index.mjs';
|
|
2
2
|
import { type WWWAuthenticateChallenge } from './diagnostics.mjs';
|
|
3
3
|
/**
|
|
4
|
-
* Structured
|
|
5
|
-
*
|
|
6
|
-
* {@link
|
|
4
|
+
* Structured result from a Bearer challenge and its available discovery
|
|
5
|
+
* metadata. Records may be partial; use
|
|
6
|
+
* {@link hasValidatedMcpAuthorizationRequirements} before treating one as
|
|
7
|
+
* proof that an MCP endpoint requires OAuth.
|
|
7
8
|
*/
|
|
8
9
|
export interface AuthorizationRequirements {
|
|
9
10
|
/** The agent URL we probed. */
|
|
@@ -62,12 +63,12 @@ export interface AuthorizationRequirements {
|
|
|
62
63
|
* `instanceof NeedsAuthorizationError` for type-narrowing and use `subCode`
|
|
63
64
|
* only for structured-log keying.
|
|
64
65
|
*
|
|
65
|
-
* Note on `hasOAuth`:
|
|
66
|
+
* Note on validation and `hasOAuth`:
|
|
66
67
|
* The inherited getter returns `true` only when both `authorization_endpoint`
|
|
67
68
|
* and `token_endpoint` were walked successfully. A partially-walked
|
|
68
|
-
* requirements record
|
|
69
|
-
*
|
|
70
|
-
*
|
|
69
|
+
* requirements record still yields `hasOAuth === false`. Callers should
|
|
70
|
+
* construct this error only after
|
|
71
|
+
* {@link hasValidatedMcpAuthorizationRequirements} succeeds.
|
|
71
72
|
*/
|
|
72
73
|
export declare class NeedsAuthorizationError extends AuthenticationRequiredError {
|
|
73
74
|
/** Narrow discriminator for consumers that already know about this class. */
|
|
@@ -95,14 +96,17 @@ export interface DiscoverAuthorizationOptions {
|
|
|
95
96
|
wwwAuthenticate?: string;
|
|
96
97
|
}
|
|
97
98
|
/**
|
|
98
|
-
* Walk the OAuth discovery chain starting from an agent URL. Returns
|
|
99
|
-
* `AuthorizationRequirements`
|
|
100
|
-
* `
|
|
99
|
+
* Walk the OAuth discovery chain starting from an agent URL. Returns an
|
|
100
|
+
* `AuthorizationRequirements` diagnostic record for a Bearer challenge (even
|
|
101
|
+
* when later metadata is absent), or `null` when the probe is not a Bearer
|
|
102
|
+
* 401. Use {@link hasValidatedMcpAuthorizationRequirements} before promoting
|
|
103
|
+
* the record to an interactive OAuth requirement.
|
|
101
104
|
*
|
|
102
105
|
* Strategy:
|
|
103
106
|
* 1. POST `tools/list` to the agent with no `Authorization` header.
|
|
104
107
|
* 2. If 401 + `WWW-Authenticate: Bearer`: parse the challenge.
|
|
105
|
-
* 3.
|
|
108
|
+
* 3. Resolve `resource_metadata=…`, or the RFC 9728 well-known fallback,
|
|
109
|
+
* then GET it and read
|
|
106
110
|
* `resource` + `authorization_servers`.
|
|
107
111
|
* 4. For the first `authorization_servers[0]`: GET `/.well-known/oauth-authorization-server`
|
|
108
112
|
* and read `authorization_endpoint`, `token_endpoint`, `registration_endpoint`,
|
|
@@ -113,6 +117,16 @@ export interface DiscoverAuthorizationOptions {
|
|
|
113
117
|
* callers can still present a partial picture without re-probing.
|
|
114
118
|
*/
|
|
115
119
|
export declare function discoverAuthorizationRequirements(agentUrl: string, options?: DiscoverAuthorizationOptions): Promise<AuthorizationRequirements | null>;
|
|
120
|
+
/**
|
|
121
|
+
* Whether a discovery record proves the MCP endpoint is OAuth protected.
|
|
122
|
+
*
|
|
123
|
+
* `discoverAuthorizationRequirements` intentionally returns partial records
|
|
124
|
+
* for diagnostics. Those records are not sufficient evidence for an
|
|
125
|
+
* interactive OAuth prompt: the MCP authorization profile requires protected
|
|
126
|
+
* resource metadata whose `resource` exactly identifies the endpoint and
|
|
127
|
+
* which names at least one authorization server.
|
|
128
|
+
*/
|
|
129
|
+
export declare function hasValidatedMcpAuthorizationRequirements(requirements: AuthorizationRequirements, agentUrl: string): boolean;
|
|
116
130
|
/**
|
|
117
131
|
* Probe the agent for the parsed `WWW-Authenticate` challenge on a 401.
|
|
118
132
|
*
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { AuthenticationRequiredError } from '../../errors';
|
|
2
2
|
import { type WWWAuthenticateChallenge } from './diagnostics';
|
|
3
3
|
/**
|
|
4
|
-
* Structured
|
|
5
|
-
*
|
|
6
|
-
* {@link
|
|
4
|
+
* Structured result from a Bearer challenge and its available discovery
|
|
5
|
+
* metadata. Records may be partial; use
|
|
6
|
+
* {@link hasValidatedMcpAuthorizationRequirements} before treating one as
|
|
7
|
+
* proof that an MCP endpoint requires OAuth.
|
|
7
8
|
*/
|
|
8
9
|
export interface AuthorizationRequirements {
|
|
9
10
|
/** The agent URL we probed. */
|
|
@@ -62,12 +63,12 @@ export interface AuthorizationRequirements {
|
|
|
62
63
|
* `instanceof NeedsAuthorizationError` for type-narrowing and use `subCode`
|
|
63
64
|
* only for structured-log keying.
|
|
64
65
|
*
|
|
65
|
-
* Note on `hasOAuth`:
|
|
66
|
+
* Note on validation and `hasOAuth`:
|
|
66
67
|
* The inherited getter returns `true` only when both `authorization_endpoint`
|
|
67
68
|
* and `token_endpoint` were walked successfully. A partially-walked
|
|
68
|
-
* requirements record
|
|
69
|
-
*
|
|
70
|
-
*
|
|
69
|
+
* requirements record still yields `hasOAuth === false`. Callers should
|
|
70
|
+
* construct this error only after
|
|
71
|
+
* {@link hasValidatedMcpAuthorizationRequirements} succeeds.
|
|
71
72
|
*/
|
|
72
73
|
export declare class NeedsAuthorizationError extends AuthenticationRequiredError {
|
|
73
74
|
/** Narrow discriminator for consumers that already know about this class. */
|
|
@@ -95,14 +96,17 @@ export interface DiscoverAuthorizationOptions {
|
|
|
95
96
|
wwwAuthenticate?: string;
|
|
96
97
|
}
|
|
97
98
|
/**
|
|
98
|
-
* Walk the OAuth discovery chain starting from an agent URL. Returns
|
|
99
|
-
* `AuthorizationRequirements`
|
|
100
|
-
* `
|
|
99
|
+
* Walk the OAuth discovery chain starting from an agent URL. Returns an
|
|
100
|
+
* `AuthorizationRequirements` diagnostic record for a Bearer challenge (even
|
|
101
|
+
* when later metadata is absent), or `null` when the probe is not a Bearer
|
|
102
|
+
* 401. Use {@link hasValidatedMcpAuthorizationRequirements} before promoting
|
|
103
|
+
* the record to an interactive OAuth requirement.
|
|
101
104
|
*
|
|
102
105
|
* Strategy:
|
|
103
106
|
* 1. POST `tools/list` to the agent with no `Authorization` header.
|
|
104
107
|
* 2. If 401 + `WWW-Authenticate: Bearer`: parse the challenge.
|
|
105
|
-
* 3.
|
|
108
|
+
* 3. Resolve `resource_metadata=…`, or the RFC 9728 well-known fallback,
|
|
109
|
+
* then GET it and read
|
|
106
110
|
* `resource` + `authorization_servers`.
|
|
107
111
|
* 4. For the first `authorization_servers[0]`: GET `/.well-known/oauth-authorization-server`
|
|
108
112
|
* and read `authorization_endpoint`, `token_endpoint`, `registration_endpoint`,
|
|
@@ -113,6 +117,16 @@ export interface DiscoverAuthorizationOptions {
|
|
|
113
117
|
* callers can still present a partial picture without re-probing.
|
|
114
118
|
*/
|
|
115
119
|
export declare function discoverAuthorizationRequirements(agentUrl: string, options?: DiscoverAuthorizationOptions): Promise<AuthorizationRequirements | null>;
|
|
120
|
+
/**
|
|
121
|
+
* Whether a discovery record proves the MCP endpoint is OAuth protected.
|
|
122
|
+
*
|
|
123
|
+
* `discoverAuthorizationRequirements` intentionally returns partial records
|
|
124
|
+
* for diagnostics. Those records are not sufficient evidence for an
|
|
125
|
+
* interactive OAuth prompt: the MCP authorization profile requires protected
|
|
126
|
+
* resource metadata whose `resource` exactly identifies the endpoint and
|
|
127
|
+
* which names at least one authorization server.
|
|
128
|
+
*/
|
|
129
|
+
export declare function hasValidatedMcpAuthorizationRequirements(requirements: AuthorizationRequirements, agentUrl: string): boolean;
|
|
116
130
|
/**
|
|
117
131
|
* Probe the agent for the parsed `WWW-Authenticate` challenge on a 401.
|
|
118
132
|
*
|
|
@@ -20,6 +20,7 @@ var authorization_required_exports = {};
|
|
|
20
20
|
__export(authorization_required_exports, {
|
|
21
21
|
NeedsAuthorizationError: () => NeedsAuthorizationError,
|
|
22
22
|
discoverAuthorizationRequirements: () => discoverAuthorizationRequirements,
|
|
23
|
+
hasValidatedMcpAuthorizationRequirements: () => hasValidatedMcpAuthorizationRequirements,
|
|
23
24
|
probeAuthChallenge: () => probeAuthChallenge
|
|
24
25
|
});
|
|
25
26
|
module.exports = __toCommonJS(authorization_required_exports);
|
|
@@ -27,6 +28,7 @@ var import_net = require('../../net/index.js');
|
|
|
27
28
|
var import_errors = require('../../errors/index.js');
|
|
28
29
|
var import_abort = require('../../protocols/abort.js');
|
|
29
30
|
var import_diagnostics = require('./diagnostics.js');
|
|
31
|
+
var import_resource_url = require('./resource-url.js');
|
|
30
32
|
const MAX_DISPLAY_STRING = 256;
|
|
31
33
|
const MAX_SCOPES = 64;
|
|
32
34
|
const MAX_CHALLENGE_PARAMS = 32;
|
|
@@ -106,14 +108,22 @@ async function discoverAuthorizationRequirements(agentUrl, options = {}) {
|
|
|
106
108
|
}
|
|
107
109
|
const requirements = {
|
|
108
110
|
agentUrl,
|
|
109
|
-
resourceMetadataUrl: challenge.resource_metadata ? sanitizeDisplay(challenge.resource_metadata) : void 0,
|
|
110
111
|
challengeScope: challenge.scope ? sanitizeDisplay(challenge.scope) : void 0,
|
|
111
112
|
challenge: sanitizeChallenge(challenge)
|
|
112
113
|
};
|
|
113
|
-
|
|
114
|
+
let resourceMetadataUrl = challenge.resource_metadata;
|
|
115
|
+
if (!resourceMetadataUrl) {
|
|
116
|
+
try {
|
|
117
|
+
resourceMetadataUrl = (0, import_resource_url.buildProtectedResourceMetadataUrl)(agentUrl);
|
|
118
|
+
} catch {
|
|
119
|
+
resourceMetadataUrl = void 0;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (resourceMetadataUrl) requirements.resourceMetadataUrl = sanitizeDisplay(resourceMetadataUrl);
|
|
123
|
+
if (resourceMetadataUrl && isSafeHttpUrl(resourceMetadataUrl)) {
|
|
114
124
|
const prm = await fetchJson(
|
|
115
|
-
|
|
116
|
-
allowPrivateIpForHop(
|
|
125
|
+
resourceMetadataUrl,
|
|
126
|
+
allowPrivateIpForHop(resourceMetadataUrl),
|
|
117
127
|
options.timeoutMs,
|
|
118
128
|
options.fetchFn,
|
|
119
129
|
options.signal
|
|
@@ -187,6 +197,9 @@ async function discoverAuthorizationRequirements(agentUrl, options = {}) {
|
|
|
187
197
|
}
|
|
188
198
|
return requirements;
|
|
189
199
|
}
|
|
200
|
+
function hasValidatedMcpAuthorizationRequirements(requirements, agentUrl) {
|
|
201
|
+
return (0, import_resource_url.normalizeOAuthResourceForComparison)(requirements.resource ?? "") === (0, import_resource_url.normalizeOAuthResourceForComparison)(agentUrl) && Array.isArray(requirements.authorizationServers) && requirements.authorizationServers.length > 0;
|
|
202
|
+
}
|
|
190
203
|
async function probeAuthChallenge(agentUrl, options = {}) {
|
|
191
204
|
const probe = await probeAgent401(
|
|
192
205
|
agentUrl,
|
|
@@ -267,5 +280,6 @@ async function fetchJson(url, allowPrivateIp, timeoutMs, fetchFn, signal) {
|
|
|
267
280
|
0 && (module.exports = {
|
|
268
281
|
NeedsAuthorizationError,
|
|
269
282
|
discoverAuthorizationRequirements,
|
|
283
|
+
hasValidatedMcpAuthorizationRequirements,
|
|
270
284
|
probeAuthChallenge
|
|
271
285
|
});
|
|
@@ -2,6 +2,7 @@ import { ssrfSafeFetch, decodeBodyAsJsonOrText } from "../../net/index.mjs";
|
|
|
2
2
|
import { AuthenticationRequiredError } from "../../errors/index.mjs";
|
|
3
3
|
import { throwIfAborted } from "../../protocols/abort.mjs";
|
|
4
4
|
import { parseWWWAuthenticate } from "./diagnostics.mjs";
|
|
5
|
+
import { buildProtectedResourceMetadataUrl, normalizeOAuthResourceForComparison } from "./resource-url.mjs";
|
|
5
6
|
const MAX_DISPLAY_STRING = 256;
|
|
6
7
|
const MAX_SCOPES = 64;
|
|
7
8
|
const MAX_CHALLENGE_PARAMS = 32;
|
|
@@ -81,14 +82,22 @@ async function discoverAuthorizationRequirements(agentUrl, options = {}) {
|
|
|
81
82
|
}
|
|
82
83
|
const requirements = {
|
|
83
84
|
agentUrl,
|
|
84
|
-
resourceMetadataUrl: challenge.resource_metadata ? sanitizeDisplay(challenge.resource_metadata) : void 0,
|
|
85
85
|
challengeScope: challenge.scope ? sanitizeDisplay(challenge.scope) : void 0,
|
|
86
86
|
challenge: sanitizeChallenge(challenge)
|
|
87
87
|
};
|
|
88
|
-
|
|
88
|
+
let resourceMetadataUrl = challenge.resource_metadata;
|
|
89
|
+
if (!resourceMetadataUrl) {
|
|
90
|
+
try {
|
|
91
|
+
resourceMetadataUrl = buildProtectedResourceMetadataUrl(agentUrl);
|
|
92
|
+
} catch {
|
|
93
|
+
resourceMetadataUrl = void 0;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (resourceMetadataUrl) requirements.resourceMetadataUrl = sanitizeDisplay(resourceMetadataUrl);
|
|
97
|
+
if (resourceMetadataUrl && isSafeHttpUrl(resourceMetadataUrl)) {
|
|
89
98
|
const prm = await fetchJson(
|
|
90
|
-
|
|
91
|
-
allowPrivateIpForHop(
|
|
99
|
+
resourceMetadataUrl,
|
|
100
|
+
allowPrivateIpForHop(resourceMetadataUrl),
|
|
92
101
|
options.timeoutMs,
|
|
93
102
|
options.fetchFn,
|
|
94
103
|
options.signal
|
|
@@ -162,6 +171,9 @@ async function discoverAuthorizationRequirements(agentUrl, options = {}) {
|
|
|
162
171
|
}
|
|
163
172
|
return requirements;
|
|
164
173
|
}
|
|
174
|
+
function hasValidatedMcpAuthorizationRequirements(requirements, agentUrl) {
|
|
175
|
+
return normalizeOAuthResourceForComparison(requirements.resource ?? "") === normalizeOAuthResourceForComparison(agentUrl) && Array.isArray(requirements.authorizationServers) && requirements.authorizationServers.length > 0;
|
|
176
|
+
}
|
|
165
177
|
async function probeAuthChallenge(agentUrl, options = {}) {
|
|
166
178
|
const probe = await probeAgent401(
|
|
167
179
|
agentUrl,
|
|
@@ -241,5 +253,6 @@ async function fetchJson(url, allowPrivateIp, timeoutMs, fetchFn, signal) {
|
|
|
241
253
|
export {
|
|
242
254
|
NeedsAuthorizationError,
|
|
243
255
|
discoverAuthorizationRequirements,
|
|
256
|
+
hasValidatedMcpAuthorizationRequirements,
|
|
244
257
|
probeAuthChallenge
|
|
245
258
|
};
|
|
@@ -138,7 +138,7 @@ export declare function getEffectiveAuthToken(agent: AgentConfig): string | unde
|
|
|
138
138
|
export { discoverOAuthMetadata, supportsOAuth, supportsDynamicRegistration, type OAuthMetadata, type DiscoveryOptions, } from './discovery.mjs';
|
|
139
139
|
export { parseWWWAuthenticate, decodeAccessTokenClaims, validateTokenAudience, type WWWAuthenticateChallenge, type DecodedJWTHeader, type DecodedJWTClaims, type DecodedAccessToken, type TokenAudienceResult, } from './diagnostics.mjs';
|
|
140
140
|
export { runAuthDiagnosis, AUTH_DIAGNOSIS_SCHEMA_VERSION, type DiagnoseOptions, type HttpCapture, type DiagnosisStep, type Hypothesis, type HypothesisVerdict, type AuthDiagnosisReport, } from './diagnose.mjs';
|
|
141
|
-
export { NeedsAuthorizationError, discoverAuthorizationRequirements, probeAuthChallenge, type AuthorizationRequirements, type DiscoverAuthorizationOptions, } from './authorization-required.mjs';
|
|
141
|
+
export { NeedsAuthorizationError, discoverAuthorizationRequirements, hasValidatedMcpAuthorizationRequirements, probeAuthChallenge, type AuthorizationRequirements, type DiscoverAuthorizationOptions, } from './authorization-required.mjs';
|
|
142
142
|
export { createFileOAuthStorage, type FileOAuthStorageOptions } from './file-storage.mjs';
|
|
143
143
|
export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, } from './ClientCredentialsFlow.mjs';
|
|
144
144
|
export { resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, MissingEnvSecretError, } from './secret-resolver.mjs';
|
|
@@ -138,7 +138,7 @@ export declare function getEffectiveAuthToken(agent: AgentConfig): string | unde
|
|
|
138
138
|
export { discoverOAuthMetadata, supportsOAuth, supportsDynamicRegistration, type OAuthMetadata, type DiscoveryOptions, } from './discovery';
|
|
139
139
|
export { parseWWWAuthenticate, decodeAccessTokenClaims, validateTokenAudience, type WWWAuthenticateChallenge, type DecodedJWTHeader, type DecodedJWTClaims, type DecodedAccessToken, type TokenAudienceResult, } from './diagnostics';
|
|
140
140
|
export { runAuthDiagnosis, AUTH_DIAGNOSIS_SCHEMA_VERSION, type DiagnoseOptions, type HttpCapture, type DiagnosisStep, type Hypothesis, type HypothesisVerdict, type AuthDiagnosisReport, } from './diagnose';
|
|
141
|
-
export { NeedsAuthorizationError, discoverAuthorizationRequirements, probeAuthChallenge, type AuthorizationRequirements, type DiscoverAuthorizationOptions, } from './authorization-required';
|
|
141
|
+
export { NeedsAuthorizationError, discoverAuthorizationRequirements, hasValidatedMcpAuthorizationRequirements, probeAuthChallenge, type AuthorizationRequirements, type DiscoverAuthorizationOptions, } from './authorization-required';
|
|
142
142
|
export { createFileOAuthStorage, type FileOAuthStorageOptions } from './file-storage';
|
|
143
143
|
export { exchangeClientCredentials, ensureClientCredentialsTokens, ClientCredentialsExchangeError, type ExchangeClientCredentialsOptions, type EnsureClientCredentialsOptions, } from './ClientCredentialsFlow';
|
|
144
144
|
export { resolveSecret, isEnvSecretReference, toEnvSecretReference, extractEnvSecretName, MissingEnvSecretError, } from './secret-resolver';
|
|
@@ -58,6 +58,7 @@ __export(oauth_exports, {
|
|
|
58
58
|
getAgentStorage: () => import_storage_registry.getAgentStorage,
|
|
59
59
|
getEffectiveAuthToken: () => getEffectiveAuthToken,
|
|
60
60
|
hasValidOAuthTokens: () => hasValidOAuthTokens,
|
|
61
|
+
hasValidatedMcpAuthorizationRequirements: () => import_authorization_required.hasValidatedMcpAuthorizationRequirements,
|
|
61
62
|
isEnvSecretReference: () => import_secret_resolver.isEnvSecretReference,
|
|
62
63
|
isOAuthRequired: () => isOAuthRequired,
|
|
63
64
|
parseWWWAuthenticate: () => import_diagnostics.parseWWWAuthenticate,
|
|
@@ -204,6 +205,7 @@ function getEffectiveAuthToken(agent) {
|
|
|
204
205
|
getAgentStorage,
|
|
205
206
|
getEffectiveAuthToken,
|
|
206
207
|
hasValidOAuthTokens,
|
|
208
|
+
hasValidatedMcpAuthorizationRequirements,
|
|
207
209
|
isEnvSecretReference,
|
|
208
210
|
isOAuthRequired,
|
|
209
211
|
parseWWWAuthenticate,
|
|
@@ -116,6 +116,7 @@ import {
|
|
|
116
116
|
import {
|
|
117
117
|
NeedsAuthorizationError,
|
|
118
118
|
discoverAuthorizationRequirements,
|
|
119
|
+
hasValidatedMcpAuthorizationRequirements,
|
|
119
120
|
probeAuthChallenge
|
|
120
121
|
} from "./authorization-required.mjs";
|
|
121
122
|
import { createFileOAuthStorage } from "./file-storage.mjs";
|
|
@@ -174,6 +175,7 @@ export {
|
|
|
174
175
|
getAgentStorage,
|
|
175
176
|
getEffectiveAuthToken,
|
|
176
177
|
hasValidOAuthTokens,
|
|
178
|
+
hasValidatedMcpAuthorizationRequirements,
|
|
177
179
|
isEnvSecretReference,
|
|
178
180
|
isOAuthRequired,
|
|
179
181
|
parseWWWAuthenticate,
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 9728 resource comparison semantics used by OAuth discovery and
|
|
3
|
+
* compliance grading. Scheme and host are case-insensitive and default ports
|
|
4
|
+
* are equivalent; the remainder stays byte-for-byte significant.
|
|
5
|
+
*/
|
|
6
|
+
export declare function normalizeOAuthResourceForComparison(value: string): string;
|
|
7
|
+
/** Build the RFC 9728 well-known metadata URL for a protected resource. */
|
|
8
|
+
export declare function buildProtectedResourceMetadataUrl(agentUrl: string): string;
|
|
1
9
|
/** Validate and canonicalize an operator-configured RFC 8707 resource URI. */
|
|
2
10
|
export declare function validateOAuthResourceUrl(value: string, options?: {
|
|
3
11
|
allowHttp?: boolean;
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 9728 resource comparison semantics used by OAuth discovery and
|
|
3
|
+
* compliance grading. Scheme and host are case-insensitive and default ports
|
|
4
|
+
* are equivalent; the remainder stays byte-for-byte significant.
|
|
5
|
+
*/
|
|
6
|
+
export declare function normalizeOAuthResourceForComparison(value: string): string;
|
|
7
|
+
/** Build the RFC 9728 well-known metadata URL for a protected resource. */
|
|
8
|
+
export declare function buildProtectedResourceMetadataUrl(agentUrl: string): string;
|
|
1
9
|
/** Validate and canonicalize an operator-configured RFC 8707 resource URI. */
|
|
2
10
|
export declare function validateOAuthResourceUrl(value: string, options?: {
|
|
3
11
|
allowHttp?: boolean;
|
|
@@ -18,11 +18,51 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var resource_url_exports = {};
|
|
20
20
|
__export(resource_url_exports, {
|
|
21
|
+
buildProtectedResourceMetadataUrl: () => buildProtectedResourceMetadataUrl,
|
|
22
|
+
normalizeOAuthResourceForComparison: () => normalizeOAuthResourceForComparison,
|
|
21
23
|
validateOAuthResourceUrl: () => validateOAuthResourceUrl
|
|
22
24
|
});
|
|
23
25
|
module.exports = __toCommonJS(resource_url_exports);
|
|
24
26
|
var import_types = require('./types.js');
|
|
25
27
|
const MAX_RESOURCE_URL_LENGTH = 2048;
|
|
28
|
+
function normalizeOAuthResourceForComparison(value) {
|
|
29
|
+
const match = /^([A-Za-z][A-Za-z\d+.-]*):\/\/([^/?#]*)([\s\S]*)$/.exec(value);
|
|
30
|
+
if (!match) return value;
|
|
31
|
+
const scheme = match[1].toLowerCase();
|
|
32
|
+
const authority = match[2];
|
|
33
|
+
const remainder = match[3];
|
|
34
|
+
const at = authority.lastIndexOf("@");
|
|
35
|
+
const userinfo = at >= 0 ? authority.slice(0, at + 1) : "";
|
|
36
|
+
const hostAndPort = at >= 0 ? authority.slice(at + 1) : authority;
|
|
37
|
+
let host;
|
|
38
|
+
let port = "";
|
|
39
|
+
if (hostAndPort.startsWith("[")) {
|
|
40
|
+
const bracket = hostAndPort.indexOf("]");
|
|
41
|
+
if (bracket < 0) return value;
|
|
42
|
+
host = hostAndPort.slice(0, bracket + 1).toLowerCase();
|
|
43
|
+
const suffix = hostAndPort.slice(bracket + 1);
|
|
44
|
+
if (suffix && !/^:\d+$/.test(suffix)) return value;
|
|
45
|
+
port = suffix.slice(1);
|
|
46
|
+
} else {
|
|
47
|
+
const colon = hostAndPort.lastIndexOf(":");
|
|
48
|
+
if (colon >= 0) {
|
|
49
|
+
const suffix = hostAndPort.slice(colon + 1);
|
|
50
|
+
if (!/^\d+$/.test(suffix)) return value;
|
|
51
|
+
host = hostAndPort.slice(0, colon).toLowerCase();
|
|
52
|
+
port = suffix;
|
|
53
|
+
} else {
|
|
54
|
+
host = hostAndPort.toLowerCase();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!host) return value;
|
|
58
|
+
const defaultPort = scheme === "https" ? "443" : scheme === "http" ? "80" : void 0;
|
|
59
|
+
const renderedPort = port && port !== defaultPort ? `:${port}` : "";
|
|
60
|
+
return `${scheme}://${userinfo}${host}${renderedPort}${remainder}`;
|
|
61
|
+
}
|
|
62
|
+
function buildProtectedResourceMetadataUrl(agentUrl) {
|
|
63
|
+
const url = new URL(agentUrl);
|
|
64
|
+
return `${url.origin}/.well-known/oauth-protected-resource${url.pathname}`;
|
|
65
|
+
}
|
|
26
66
|
function validateOAuthResourceUrl(value, options = {}) {
|
|
27
67
|
if (value.length === 0 || value.length > MAX_RESOURCE_URL_LENGTH) {
|
|
28
68
|
throw new import_types.OAuthError("OAuth resource override must be between 1 and 2048 characters", "invalid_resource_override");
|
|
@@ -46,5 +86,7 @@ function validateOAuthResourceUrl(value, options = {}) {
|
|
|
46
86
|
}
|
|
47
87
|
// Annotate the CommonJS export names for ESM import in node:
|
|
48
88
|
0 && (module.exports = {
|
|
89
|
+
buildProtectedResourceMetadataUrl,
|
|
90
|
+
normalizeOAuthResourceForComparison,
|
|
49
91
|
validateOAuthResourceUrl
|
|
50
92
|
});
|
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
import { OAuthError } from "./types.mjs";
|
|
2
2
|
const MAX_RESOURCE_URL_LENGTH = 2048;
|
|
3
|
+
function normalizeOAuthResourceForComparison(value) {
|
|
4
|
+
const match = /^([A-Za-z][A-Za-z\d+.-]*):\/\/([^/?#]*)([\s\S]*)$/.exec(value);
|
|
5
|
+
if (!match) return value;
|
|
6
|
+
const scheme = match[1].toLowerCase();
|
|
7
|
+
const authority = match[2];
|
|
8
|
+
const remainder = match[3];
|
|
9
|
+
const at = authority.lastIndexOf("@");
|
|
10
|
+
const userinfo = at >= 0 ? authority.slice(0, at + 1) : "";
|
|
11
|
+
const hostAndPort = at >= 0 ? authority.slice(at + 1) : authority;
|
|
12
|
+
let host;
|
|
13
|
+
let port = "";
|
|
14
|
+
if (hostAndPort.startsWith("[")) {
|
|
15
|
+
const bracket = hostAndPort.indexOf("]");
|
|
16
|
+
if (bracket < 0) return value;
|
|
17
|
+
host = hostAndPort.slice(0, bracket + 1).toLowerCase();
|
|
18
|
+
const suffix = hostAndPort.slice(bracket + 1);
|
|
19
|
+
if (suffix && !/^:\d+$/.test(suffix)) return value;
|
|
20
|
+
port = suffix.slice(1);
|
|
21
|
+
} else {
|
|
22
|
+
const colon = hostAndPort.lastIndexOf(":");
|
|
23
|
+
if (colon >= 0) {
|
|
24
|
+
const suffix = hostAndPort.slice(colon + 1);
|
|
25
|
+
if (!/^\d+$/.test(suffix)) return value;
|
|
26
|
+
host = hostAndPort.slice(0, colon).toLowerCase();
|
|
27
|
+
port = suffix;
|
|
28
|
+
} else {
|
|
29
|
+
host = hostAndPort.toLowerCase();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (!host) return value;
|
|
33
|
+
const defaultPort = scheme === "https" ? "443" : scheme === "http" ? "80" : void 0;
|
|
34
|
+
const renderedPort = port && port !== defaultPort ? `:${port}` : "";
|
|
35
|
+
return `${scheme}://${userinfo}${host}${renderedPort}${remainder}`;
|
|
36
|
+
}
|
|
37
|
+
function buildProtectedResourceMetadataUrl(agentUrl) {
|
|
38
|
+
const url = new URL(agentUrl);
|
|
39
|
+
return `${url.origin}/.well-known/oauth-protected-resource${url.pathname}`;
|
|
40
|
+
}
|
|
3
41
|
function validateOAuthResourceUrl(value, options = {}) {
|
|
4
42
|
if (value.length === 0 || value.length > MAX_RESOURCE_URL_LENGTH) {
|
|
5
43
|
throw new OAuthError("OAuth resource override must be between 1 and 2048 characters", "invalid_resource_override");
|
|
@@ -22,5 +60,7 @@ function validateOAuthResourceUrl(value, options = {}) {
|
|
|
22
60
|
return url;
|
|
23
61
|
}
|
|
24
62
|
export {
|
|
63
|
+
buildProtectedResourceMetadataUrl,
|
|
64
|
+
normalizeOAuthResourceForComparison,
|
|
25
65
|
validateOAuthResourceUrl
|
|
26
66
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProductPropertyPolicyDiagnostic, ProductPropertyPolicyMode } from '../media-buy/property-policy.mjs';
|
|
2
|
+
import type { DelegatedOperatorAuthorizationContext } from '../signing/agent-resolver/resolve-agent.mjs';
|
|
2
3
|
/**
|
|
3
4
|
* Represents a single message in a conversation with an agent
|
|
4
5
|
*/
|
|
@@ -152,6 +153,15 @@ export interface TaskOptions {
|
|
|
152
153
|
debug?: boolean;
|
|
153
154
|
/** Suppress automatic webhook URL generation for this call. */
|
|
154
155
|
disableWebhook?: boolean;
|
|
156
|
+
/**
|
|
157
|
+
* Trusted local authorization tuple for a delegated, cross-origin seller.
|
|
158
|
+
* The SDK snapshots this before dispatch and persists it with any generated
|
|
159
|
+
* webhook registration. It is never inferred from or sent in task arguments.
|
|
160
|
+
*
|
|
161
|
+
* When present, this whole object takes precedence over the client-wide
|
|
162
|
+
* `webhookVerification.resolverOptions.requiredOperator*` fallback.
|
|
163
|
+
*/
|
|
164
|
+
delegatedOperatorAuthorization?: DelegatedOperatorAuthorizationContext;
|
|
155
165
|
/** Additional metadata to include */
|
|
156
166
|
metadata?: Record<string, any>;
|
|
157
167
|
/**
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ProductPropertyPolicyDiagnostic, ProductPropertyPolicyMode } from '../media-buy/property-policy';
|
|
2
|
+
import type { DelegatedOperatorAuthorizationContext } from '../signing/agent-resolver/resolve-agent';
|
|
2
3
|
/**
|
|
3
4
|
* Represents a single message in a conversation with an agent
|
|
4
5
|
*/
|
|
@@ -152,6 +153,15 @@ export interface TaskOptions {
|
|
|
152
153
|
debug?: boolean;
|
|
153
154
|
/** Suppress automatic webhook URL generation for this call. */
|
|
154
155
|
disableWebhook?: boolean;
|
|
156
|
+
/**
|
|
157
|
+
* Trusted local authorization tuple for a delegated, cross-origin seller.
|
|
158
|
+
* The SDK snapshots this before dispatch and persists it with any generated
|
|
159
|
+
* webhook registration. It is never inferred from or sent in task arguments.
|
|
160
|
+
*
|
|
161
|
+
* When present, this whole object takes precedence over the client-wide
|
|
162
|
+
* `webhookVerification.resolverOptions.requiredOperator*` fallback.
|
|
163
|
+
*/
|
|
164
|
+
delegatedOperatorAuthorization?: DelegatedOperatorAuthorizationContext;
|
|
155
165
|
/** Additional metadata to include */
|
|
156
166
|
metadata?: Record<string, any>;
|
|
157
167
|
/**
|
|
@@ -457,6 +457,9 @@ export declare class SingleAgentClient {
|
|
|
457
457
|
private readonly durableDeferredResumeTokenReplacers;
|
|
458
458
|
constructor(agent: AgentConfig, config?: SingleAgentClientConfig);
|
|
459
459
|
private persistWebhookRegistration;
|
|
460
|
+
private configuredDelegatedOperatorAuthorization;
|
|
461
|
+
private effectiveDelegatedOperatorAuthorization;
|
|
462
|
+
private delegatedOperatorAuthorizationForRegistration;
|
|
460
463
|
private markWebhookDurableSettlementRequired;
|
|
461
464
|
private webhookJwksFor;
|
|
462
465
|
private resolveLegacyFormatConverter;
|
|
@@ -536,8 +539,8 @@ export declare class SingleAgentClient {
|
|
|
536
539
|
*
|
|
537
540
|
* Special handling for authentication errors (401):
|
|
538
541
|
* - If any endpoint returns 401, we know the server exists but requires auth
|
|
539
|
-
* -
|
|
540
|
-
* -
|
|
542
|
+
* - A validated MCP protected-resource metadata chain yields NeedsAuthorizationError
|
|
543
|
+
* - Otherwise AuthenticationRequiredError carries the advertised challenge
|
|
541
544
|
*
|
|
542
545
|
* Note: This is async and called lazily on first agent interaction
|
|
543
546
|
*/
|
|
@@ -457,6 +457,9 @@ export declare class SingleAgentClient {
|
|
|
457
457
|
private readonly durableDeferredResumeTokenReplacers;
|
|
458
458
|
constructor(agent: AgentConfig, config?: SingleAgentClientConfig);
|
|
459
459
|
private persistWebhookRegistration;
|
|
460
|
+
private configuredDelegatedOperatorAuthorization;
|
|
461
|
+
private effectiveDelegatedOperatorAuthorization;
|
|
462
|
+
private delegatedOperatorAuthorizationForRegistration;
|
|
460
463
|
private markWebhookDurableSettlementRequired;
|
|
461
464
|
private webhookJwksFor;
|
|
462
465
|
private resolveLegacyFormatConverter;
|
|
@@ -536,8 +539,8 @@ export declare class SingleAgentClient {
|
|
|
536
539
|
*
|
|
537
540
|
* Special handling for authentication errors (401):
|
|
538
541
|
* - If any endpoint returns 401, we know the server exists but requires auth
|
|
539
|
-
* -
|
|
540
|
-
* -
|
|
542
|
+
* - A validated MCP protected-resource metadata chain yields NeedsAuthorizationError
|
|
543
|
+
* - Otherwise AuthenticationRequiredError carries the advertised challenge
|
|
541
544
|
*
|
|
542
545
|
* Note: This is async and called lazily on first agent interaction
|
|
543
546
|
*/
|