@kya-os/create-mcpi-app 1.10.1 → 1.10.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +13 -13
- package/dist/bundles/blank.js +522 -133
- package/dist/bundles/ecommerce.js +522 -133
- package/dist/bundles/hardware-world.js +522 -133
- package/dist/bundles/manifest.json +11 -11
- package/dist/bundles/mix-station.js +522 -133
- package/dist/helpers/get-package-versions.js +1 -1
- package/package.json +2 -2
|
@@ -19235,7 +19235,7 @@ var require_base2 = __commonJS({
|
|
|
19235
19235
|
var agentshield_api_1 = require_agentshield_api();
|
|
19236
19236
|
var user_did_manager_1 = require_user_did_manager();
|
|
19237
19237
|
var wire_format_1 = require_wire_format();
|
|
19238
|
-
var
|
|
19238
|
+
var isRecord3 = (value) => typeof value === "object" && value !== null;
|
|
19239
19239
|
var MCPIRuntimeBase3 = class _MCPIRuntimeBase {
|
|
19240
19240
|
crypto;
|
|
19241
19241
|
clock;
|
|
@@ -19535,7 +19535,7 @@ var require_base2 = __commonJS({
|
|
|
19535
19535
|
});
|
|
19536
19536
|
}
|
|
19537
19537
|
const clientInfo = session?.clientInfo;
|
|
19538
|
-
const clientCaps =
|
|
19538
|
+
const clientCaps = isRecord3(clientInfo?.capabilities) ? clientInfo.capabilities : void 0;
|
|
19539
19539
|
const uiResult = this.buildConsentUIResult(toolName, protection.requiredScopes, session, resumeToken, session?.projectId || void 0, session?.serverOrigin || void 0, clientCaps);
|
|
19540
19540
|
if (uiResult) {
|
|
19541
19541
|
return uiResult;
|
|
@@ -20118,7 +20118,7 @@ var require_base2 = __commonJS({
|
|
|
20118
20118
|
async verifyProof(dataOrProof, proofOrSession) {
|
|
20119
20119
|
if (dataOrProof && typeof dataOrProof === "object" && "jws" in dataOrProof && "meta" in dataOrProof) {
|
|
20120
20120
|
const detachedProof = dataOrProof;
|
|
20121
|
-
const session =
|
|
20121
|
+
const session = isRecord3(proofOrSession) ? proofOrSession : void 0;
|
|
20122
20122
|
if (this.proofVerifier) {
|
|
20123
20123
|
try {
|
|
20124
20124
|
const didDoc = await this.fetch.resolveDID(detachedProof.meta.did);
|
|
@@ -20139,10 +20139,10 @@ var require_base2 = __commonJS({
|
|
|
20139
20139
|
}
|
|
20140
20140
|
} else {
|
|
20141
20141
|
console.warn("[MCPIRuntimeBase] ProofVerifier not available, using fallback verification");
|
|
20142
|
-
return this.verifyProofLegacy(dataOrProof,
|
|
20142
|
+
return this.verifyProofLegacy(dataOrProof, isRecord3(proofOrSession) ? proofOrSession : {});
|
|
20143
20143
|
}
|
|
20144
20144
|
} else {
|
|
20145
|
-
return this.verifyProofLegacy(dataOrProof,
|
|
20145
|
+
return this.verifyProofLegacy(dataOrProof, isRecord3(proofOrSession) ? proofOrSession : {});
|
|
20146
20146
|
}
|
|
20147
20147
|
}
|
|
20148
20148
|
/**
|
|
@@ -20537,7 +20537,7 @@ var require_base2 = __commonJS({
|
|
|
20537
20537
|
};
|
|
20538
20538
|
}
|
|
20539
20539
|
extractPublicKey(didDoc) {
|
|
20540
|
-
const verificationMethods =
|
|
20540
|
+
const verificationMethods = isRecord3(didDoc) ? didDoc.verificationMethod : void 0;
|
|
20541
20541
|
const method = Array.isArray(verificationMethods) ? verificationMethods[0] : void 0;
|
|
20542
20542
|
if (method?.publicKeyBase64) {
|
|
20543
20543
|
return String(method.publicKeyBase64);
|
|
@@ -20551,7 +20551,7 @@ var require_base2 = __commonJS({
|
|
|
20551
20551
|
* Extract public key JWK from DID document
|
|
20552
20552
|
*/
|
|
20553
20553
|
extractPublicKeyJwk(didDoc, kid) {
|
|
20554
|
-
const verificationMethods =
|
|
20554
|
+
const verificationMethods = isRecord3(didDoc) ? didDoc.verificationMethod : void 0;
|
|
20555
20555
|
const verificationMethodList = Array.isArray(verificationMethods) ? verificationMethods : [];
|
|
20556
20556
|
const verificationMethod = verificationMethodList.find((vm) => {
|
|
20557
20557
|
const vmType = typeof vm.type === "string" ? vm.type : void 0;
|
|
@@ -20560,7 +20560,7 @@ var require_base2 = __commonJS({
|
|
|
20560
20560
|
const matchesKid = !kid || vmId === kid || vmId?.endsWith(`#${kid}`);
|
|
20561
20561
|
return matchesType && matchesKid;
|
|
20562
20562
|
}) || verificationMethodList[0];
|
|
20563
|
-
if (verificationMethod &&
|
|
20563
|
+
if (verificationMethod && isRecord3(verificationMethod.publicKeyJwk)) {
|
|
20564
20564
|
const jwk = verificationMethod.publicKeyJwk;
|
|
20565
20565
|
if (jwk.kty === "OKP" && jwk.crv === "Ed25519") {
|
|
20566
20566
|
return jwk;
|
|
@@ -80849,7 +80849,7 @@ var init_protocol4 = __esm({
|
|
|
80849
80849
|
const capturedTransport = this._transport;
|
|
80850
80850
|
const relatedTaskId = request.params?._meta?.[RELATED_TASK_META_KEY2]?.taskId;
|
|
80851
80851
|
if (handler === void 0) {
|
|
80852
|
-
const
|
|
80852
|
+
const errorResponse2 = {
|
|
80853
80853
|
jsonrpc: "2.0",
|
|
80854
80854
|
id: request.id,
|
|
80855
80855
|
error: {
|
|
@@ -80860,11 +80860,11 @@ var init_protocol4 = __esm({
|
|
|
80860
80860
|
if (relatedTaskId && this._taskMessageQueue) {
|
|
80861
80861
|
this._enqueueTaskMessage(relatedTaskId, {
|
|
80862
80862
|
type: "error",
|
|
80863
|
-
message:
|
|
80863
|
+
message: errorResponse2,
|
|
80864
80864
|
timestamp: Date.now()
|
|
80865
80865
|
}, capturedTransport?.sessionId).catch((error87) => this._onerror(new Error(`Failed to enqueue error response: ${error87}`)));
|
|
80866
80866
|
} else {
|
|
80867
|
-
capturedTransport?.send(
|
|
80867
|
+
capturedTransport?.send(errorResponse2).catch((error87) => this._onerror(new Error(`Failed to send an error response: ${error87}`)));
|
|
80868
80868
|
}
|
|
80869
80869
|
return;
|
|
80870
80870
|
}
|
|
@@ -80934,7 +80934,7 @@ var init_protocol4 = __esm({
|
|
|
80934
80934
|
if (abortController.signal.aborted) {
|
|
80935
80935
|
return;
|
|
80936
80936
|
}
|
|
80937
|
-
const
|
|
80937
|
+
const errorResponse2 = {
|
|
80938
80938
|
jsonrpc: "2.0",
|
|
80939
80939
|
id: request.id,
|
|
80940
80940
|
error: {
|
|
@@ -80946,11 +80946,11 @@ var init_protocol4 = __esm({
|
|
|
80946
80946
|
if (relatedTaskId && this._taskMessageQueue) {
|
|
80947
80947
|
await this._enqueueTaskMessage(relatedTaskId, {
|
|
80948
80948
|
type: "error",
|
|
80949
|
-
message:
|
|
80949
|
+
message: errorResponse2,
|
|
80950
80950
|
timestamp: Date.now()
|
|
80951
80951
|
}, capturedTransport?.sessionId);
|
|
80952
80952
|
} else {
|
|
80953
|
-
await capturedTransport?.send(
|
|
80953
|
+
await capturedTransport?.send(errorResponse2);
|
|
80954
80954
|
}
|
|
80955
80955
|
}).catch((error87) => this._onerror(new Error(`Failed to send response: ${error87}`))).finally(() => {
|
|
80956
80956
|
this._requestHandlerAbortControllers.delete(request.id);
|
|
@@ -141255,6 +141255,11 @@ function resolveHttpChallengeConfig(config4, env2) {
|
|
|
141255
141255
|
if (!enabled)
|
|
141256
141256
|
return null;
|
|
141257
141257
|
const anchorTtlS = Math.min(positiveOrDefault(httpChallenge?.anchorTtlS, ANCHOR_TTL_MAX_S), ANCHOR_TTL_MAX_S);
|
|
141258
|
+
const anchorRegistrationEnvFlag = readHttpChallengeEnvFlag(env2?.MCPI_ANCHOR_REGISTRATION);
|
|
141259
|
+
let remoteAnchorRegistration = httpChallenge?.remoteAnchorRegistration ?? true;
|
|
141260
|
+
if (anchorRegistrationEnvFlag !== void 0) {
|
|
141261
|
+
remoteAnchorRegistration = anchorRegistrationEnvFlag;
|
|
141262
|
+
}
|
|
141258
141263
|
return {
|
|
141259
141264
|
enabled: true,
|
|
141260
141265
|
mode: httpChallenge?.mode ?? "negotiated",
|
|
@@ -141262,7 +141267,8 @@ function resolveHttpChallengeConfig(config4, env2) {
|
|
|
141262
141267
|
pollIntervalS: positiveOrDefault(httpChallenge?.pollIntervalS, 3),
|
|
141263
141268
|
anchorTtlS,
|
|
141264
141269
|
delegationExpiresInS: positiveOrDefault(httpChallenge?.delegationExpiresInS, 900),
|
|
141265
|
-
allowUnverifiedKeyidHolders: httpChallenge?.allowUnverifiedKeyidHolders ?? false
|
|
141270
|
+
allowUnverifiedKeyidHolders: httpChallenge?.allowUnverifiedKeyidHolders ?? false,
|
|
141271
|
+
remoteAnchorRegistration
|
|
141266
141272
|
};
|
|
141267
141273
|
}
|
|
141268
141274
|
|
|
@@ -141325,6 +141331,7 @@ function mapPrefixedEnv(env2, prefix) {
|
|
|
141325
141331
|
MCPI_HTTP_CHALLENGE: typeof env2.MCPI_HTTP_CHALLENGE === "string" ? env2.MCPI_HTTP_CHALLENGE : void 0,
|
|
141326
141332
|
MCPI_TEST_CONSENT: typeof env2.MCPI_TEST_CONSENT === "string" ? env2.MCPI_TEST_CONSENT : void 0,
|
|
141327
141333
|
MCPI_INLINE_CONSENT: typeof env2.MCPI_INLINE_CONSENT === "string" ? env2.MCPI_INLINE_CONSENT : void 0,
|
|
141334
|
+
MCPI_ANCHOR_REGISTRATION: typeof env2.MCPI_ANCHOR_REGISTRATION === "string" ? env2.MCPI_ANCHOR_REGISTRATION : void 0,
|
|
141328
141335
|
// MCP_OBJECT: Durable Object namespace for MCP agent
|
|
141329
141336
|
// Try prefixed first, then fall back to unprefixed (most deployments use unprefixed)
|
|
141330
141337
|
MCP_OBJECT: env2[`${prefixWithUnderscore}_MCP_OBJECT`] || env2[`${prefixWithoutUnderscore}_MCP_OBJECT`] || env2.MCP_OBJECT,
|
|
@@ -141456,6 +141463,7 @@ function sha256Hex(input) {
|
|
|
141456
141463
|
// ../mcp-i-cloudflare/dist/delegation-http/constants.js
|
|
141457
141464
|
var PICKUP_ROUTE = "/api/delegation/pickup/:sid";
|
|
141458
141465
|
var CONSENT_ROUTE = "/consent";
|
|
141466
|
+
var ANCHOR_REGISTRATION_ROUTE = "/api/v1/bouncer/sessions";
|
|
141459
141467
|
var PICKUP_TOKEN_HEADER = "X-KYA-Pickup-Token";
|
|
141460
141468
|
var FALLBACK_DELEGATION_HEADER = "KYA-Delegation";
|
|
141461
141469
|
var CHALLENGE_PARAM_ORDER = [
|
|
@@ -141484,6 +141492,21 @@ var INTERNAL_PICKUP_INFO = "/_internal/pickup/info";
|
|
|
141484
141492
|
|
|
141485
141493
|
// ../mcp-i-cloudflare/dist/delegation-http/anchor-do.js
|
|
141486
141494
|
init_storage_keys();
|
|
141495
|
+
function anchorSnapshot(rec) {
|
|
141496
|
+
return {
|
|
141497
|
+
sid: rec.sid,
|
|
141498
|
+
status: rec.status,
|
|
141499
|
+
requiredScopes: rec.requiredScopes,
|
|
141500
|
+
minAssurance: rec.minAssurance,
|
|
141501
|
+
expiresAt: rec.expiresAt,
|
|
141502
|
+
createdAt: rec.createdAt,
|
|
141503
|
+
registeredAtMs: rec.registeredAtMs,
|
|
141504
|
+
issuedAtMs: rec.issuedAtMs,
|
|
141505
|
+
agentDid: rec.agentDid,
|
|
141506
|
+
audience: rec.audience,
|
|
141507
|
+
serverDid: rec.serverDid
|
|
141508
|
+
};
|
|
141509
|
+
}
|
|
141487
141510
|
var pendingBody = () => ({ status: "pending" });
|
|
141488
141511
|
var pinnedErr = () => ({ error: KYAOS_ERRORS.pickupPinned });
|
|
141489
141512
|
var invalidSessionErr = () => ({ error: KYAOS_ERRORS.invalidSession });
|
|
@@ -141491,7 +141514,12 @@ var pickupExpiredErr = () => ({ error: KYAOS_ERRORS.pickupExpired });
|
|
|
141491
141514
|
function reduceCreate(rec, input, now2) {
|
|
141492
141515
|
const i2 = input;
|
|
141493
141516
|
if (rec && now2 <= rec.expiresAt) {
|
|
141494
|
-
return {
|
|
141517
|
+
return {
|
|
141518
|
+
response: {
|
|
141519
|
+
status: 201,
|
|
141520
|
+
body: { success: true, reused: true, anchor: anchorSnapshot(rec) }
|
|
141521
|
+
}
|
|
141522
|
+
};
|
|
141495
141523
|
}
|
|
141496
141524
|
const record4 = {
|
|
141497
141525
|
sid: i2.sid,
|
|
@@ -141501,6 +141529,11 @@ function reduceCreate(rec, input, now2) {
|
|
|
141501
141529
|
pollIntervalS: i2.pollIntervalS,
|
|
141502
141530
|
createdAt: now2,
|
|
141503
141531
|
expiresAt: now2 + i2.anchorTtlS * 1e3,
|
|
141532
|
+
agentDid: typeof i2.agentDid === "string" ? i2.agentDid : void 0,
|
|
141533
|
+
audience: typeof i2.audience === "string" ? i2.audience : void 0,
|
|
141534
|
+
serverDid: typeof i2.serverDid === "string" ? i2.serverDid : void 0,
|
|
141535
|
+
registeredAtMs: typeof i2.registeredAtMs === "number" ? i2.registeredAtMs : void 0,
|
|
141536
|
+
issuedAtMs: now2,
|
|
141504
141537
|
pin: i2.pin ? {
|
|
141505
141538
|
type: i2.pin.type,
|
|
141506
141539
|
valueSha256: i2.pin.valueSha256,
|
|
@@ -141508,7 +141541,13 @@ function reduceCreate(rec, input, now2) {
|
|
|
141508
141541
|
source: "challenge"
|
|
141509
141542
|
} : void 0
|
|
141510
141543
|
};
|
|
141511
|
-
return {
|
|
141544
|
+
return {
|
|
141545
|
+
record: record4,
|
|
141546
|
+
response: {
|
|
141547
|
+
status: 201,
|
|
141548
|
+
body: { success: true, anchor: anchorSnapshot(record4) }
|
|
141549
|
+
}
|
|
141550
|
+
};
|
|
141512
141551
|
}
|
|
141513
141552
|
function reducePoll(rec, holder, now2) {
|
|
141514
141553
|
if (!rec) {
|
|
@@ -141639,7 +141678,10 @@ async function handlePickupInternal(ctx, request, now2) {
|
|
|
141639
141678
|
status: rec.status,
|
|
141640
141679
|
requiredScopes: rec.requiredScopes,
|
|
141641
141680
|
minAssurance: rec.minAssurance,
|
|
141642
|
-
expiresAt: rec.expiresAt
|
|
141681
|
+
expiresAt: rec.expiresAt,
|
|
141682
|
+
agentDid: rec.agentDid,
|
|
141683
|
+
audience: rec.audience,
|
|
141684
|
+
serverDid: rec.serverDid
|
|
141643
141685
|
}
|
|
141644
141686
|
});
|
|
141645
141687
|
}
|
|
@@ -141649,7 +141691,7 @@ async function handlePickupInternal(ctx, request, now2) {
|
|
|
141649
141691
|
// ../mcp-i-cloudflare/package.json
|
|
141650
141692
|
var package_default = {
|
|
141651
141693
|
name: "@kya-os/mcp-i-cloudflare",
|
|
141652
|
-
version: "1.
|
|
141694
|
+
version: "1.12.1",
|
|
141653
141695
|
description: "Cloudflare Workers adapter for MCP-I framework",
|
|
141654
141696
|
main: "dist/index.js",
|
|
141655
141697
|
types: "dist/index.d.ts",
|
|
@@ -141719,7 +141761,7 @@ var package_default = {
|
|
|
141719
141761
|
|
|
141720
141762
|
// ../mcp-i-cloudflare/dist/delegation-http/well-known-capability.js
|
|
141721
141763
|
var KYA_OS_IDENTITY_WELL_KNOWN_PATH = "/.well-known/kya-os-identity";
|
|
141722
|
-
function augmentKyaOsIdentityWellKnown(wellKnownPath, result, cfg) {
|
|
141764
|
+
function augmentKyaOsIdentityWellKnown(wellKnownPath, result, cfg, anchorRegistration) {
|
|
141723
141765
|
if (wellKnownPath !== KYA_OS_IDENTITY_WELL_KNOWN_PATH || !result) {
|
|
141724
141766
|
return result;
|
|
141725
141767
|
}
|
|
@@ -141727,11 +141769,429 @@ function augmentKyaOsIdentityWellKnown(wellKnownPath, result, cfg) {
|
|
|
141727
141769
|
...result,
|
|
141728
141770
|
delegationHttp: {
|
|
141729
141771
|
enabled: cfg !== null,
|
|
141730
|
-
version: package_default.version
|
|
141772
|
+
version: package_default.version,
|
|
141773
|
+
anchorRegistration
|
|
141774
|
+
}
|
|
141775
|
+
};
|
|
141776
|
+
}
|
|
141777
|
+
|
|
141778
|
+
// ../mcp-i-cloudflare/dist/delegation-http/sid.js
|
|
141779
|
+
var ANCHOR_SID_RE = /^kya-[0-9a-f]{16,64}$/;
|
|
141780
|
+
function isAnchorSid(s5) {
|
|
141781
|
+
return typeof s5 === "string" && ANCHOR_SID_RE.test(s5);
|
|
141782
|
+
}
|
|
141783
|
+
|
|
141784
|
+
// ../mcp-i-cloudflare/dist/delegation-http/challenge.js
|
|
141785
|
+
var CHALLENGE_PROOF_METHOD = "kyaos/challenge";
|
|
141786
|
+
function buildWWWAuthenticateDelegation(i2) {
|
|
141787
|
+
const values = {
|
|
141788
|
+
realm: i2.realm,
|
|
141789
|
+
sid: i2.sid,
|
|
141790
|
+
consent_uri: buildConsentUri(i2),
|
|
141791
|
+
pickup_uri: buildPickupUri(i2),
|
|
141792
|
+
scope: i2.requiredScopes.join(" "),
|
|
141793
|
+
min_assurance: i2.minAssurance,
|
|
141794
|
+
interval: String(i2.pollIntervalS),
|
|
141795
|
+
kind: "delegation"
|
|
141796
|
+
};
|
|
141797
|
+
const params = CHALLENGE_PARAM_ORDER.filter(
|
|
141798
|
+
// min_assurance is the only optional param: omit the whole token when absent.
|
|
141799
|
+
(key) => values[key] !== void 0
|
|
141800
|
+
).map((key) => `${key}="${values[key]}"`);
|
|
141801
|
+
return `Delegation ${params.join(", ")}`;
|
|
141802
|
+
}
|
|
141803
|
+
function buildWWWAuthenticateBearer(realm) {
|
|
141804
|
+
return `Bearer resource_metadata="https://${realm}/.well-known/oauth-protected-resource"`;
|
|
141805
|
+
}
|
|
141806
|
+
function buildConsentUri(i2) {
|
|
141807
|
+
return `https://${i2.authorizationHost}/consent?sid=${i2.sid}`;
|
|
141808
|
+
}
|
|
141809
|
+
function buildPickupUri(i2) {
|
|
141810
|
+
return `https://${i2.authorizationHost}/api/delegation/pickup/${i2.sid}`;
|
|
141811
|
+
}
|
|
141812
|
+
function buildInstructions(i2) {
|
|
141813
|
+
const consentUri = buildConsentUri(i2);
|
|
141814
|
+
const pickupUri = buildPickupUri(i2);
|
|
141815
|
+
return `This action requires human authorization. Show your user this link and ask them to approve: ${consentUri}. Then poll ${pickupUri} every ${i2.pollIntervalS} seconds. If you can sign HTTP requests, sign each poll with an ephemeral did:key; otherwise generate one random 32-byte token and send it as X-KYA-Pickup-Token on EVERY poll. When the response status is 200, take the 'delegation' value and retry your original request with header 'Authorization: Bearer <delegation>'.`;
|
|
141816
|
+
}
|
|
141817
|
+
function buildChallengeBody(i2, challengeProof) {
|
|
141818
|
+
const kyaos = {
|
|
141819
|
+
sid: i2.sid,
|
|
141820
|
+
consent_uri: buildConsentUri(i2),
|
|
141821
|
+
pickup_uri: buildPickupUri(i2),
|
|
141822
|
+
required_scopes: i2.requiredScopes
|
|
141823
|
+
};
|
|
141824
|
+
if (i2.minAssurance !== void 0) {
|
|
141825
|
+
kyaos.min_assurance = i2.minAssurance;
|
|
141826
|
+
}
|
|
141827
|
+
kyaos.poll_interval_s = i2.pollIntervalS;
|
|
141828
|
+
kyaos.challenge_proof = challengeProof;
|
|
141829
|
+
return {
|
|
141830
|
+
error: KYAOS_ERRORS.authorizationRequired,
|
|
141831
|
+
kyaos,
|
|
141832
|
+
instructions: buildInstructions(i2)
|
|
141833
|
+
};
|
|
141834
|
+
}
|
|
141835
|
+
function buildChallengeResponse(i2, challengeProof) {
|
|
141836
|
+
const headers = new Headers();
|
|
141837
|
+
headers.append("WWW-Authenticate", buildWWWAuthenticateDelegation(i2));
|
|
141838
|
+
headers.append("WWW-Authenticate", buildWWWAuthenticateBearer(i2.realm));
|
|
141839
|
+
headers.set("Retry-After", String(i2.pollIntervalS));
|
|
141840
|
+
headers.set("Content-Type", "application/json");
|
|
141841
|
+
headers.set("Cache-Control", "no-store");
|
|
141842
|
+
return new Response(JSON.stringify(buildChallengeBody(i2, challengeProof)), {
|
|
141843
|
+
status: 401,
|
|
141844
|
+
headers
|
|
141845
|
+
});
|
|
141846
|
+
}
|
|
141847
|
+
function buildFetcherChallengeResponse(i2, challengeProof) {
|
|
141848
|
+
const consentUri = buildConsentUri(i2);
|
|
141849
|
+
const headers = new Headers();
|
|
141850
|
+
headers.set("Content-Type", "application/json");
|
|
141851
|
+
headers.set("Cache-Control", "no-store");
|
|
141852
|
+
headers.set("KYA-Auth-Required", "true");
|
|
141853
|
+
headers.set("KYA-Auth-Url", consentUri);
|
|
141854
|
+
headers.set("Link", `<${consentUri}>; rel="kya-authorize"`);
|
|
141855
|
+
headers.set("KYA-Action", "challenge");
|
|
141856
|
+
return new Response(JSON.stringify(buildChallengeBody(i2, challengeProof)), {
|
|
141857
|
+
status: 200,
|
|
141858
|
+
headers
|
|
141859
|
+
});
|
|
141860
|
+
}
|
|
141861
|
+
async function signChallengeProof(gen, payload) {
|
|
141862
|
+
const proof = await gen.generateProof({
|
|
141863
|
+
method: CHALLENGE_PROOF_METHOD,
|
|
141864
|
+
params: {
|
|
141865
|
+
sid: payload.sid,
|
|
141866
|
+
consent_uri: payload.consent_uri,
|
|
141867
|
+
required_scopes: payload.required_scopes
|
|
141868
|
+
}
|
|
141869
|
+
}, { data: { sid: payload.sid } }, {
|
|
141870
|
+
// The session binds the proof to this anchor; sid is the natural nonce.
|
|
141871
|
+
nonce: payload.sid,
|
|
141872
|
+
audience: payload.consent_uri,
|
|
141873
|
+
sessionId: payload.sid
|
|
141874
|
+
});
|
|
141875
|
+
return proof.jws;
|
|
141876
|
+
}
|
|
141877
|
+
|
|
141878
|
+
// ../mcp-i-cloudflare/dist/delegation-http/registrar-auth.js
|
|
141879
|
+
function constantTimeEqualHex(a5, b3) {
|
|
141880
|
+
if (a5.length !== b3.length)
|
|
141881
|
+
return false;
|
|
141882
|
+
let diff = 0;
|
|
141883
|
+
for (let i2 = 0; i2 < a5.length; i2++) {
|
|
141884
|
+
diff |= a5.charCodeAt(i2) ^ b3.charCodeAt(i2);
|
|
141885
|
+
}
|
|
141886
|
+
return diff === 0;
|
|
141887
|
+
}
|
|
141888
|
+
function registrarAuthorized(env2, authorizationHeader) {
|
|
141889
|
+
const expected = env2.AGENTSHIELD_API_KEY;
|
|
141890
|
+
if (!expected || !authorizationHeader)
|
|
141891
|
+
return false;
|
|
141892
|
+
const match2 = /^Bearer\s+(.+)$/i.exec(authorizationHeader.trim());
|
|
141893
|
+
if (!match2)
|
|
141894
|
+
return false;
|
|
141895
|
+
return constantTimeEqualHex(sha256Hex(match2[1]), sha256Hex(expected));
|
|
141896
|
+
}
|
|
141897
|
+
var RATE_WINDOW_MS = 6e4;
|
|
141898
|
+
var RATE_MAX_PER_WINDOW = 60;
|
|
141899
|
+
var rateWindowStart = 0;
|
|
141900
|
+
var rateCount = 0;
|
|
141901
|
+
function registrationRateLimited(now2) {
|
|
141902
|
+
if (now2 - rateWindowStart >= RATE_WINDOW_MS) {
|
|
141903
|
+
rateWindowStart = now2;
|
|
141904
|
+
rateCount = 0;
|
|
141905
|
+
}
|
|
141906
|
+
rateCount += 1;
|
|
141907
|
+
return rateCount > RATE_MAX_PER_WINDOW;
|
|
141908
|
+
}
|
|
141909
|
+
|
|
141910
|
+
// ../mcp-i-cloudflare/dist/delegation-http/anchor-registration-validate.js
|
|
141911
|
+
var DID_RE = /^did:(key|web):.+$/;
|
|
141912
|
+
var SYNTHETIC_DETECTED_DID_PREFIX = "did:web:detected:";
|
|
141913
|
+
function didIssueMessage(value) {
|
|
141914
|
+
if (typeof value !== "string" || !DID_RE.test(value)) {
|
|
141915
|
+
return "Invalid DID format. Must be did:key: or did:web:";
|
|
141916
|
+
}
|
|
141917
|
+
if (value.startsWith(SYNTHETIC_DETECTED_DID_PREFIX)) {
|
|
141918
|
+
return "Synthetic detected DIDs are not valid KYA-OS identities";
|
|
141919
|
+
}
|
|
141920
|
+
return null;
|
|
141921
|
+
}
|
|
141922
|
+
function isRecord2(value) {
|
|
141923
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
141924
|
+
}
|
|
141925
|
+
function checkString(issues, path, value, max) {
|
|
141926
|
+
if (typeof value !== "string" || value.length < 1 || value.length > max) {
|
|
141927
|
+
issues.push({ path, message: `${path} must be a string (1-${max} chars)` });
|
|
141928
|
+
return false;
|
|
141929
|
+
}
|
|
141930
|
+
return true;
|
|
141931
|
+
}
|
|
141932
|
+
function checkOptionalString(issues, path, value, max) {
|
|
141933
|
+
if (value === void 0)
|
|
141934
|
+
return;
|
|
141935
|
+
checkString(issues, path, value, max);
|
|
141936
|
+
}
|
|
141937
|
+
function validateChallenge(issues, raw2) {
|
|
141938
|
+
if (raw2 === void 0)
|
|
141939
|
+
return void 0;
|
|
141940
|
+
if (!isRecord2(raw2)) {
|
|
141941
|
+
issues.push({ path: "challenge", message: "challenge must be an object" });
|
|
141942
|
+
return void 0;
|
|
141943
|
+
}
|
|
141944
|
+
const issuesBefore = issues.length;
|
|
141945
|
+
const scopes = raw2.required_scopes;
|
|
141946
|
+
if (!Array.isArray(scopes) || scopes.length < 1 || scopes.length > 50 || scopes.some((s5) => typeof s5 !== "string" || s5.length < 1 || s5.length > 200)) {
|
|
141947
|
+
issues.push({
|
|
141948
|
+
path: "challenge.required_scopes",
|
|
141949
|
+
message: "challenge.required_scopes must be 1-50 strings of 1-200 chars each"
|
|
141950
|
+
});
|
|
141951
|
+
}
|
|
141952
|
+
checkOptionalString(issues, "challenge.pep_surface", raw2.pep_surface, 64);
|
|
141953
|
+
checkOptionalString(issues, "challenge.verdict", raw2.verdict, 64);
|
|
141954
|
+
checkOptionalString(issues, "challenge.challenge_pin", raw2.challenge_pin, 512);
|
|
141955
|
+
if (raw2.detected_agent_did !== void 0) {
|
|
141956
|
+
const issue4 = didIssueMessage(raw2.detected_agent_did);
|
|
141957
|
+
if (issue4) {
|
|
141958
|
+
issues.push({ path: "challenge.detected_agent_did", message: issue4 });
|
|
141959
|
+
}
|
|
141960
|
+
}
|
|
141961
|
+
if (raw2.audience !== void 0) {
|
|
141962
|
+
const issue4 = didIssueMessage(raw2.audience);
|
|
141963
|
+
if (issue4) {
|
|
141964
|
+
issues.push({ path: "challenge.audience", message: issue4 });
|
|
141965
|
+
}
|
|
141966
|
+
}
|
|
141967
|
+
if (issues.length > issuesBefore)
|
|
141968
|
+
return void 0;
|
|
141969
|
+
return {
|
|
141970
|
+
requiredScopes: scopes,
|
|
141971
|
+
pepSurface: raw2.pep_surface,
|
|
141972
|
+
verdict: raw2.verdict,
|
|
141973
|
+
detectedAgentDid: raw2.detected_agent_did,
|
|
141974
|
+
challengePin: raw2.challenge_pin,
|
|
141975
|
+
audience: raw2.audience
|
|
141976
|
+
};
|
|
141977
|
+
}
|
|
141978
|
+
function validateRegistrationBody(raw2) {
|
|
141979
|
+
if (!isRecord2(raw2)) {
|
|
141980
|
+
return {
|
|
141981
|
+
ok: false,
|
|
141982
|
+
issues: [{ path: "", message: "body must be a JSON object" }]
|
|
141983
|
+
};
|
|
141984
|
+
}
|
|
141985
|
+
const issues = [];
|
|
141986
|
+
checkString(issues, "session_id", raw2.session_id, 255);
|
|
141987
|
+
{
|
|
141988
|
+
const issue4 = didIssueMessage(raw2.agent_did);
|
|
141989
|
+
if (issue4)
|
|
141990
|
+
issues.push({ path: "agent_did", message: issue4 });
|
|
141991
|
+
}
|
|
141992
|
+
if (typeof raw2.project_id !== "string" || raw2.project_id.length < 1) {
|
|
141993
|
+
issues.push({
|
|
141994
|
+
path: "project_id",
|
|
141995
|
+
message: "project_id must be a non-empty string"
|
|
141996
|
+
});
|
|
141997
|
+
}
|
|
141998
|
+
if (typeof raw2.created_at !== "number" || !Number.isInteger(raw2.created_at) || raw2.created_at <= 0 || raw2.created_at > 864e13) {
|
|
141999
|
+
issues.push({
|
|
142000
|
+
path: "created_at",
|
|
142001
|
+
message: "created_at must be a valid positive unix-ms integer"
|
|
142002
|
+
});
|
|
142003
|
+
}
|
|
142004
|
+
const clientInfo = raw2.client_info;
|
|
142005
|
+
if (!isRecord2(clientInfo)) {
|
|
142006
|
+
issues.push({
|
|
142007
|
+
path: "client_info",
|
|
142008
|
+
message: "client_info must be an object"
|
|
142009
|
+
});
|
|
142010
|
+
} else {
|
|
142011
|
+
checkString(issues, "client_info.name", clientInfo.name, 255);
|
|
142012
|
+
checkOptionalString(issues, "client_info.version", clientInfo.version, 50);
|
|
142013
|
+
}
|
|
142014
|
+
if (raw2.server_did !== void 0) {
|
|
142015
|
+
const issue4 = didIssueMessage(raw2.server_did);
|
|
142016
|
+
if (issue4)
|
|
142017
|
+
issues.push({ path: "server_did", message: issue4 });
|
|
142018
|
+
}
|
|
142019
|
+
const challenge = validateChallenge(issues, raw2.challenge);
|
|
142020
|
+
if (raw2.challenge !== void 0 && typeof raw2.session_id === "string" && raw2.session_id.length < 22) {
|
|
142021
|
+
issues.push({
|
|
142022
|
+
path: "session_id",
|
|
142023
|
+
message: "session_id must be at least 22 characters (\u2248128-bit) when a challenge is attached"
|
|
142024
|
+
});
|
|
142025
|
+
}
|
|
142026
|
+
if (issues.length > 0)
|
|
142027
|
+
return { ok: false, issues };
|
|
142028
|
+
return {
|
|
142029
|
+
ok: true,
|
|
142030
|
+
input: {
|
|
142031
|
+
sessionId: raw2.session_id,
|
|
142032
|
+
agentDid: raw2.agent_did,
|
|
142033
|
+
projectId: raw2.project_id,
|
|
142034
|
+
createdAt: raw2.created_at,
|
|
142035
|
+
clientName: clientInfo.name,
|
|
142036
|
+
clientVersion: clientInfo.version,
|
|
142037
|
+
serverDid: raw2.server_did,
|
|
142038
|
+
challenge
|
|
141731
142039
|
}
|
|
141732
142040
|
};
|
|
141733
142041
|
}
|
|
141734
142042
|
|
|
142043
|
+
// ../mcp-i-cloudflare/dist/delegation-http/anchor-registration.js
|
|
142044
|
+
var DO_INTERNAL_ORIGIN = "https://do.internal";
|
|
142045
|
+
function isAnchorRegistrationEnabled(cfg, env2) {
|
|
142046
|
+
return cfg !== null && cfg.remoteAnchorRegistration && typeof env2.AGENTSHIELD_API_KEY === "string" && env2.AGENTSHIELD_API_KEY.length > 0 && // No anchor store, no registration surface: getAnchorStub throws on an
|
|
142047
|
+
// unbound MCP_OBJECT, so an unbound deployment must 404 like every other
|
|
142048
|
+
// unprovisioned state instead of 500ing per request.
|
|
142049
|
+
env2.MCP_OBJECT !== void 0;
|
|
142050
|
+
}
|
|
142051
|
+
function deriveRegistrationSid(sessionId) {
|
|
142052
|
+
if (isAnchorSid(sessionId))
|
|
142053
|
+
return sessionId;
|
|
142054
|
+
return `kya-${sha256Hex(sessionId).slice(0, 32)}`;
|
|
142055
|
+
}
|
|
142056
|
+
function errorResponse(status, code, message3, details) {
|
|
142057
|
+
return new Response(JSON.stringify({
|
|
142058
|
+
success: false,
|
|
142059
|
+
error: { code, message: message3, ...details ? { details } : {} }
|
|
142060
|
+
}), {
|
|
142061
|
+
status,
|
|
142062
|
+
headers: {
|
|
142063
|
+
"Content-Type": "application/json",
|
|
142064
|
+
"Cache-Control": "no-store"
|
|
142065
|
+
}
|
|
142066
|
+
});
|
|
142067
|
+
}
|
|
142068
|
+
async function callAnchor(env2, deps, sid, internalPath, body) {
|
|
142069
|
+
const stub = deps.getAnchorStub(env2, sid);
|
|
142070
|
+
const response = await stub.fetch(new URL(internalPath, DO_INTERNAL_ORIGIN).toString(), {
|
|
142071
|
+
method: "POST",
|
|
142072
|
+
headers: { "Content-Type": "application/json" },
|
|
142073
|
+
body: JSON.stringify(body)
|
|
142074
|
+
});
|
|
142075
|
+
return response;
|
|
142076
|
+
}
|
|
142077
|
+
async function ensureAnchor(env2, cfg, deps, sid, challenge, session) {
|
|
142078
|
+
const pin = challenge.challengePin && cfg.allowUnverifiedKeyidHolders ? { type: "keyid", valueSha256: sha256Hex(challenge.challengePin) } : void 0;
|
|
142079
|
+
const anchorUnavailable = {
|
|
142080
|
+
error: errorResponse(502, "anchor_unavailable", "The anchor store did not accept the registration")
|
|
142081
|
+
};
|
|
142082
|
+
let created;
|
|
142083
|
+
let body;
|
|
142084
|
+
try {
|
|
142085
|
+
created = await callAnchor(env2, deps, sid, INTERNAL_PICKUP_CREATE, {
|
|
142086
|
+
sid,
|
|
142087
|
+
requiredScopes: challenge.requiredScopes,
|
|
142088
|
+
pollIntervalS: cfg.pollIntervalS,
|
|
142089
|
+
anchorTtlS: cfg.anchorTtlS,
|
|
142090
|
+
delegationExpiresInS: cfg.delegationExpiresInS,
|
|
142091
|
+
agentDid: challenge.detectedAgentDid ?? session.agentDid,
|
|
142092
|
+
registeredAtMs: session.registeredAtMs,
|
|
142093
|
+
// Cross-resource claim inputs (drive the minted VC's aud / server_did —
|
|
142094
|
+
// see consent-anchor-bridge's withCrossResourceClaims).
|
|
142095
|
+
...challenge.audience ? { audience: challenge.audience } : {},
|
|
142096
|
+
...session.serverDid ? { serverDid: session.serverDid } : {},
|
|
142097
|
+
...pin ? { pin } : {}
|
|
142098
|
+
});
|
|
142099
|
+
if (created.status !== 201)
|
|
142100
|
+
return anchorUnavailable;
|
|
142101
|
+
body = await created.json();
|
|
142102
|
+
} catch (error87) {
|
|
142103
|
+
console.warn(`[kya-http] anchor create failed (sid=${sid}):`, error87 instanceof Error ? error87.message : String(error87));
|
|
142104
|
+
return anchorUnavailable;
|
|
142105
|
+
}
|
|
142106
|
+
if (!body.anchor || !Array.isArray(body.anchor.requiredScopes)) {
|
|
142107
|
+
return anchorUnavailable;
|
|
142108
|
+
}
|
|
142109
|
+
return { isNew: body.reused !== true, snapshot: body.anchor };
|
|
142110
|
+
}
|
|
142111
|
+
async function handleAnchorRegistration(c, env2, cfg, deps) {
|
|
142112
|
+
if (!registrarAuthorized(env2, c.req.header("Authorization"))) {
|
|
142113
|
+
return errorResponse(401, "unauthorized", "Invalid or missing API key");
|
|
142114
|
+
}
|
|
142115
|
+
if (registrationRateLimited(Date.now())) {
|
|
142116
|
+
return errorResponse(429, "rate_limited", "Too many anchor registrations; retry shortly");
|
|
142117
|
+
}
|
|
142118
|
+
let raw2;
|
|
142119
|
+
try {
|
|
142120
|
+
raw2 = await c.req.raw.clone().json();
|
|
142121
|
+
} catch {
|
|
142122
|
+
return errorResponse(400, "invalid_request", "Invalid request body", [
|
|
142123
|
+
{ path: "", message: "body must be JSON" }
|
|
142124
|
+
]);
|
|
142125
|
+
}
|
|
142126
|
+
const validated = validateRegistrationBody(raw2);
|
|
142127
|
+
if (!validated.ok) {
|
|
142128
|
+
return errorResponse(400, "invalid_request", "Invalid request body", validated.issues);
|
|
142129
|
+
}
|
|
142130
|
+
const { challenge } = validated.input;
|
|
142131
|
+
if (!challenge) {
|
|
142132
|
+
return errorResponse(401, "unauthorized", "This endpoint only accepts challenge registration");
|
|
142133
|
+
}
|
|
142134
|
+
const sid = deriveRegistrationSid(validated.input.sessionId);
|
|
142135
|
+
if (!challenge.audience) {
|
|
142136
|
+
console.warn(`[kya-http] external registration without challenge.audience (sid=${sid}): the minted credential will FAIL an org-pinned \xA74.3 audience gate; cross-resource use requires the registrar to send challenge.audience`);
|
|
142137
|
+
}
|
|
142138
|
+
const anchor = await ensureAnchor(env2, cfg, deps, sid, challenge, {
|
|
142139
|
+
agentDid: validated.input.agentDid,
|
|
142140
|
+
serverDid: validated.input.serverDid,
|
|
142141
|
+
registeredAtMs: validated.input.createdAt
|
|
142142
|
+
});
|
|
142143
|
+
if ("error" in anchor)
|
|
142144
|
+
return anchor.error;
|
|
142145
|
+
const host = cfg.realm || new URL(c.req.url).host;
|
|
142146
|
+
const verdict = {
|
|
142147
|
+
requiredScopes: anchor.snapshot.requiredScopes,
|
|
142148
|
+
authorizationHost: host,
|
|
142149
|
+
realm: host,
|
|
142150
|
+
sid,
|
|
142151
|
+
pollIntervalS: cfg.pollIntervalS
|
|
142152
|
+
};
|
|
142153
|
+
const consentUri = buildConsentUri(verdict);
|
|
142154
|
+
let challengeProof;
|
|
142155
|
+
try {
|
|
142156
|
+
challengeProof = await signChallengeProof(await deps.proofGenerator(), {
|
|
142157
|
+
sid,
|
|
142158
|
+
consent_uri: consentUri,
|
|
142159
|
+
required_scopes: anchor.snapshot.requiredScopes
|
|
142160
|
+
});
|
|
142161
|
+
} catch (error87) {
|
|
142162
|
+
console.warn(`[kya-http] registration challenge_proof signing failed (sid=${sid}):`, error87 instanceof Error ? error87.message : String(error87));
|
|
142163
|
+
return errorResponse(502, "proof_unavailable", "The challenge proof could not be signed");
|
|
142164
|
+
}
|
|
142165
|
+
const createdAtMs = anchor.snapshot.registeredAtMs ?? validated.input.createdAt;
|
|
142166
|
+
const issuedAtMs = anchor.snapshot.issuedAtMs ?? Date.now();
|
|
142167
|
+
return new Response(JSON.stringify({
|
|
142168
|
+
success: true,
|
|
142169
|
+
data: {
|
|
142170
|
+
session_id: sid,
|
|
142171
|
+
registered: true,
|
|
142172
|
+
created_at: new Date(createdAtMs).toISOString(),
|
|
142173
|
+
challenge: {
|
|
142174
|
+
consent_uri: consentUri,
|
|
142175
|
+
challenge_proof: challengeProof,
|
|
142176
|
+
required_scopes: anchor.snapshot.requiredScopes,
|
|
142177
|
+
issued_at: issuedAtMs,
|
|
142178
|
+
// ADDITIVE diagnostic (not in the frozen conformance key set, ignored
|
|
142179
|
+
// by both existing parsers): whether the minted credential will carry
|
|
142180
|
+
// the §4.3 cross-resource claims. False means no audience was
|
|
142181
|
+
// registered — the credential only self-verifies at this worker.
|
|
142182
|
+
cross_resource: typeof anchor.snapshot.audience === "string"
|
|
142183
|
+
}
|
|
142184
|
+
}
|
|
142185
|
+
}), {
|
|
142186
|
+
status: anchor.isNew ? 201 : 200,
|
|
142187
|
+
headers: {
|
|
142188
|
+
"Content-Type": "application/json",
|
|
142189
|
+
// Checkpoint's route parity (its success responses are private/no-cache).
|
|
142190
|
+
"Cache-Control": "private, no-cache"
|
|
142191
|
+
}
|
|
142192
|
+
});
|
|
142193
|
+
}
|
|
142194
|
+
|
|
141735
142195
|
// ../mcp-i-cloudflare/dist/agent.js
|
|
141736
142196
|
init_storage_keys();
|
|
141737
142197
|
|
|
@@ -144166,7 +144626,7 @@ var MCPICloudflareAgent = class extends McpAgent {
|
|
|
144166
144626
|
const mappedEnv = envPrefix ? mapPrefixedEnv(this.env, envPrefix) : this.env;
|
|
144167
144627
|
const runtimeConfig = this.getRuntimeConfigInternal(mappedEnv);
|
|
144168
144628
|
const httpChallengeCfg = resolveHttpChallengeConfig(runtimeConfig, mappedEnv);
|
|
144169
|
-
const augmented = augmentKyaOsIdentityWellKnown(wellKnownPath, result, httpChallengeCfg);
|
|
144629
|
+
const augmented = augmentKyaOsIdentityWellKnown(wellKnownPath, result, httpChallengeCfg, isAnchorRegistrationEnabled(httpChallengeCfg, mappedEnv));
|
|
144170
144630
|
return new Response(JSON.stringify(augmented), {
|
|
144171
144631
|
status: 200,
|
|
144172
144632
|
headers: { "Content-Type": "application/json" }
|
|
@@ -146908,12 +147368,6 @@ var cors = (options) => {
|
|
|
146908
147368
|
};
|
|
146909
147369
|
};
|
|
146910
147370
|
|
|
146911
|
-
// ../mcp-i-cloudflare/dist/delegation-http/sid.js
|
|
146912
|
-
var ANCHOR_SID_RE = /^kya-[0-9a-f]{16,64}$/;
|
|
146913
|
-
function isAnchorSid(s5) {
|
|
146914
|
-
return typeof s5 === "string" && ANCHOR_SID_RE.test(s5);
|
|
146915
|
-
}
|
|
146916
|
-
|
|
146917
147371
|
// ../mcp-i-cloudflare/dist/delegation-http/anchor-routing.js
|
|
146918
147372
|
function anchorInstanceId(sid) {
|
|
146919
147373
|
return `pickup:${sid}`;
|
|
@@ -146973,10 +147427,10 @@ async function handlePickupGet(c, env2, cfg) {
|
|
|
146973
147427
|
init_dist2();
|
|
146974
147428
|
init_crypto();
|
|
146975
147429
|
init_storage();
|
|
146976
|
-
var
|
|
146977
|
-
async function
|
|
147430
|
+
var DO_INTERNAL_ORIGIN2 = "https://do.internal";
|
|
147431
|
+
async function callAnchor2(env2, sid, internalPath, body) {
|
|
146978
147432
|
const stub = getAnchorStub(env2, sid);
|
|
146979
|
-
const response = await stub.fetch(new URL(internalPath,
|
|
147433
|
+
const response = await stub.fetch(new URL(internalPath, DO_INTERNAL_ORIGIN2).toString(), {
|
|
146980
147434
|
method: "POST",
|
|
146981
147435
|
headers: { "Content-Type": "application/json" },
|
|
146982
147436
|
body: JSON.stringify(body)
|
|
@@ -147109,6 +147563,17 @@ function isTestConsentMode(env2) {
|
|
|
147109
147563
|
const environment = String(bag.ENVIRONMENT ?? bag.MCPI_ENV ?? "").toLowerCase();
|
|
147110
147564
|
return environment === "development";
|
|
147111
147565
|
}
|
|
147566
|
+
function withCrossResourceClaims(unsigned, info, sid) {
|
|
147567
|
+
if (!info.audience)
|
|
147568
|
+
return unsigned.signingInput;
|
|
147569
|
+
const payload = {
|
|
147570
|
+
...unsigned.payload,
|
|
147571
|
+
aud: info.audience,
|
|
147572
|
+
sid,
|
|
147573
|
+
...info.serverDid ? { server_did: info.serverDid } : {}
|
|
147574
|
+
};
|
|
147575
|
+
return `${unsigned.encodedHeader}.${base64UrlEncodeString(JSON.stringify(payload))}`;
|
|
147576
|
+
}
|
|
147112
147577
|
async function mintDelegationVcJwt(env2, sid, info, expiresInS) {
|
|
147113
147578
|
const cryptoProvider = new WebCryptoProvider();
|
|
147114
147579
|
const configuredIdentity = getConfiguredIdentity(env2);
|
|
@@ -147125,7 +147590,7 @@ async function mintDelegationVcJwt(env2, sid, info, expiresInS) {
|
|
|
147125
147590
|
keyId = `${issuerDid}#${didKeyFragment2(issuerDid)}`;
|
|
147126
147591
|
signingPrivateKey = rawKeyPair.privateKey;
|
|
147127
147592
|
}
|
|
147128
|
-
const agentDid = env2.MCP_IDENTITY_AGENT_DID || issuerDid;
|
|
147593
|
+
const agentDid = info.agentDid || env2.MCP_IDENTITY_AGENT_DID || issuerDid;
|
|
147129
147594
|
const nowS = Math.floor(Date.now() / 1e3);
|
|
147130
147595
|
const delegation = {
|
|
147131
147596
|
id: `urn:uuid:${sid}`,
|
|
@@ -147135,7 +147600,11 @@ async function mintDelegationVcJwt(env2, sid, info, expiresInS) {
|
|
|
147135
147600
|
constraints: {
|
|
147136
147601
|
scopes: info.requiredScopes,
|
|
147137
147602
|
notBefore: nowS,
|
|
147138
|
-
notAfter: nowS + expiresInS
|
|
147603
|
+
notAfter: nowS + expiresInS,
|
|
147604
|
+
// §11.7 outer===inner audience invariant (checkpoint's own mints bind the
|
|
147605
|
+
// audience in BOTH the JWT aud and constraints.audience): set the inner
|
|
147606
|
+
// half for cross-resource anchors so verifiers reading either slot agree.
|
|
147607
|
+
...info.audience ? { audience: info.audience } : {}
|
|
147139
147608
|
},
|
|
147140
147609
|
signature: "",
|
|
147141
147610
|
status: "active",
|
|
@@ -147146,13 +147615,14 @@ async function mintDelegationVcJwt(env2, sid, info, expiresInS) {
|
|
|
147146
147615
|
issuanceDate: (/* @__PURE__ */ new Date()).toISOString()
|
|
147147
147616
|
});
|
|
147148
147617
|
const vcWithIssuer = { ...unsignedVC, issuer: issuerDid };
|
|
147149
|
-
const
|
|
147618
|
+
const unsigned = createUnsignedVCJWT2(vcWithIssuer, { keyId });
|
|
147619
|
+
const signingInput = withCrossResourceClaims(unsigned, info, sid);
|
|
147150
147620
|
const signatureBytes = await cryptoProvider.sign(new TextEncoder().encode(signingInput), signingPrivateKey);
|
|
147151
147621
|
const signature = base64urlEncodeFromBytes2(signatureBytes);
|
|
147152
147622
|
return completeVCJWT2(signingInput, signature);
|
|
147153
147623
|
}
|
|
147154
147624
|
async function handleAnchorConsentGet(c, sid, env2, _cfg) {
|
|
147155
|
-
const infoResponse = await
|
|
147625
|
+
const infoResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_INFO, {
|
|
147156
147626
|
sid
|
|
147157
147627
|
});
|
|
147158
147628
|
if (infoResponse.status === 404)
|
|
@@ -147174,7 +147644,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
|
|
|
147174
147644
|
return htmlResponse(page("Authorization failed", `<main class="kya-consent-failed"><h1>Authorization failed</h1><p>Invalid or missing security token. Please reload and try again.</p></main>`), 403);
|
|
147175
147645
|
}
|
|
147176
147646
|
}
|
|
147177
|
-
const infoResponse = await
|
|
147647
|
+
const infoResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_INFO, {
|
|
147178
147648
|
sid
|
|
147179
147649
|
});
|
|
147180
147650
|
if (infoResponse.status === 404)
|
|
@@ -147193,7 +147663,7 @@ async function handleAnchorConsentApprove(c, sid, env2, cfg) {
|
|
|
147193
147663
|
console.warn(`[kya-http] delegation mint failed (sid=${sid}):`, error87 instanceof Error ? error87.message : String(error87));
|
|
147194
147664
|
return approvalFailedPage("We could not complete the authorization. Please start over.", 500);
|
|
147195
147665
|
}
|
|
147196
|
-
const approveResponse = await
|
|
147666
|
+
const approveResponse = await callAnchor2(env2, sid, INTERNAL_PICKUP_APPROVE, {
|
|
147197
147667
|
sid,
|
|
147198
147668
|
vcJwt,
|
|
147199
147669
|
expiresInS: cfg.delegationExpiresInS
|
|
@@ -147237,7 +147707,7 @@ function resolveRequest(c, options) {
|
|
|
147237
147707
|
return { env: c.env, cfg: null };
|
|
147238
147708
|
}
|
|
147239
147709
|
}
|
|
147240
|
-
function registerDelegationHttpRoutes(app, options) {
|
|
147710
|
+
function registerDelegationHttpRoutes(app, options, deps) {
|
|
147241
147711
|
app.get(PICKUP_ROUTE, async (c, next) => {
|
|
147242
147712
|
const { env: env2, cfg } = resolveRequest(c, options);
|
|
147243
147713
|
if (!cfg)
|
|
@@ -147258,6 +147728,17 @@ function registerDelegationHttpRoutes(app, options) {
|
|
|
147258
147728
|
return next();
|
|
147259
147729
|
return handleAnchorConsentApprove(c, sid, env2, cfg);
|
|
147260
147730
|
});
|
|
147731
|
+
const proofGenerator = deps?.proofGenerator;
|
|
147732
|
+
app.post(ANCHOR_REGISTRATION_ROUTE, async (c, next) => {
|
|
147733
|
+
const { env: env2, cfg } = resolveRequest(c, options);
|
|
147734
|
+
if (!cfg || !isAnchorRegistrationEnabled(cfg, env2) || !proofGenerator) {
|
|
147735
|
+
return next();
|
|
147736
|
+
}
|
|
147737
|
+
return handleAnchorRegistration(c, env2, cfg, {
|
|
147738
|
+
getAnchorStub,
|
|
147739
|
+
proofGenerator: () => proofGenerator(c)
|
|
147740
|
+
});
|
|
147741
|
+
});
|
|
147261
147742
|
}
|
|
147262
147743
|
|
|
147263
147744
|
// ../mcp-i-cloudflare/dist/delegation-http/bearer-retry.js
|
|
@@ -147360,100 +147841,6 @@ async function applyBearerDelegation(request, env2, _cfg) {
|
|
|
147360
147841
|
return { request: rewritten };
|
|
147361
147842
|
}
|
|
147362
147843
|
|
|
147363
|
-
// ../mcp-i-cloudflare/dist/delegation-http/challenge.js
|
|
147364
|
-
var CHALLENGE_PROOF_METHOD = "kyaos/challenge";
|
|
147365
|
-
function buildWWWAuthenticateDelegation(i2) {
|
|
147366
|
-
const values = {
|
|
147367
|
-
realm: i2.realm,
|
|
147368
|
-
sid: i2.sid,
|
|
147369
|
-
consent_uri: buildConsentUri(i2),
|
|
147370
|
-
pickup_uri: buildPickupUri(i2),
|
|
147371
|
-
scope: i2.requiredScopes.join(" "),
|
|
147372
|
-
min_assurance: i2.minAssurance,
|
|
147373
|
-
interval: String(i2.pollIntervalS),
|
|
147374
|
-
kind: "delegation"
|
|
147375
|
-
};
|
|
147376
|
-
const params = CHALLENGE_PARAM_ORDER.filter(
|
|
147377
|
-
// min_assurance is the only optional param: omit the whole token when absent.
|
|
147378
|
-
(key) => values[key] !== void 0
|
|
147379
|
-
).map((key) => `${key}="${values[key]}"`);
|
|
147380
|
-
return `Delegation ${params.join(", ")}`;
|
|
147381
|
-
}
|
|
147382
|
-
function buildWWWAuthenticateBearer(realm) {
|
|
147383
|
-
return `Bearer resource_metadata="https://${realm}/.well-known/oauth-protected-resource"`;
|
|
147384
|
-
}
|
|
147385
|
-
function buildConsentUri(i2) {
|
|
147386
|
-
return `https://${i2.authorizationHost}/consent?sid=${i2.sid}`;
|
|
147387
|
-
}
|
|
147388
|
-
function buildPickupUri(i2) {
|
|
147389
|
-
return `https://${i2.authorizationHost}/api/delegation/pickup/${i2.sid}`;
|
|
147390
|
-
}
|
|
147391
|
-
function buildInstructions(i2) {
|
|
147392
|
-
const consentUri = buildConsentUri(i2);
|
|
147393
|
-
const pickupUri = buildPickupUri(i2);
|
|
147394
|
-
return `This action requires human authorization. Show your user this link and ask them to approve: ${consentUri}. Then poll ${pickupUri} every ${i2.pollIntervalS} seconds. If you can sign HTTP requests, sign each poll with an ephemeral did:key; otherwise generate one random 32-byte token and send it as X-KYA-Pickup-Token on EVERY poll. When the response status is 200, take the 'delegation' value and retry your original request with header 'Authorization: Bearer <delegation>'.`;
|
|
147395
|
-
}
|
|
147396
|
-
function buildChallengeBody(i2, challengeProof) {
|
|
147397
|
-
const kyaos = {
|
|
147398
|
-
sid: i2.sid,
|
|
147399
|
-
consent_uri: buildConsentUri(i2),
|
|
147400
|
-
pickup_uri: buildPickupUri(i2),
|
|
147401
|
-
required_scopes: i2.requiredScopes
|
|
147402
|
-
};
|
|
147403
|
-
if (i2.minAssurance !== void 0) {
|
|
147404
|
-
kyaos.min_assurance = i2.minAssurance;
|
|
147405
|
-
}
|
|
147406
|
-
kyaos.poll_interval_s = i2.pollIntervalS;
|
|
147407
|
-
kyaos.challenge_proof = challengeProof;
|
|
147408
|
-
return {
|
|
147409
|
-
error: KYAOS_ERRORS.authorizationRequired,
|
|
147410
|
-
kyaos,
|
|
147411
|
-
instructions: buildInstructions(i2)
|
|
147412
|
-
};
|
|
147413
|
-
}
|
|
147414
|
-
function buildChallengeResponse(i2, challengeProof) {
|
|
147415
|
-
const headers = new Headers();
|
|
147416
|
-
headers.append("WWW-Authenticate", buildWWWAuthenticateDelegation(i2));
|
|
147417
|
-
headers.append("WWW-Authenticate", buildWWWAuthenticateBearer(i2.realm));
|
|
147418
|
-
headers.set("Retry-After", String(i2.pollIntervalS));
|
|
147419
|
-
headers.set("Content-Type", "application/json");
|
|
147420
|
-
headers.set("Cache-Control", "no-store");
|
|
147421
|
-
return new Response(JSON.stringify(buildChallengeBody(i2, challengeProof)), {
|
|
147422
|
-
status: 401,
|
|
147423
|
-
headers
|
|
147424
|
-
});
|
|
147425
|
-
}
|
|
147426
|
-
function buildFetcherChallengeResponse(i2, challengeProof) {
|
|
147427
|
-
const consentUri = buildConsentUri(i2);
|
|
147428
|
-
const headers = new Headers();
|
|
147429
|
-
headers.set("Content-Type", "application/json");
|
|
147430
|
-
headers.set("Cache-Control", "no-store");
|
|
147431
|
-
headers.set("KYA-Auth-Required", "true");
|
|
147432
|
-
headers.set("KYA-Auth-Url", consentUri);
|
|
147433
|
-
headers.set("Link", `<${consentUri}>; rel="kya-authorize"`);
|
|
147434
|
-
headers.set("KYA-Action", "challenge");
|
|
147435
|
-
return new Response(JSON.stringify(buildChallengeBody(i2, challengeProof)), {
|
|
147436
|
-
status: 200,
|
|
147437
|
-
headers
|
|
147438
|
-
});
|
|
147439
|
-
}
|
|
147440
|
-
async function signChallengeProof(gen, payload) {
|
|
147441
|
-
const proof = await gen.generateProof({
|
|
147442
|
-
method: CHALLENGE_PROOF_METHOD,
|
|
147443
|
-
params: {
|
|
147444
|
-
sid: payload.sid,
|
|
147445
|
-
consent_uri: payload.consent_uri,
|
|
147446
|
-
required_scopes: payload.required_scopes
|
|
147447
|
-
}
|
|
147448
|
-
}, { data: { sid: payload.sid } }, {
|
|
147449
|
-
// The session binds the proof to this anchor; sid is the natural nonce.
|
|
147450
|
-
nonce: payload.sid,
|
|
147451
|
-
audience: payload.consent_uri,
|
|
147452
|
-
sessionId: payload.sid
|
|
147453
|
-
});
|
|
147454
|
-
return proof.jws;
|
|
147455
|
-
}
|
|
147456
|
-
|
|
147457
147844
|
// ../mcp-i-cloudflare/dist/delegation-http/challenge-middleware.js
|
|
147458
147845
|
async function readAuthorizationRequiredMeta(response) {
|
|
147459
147846
|
let parsed;
|
|
@@ -147656,7 +148043,9 @@ function createMCPIApp(options) {
|
|
|
147656
148043
|
});
|
|
147657
148044
|
}
|
|
147658
148045
|
});
|
|
147659
|
-
registerDelegationHttpRoutes(app, options
|
|
148046
|
+
registerDelegationHttpRoutes(app, options, {
|
|
148047
|
+
proofGenerator: (c) => buildChallengeProofGenerator(c)
|
|
148048
|
+
});
|
|
147660
148049
|
app.get("/consent.js", async (c) => {
|
|
147661
148050
|
const server = await getMcpiServer(c.env);
|
|
147662
148051
|
return server.handleRequest(c.req.raw, c.executionCtx);
|