@kya-os/mcp-i-core 1.7.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/conformance/capability-verifier-adapter.d.ts +66 -0
- package/dist/conformance/capability-verifier-adapter.js +61 -0
- package/dist/conformance/index.d.ts +10 -0
- package/dist/conformance/index.js +19 -0
- package/dist/conformance/validate-level2.d.ts +203 -0
- package/dist/conformance/validate-level2.js +294 -0
- package/dist/conformance/vc-jwt-verifier.d.ts +55 -0
- package/dist/conformance/vc-jwt-verifier.js +147 -0
- package/dist/delegation/did-web-resolver.d.ts +60 -0
- package/dist/delegation/did-web-resolver.js +129 -0
- package/dist/delegation/outbound-proof.d.ts +3 -2
- package/dist/delegation/outbound-proof.js +3 -2
- package/dist/delegation/utils.d.ts +3 -1
- package/dist/index.d.ts +9 -63
- package/dist/index.js +22 -161
- package/dist/utils/base58.d.ts +4 -28
- package/dist/utils/base58.js +18 -98
- package/dist/utils/base64.d.ts +4 -29
- package/dist/utils/base64.js +18 -167
- package/dist/utils/did-helpers.d.ts +4 -165
- package/dist/utils/did-helpers.js +18 -217
- package/package.json +5 -7
- package/dist/auth/handshake.d.ts +0 -119
- package/dist/auth/handshake.js +0 -250
- package/dist/auth/index.d.ts +0 -6
- package/dist/auth/index.js +0 -11
- package/dist/auth/types.d.ts +0 -46
- package/dist/auth/types.js +0 -10
- package/dist/cache/oauth-config-cache.d.ts +0 -69
- package/dist/cache/oauth-config-cache.js +0 -76
- package/dist/cache/tool-protection-cache.d.ts +0 -89
- package/dist/cache/tool-protection-cache.js +0 -118
- package/dist/compliance/index.d.ts +0 -8
- package/dist/compliance/index.js +0 -24
- package/dist/compliance/schema-registry.d.ts +0 -50
- package/dist/compliance/schema-registry.js +0 -438
- package/dist/compliance/schema-verifier.d.ts +0 -110
- package/dist/compliance/schema-verifier.js +0 -518
- package/dist/config/remote-config.d.ts +0 -173
- package/dist/config/remote-config.js +0 -253
- package/dist/config.d.ts +0 -182
- package/dist/config.js +0 -148
- package/dist/identity/idp-token-resolver.d.ts +0 -69
- package/dist/identity/idp-token-resolver.js +0 -136
- package/dist/identity/idp-token-storage.interface.d.ts +0 -80
- package/dist/identity/idp-token-storage.interface.js +0 -14
- package/dist/identity/user-did-manager.d.ts +0 -228
- package/dist/identity/user-did-manager.js +0 -356
- package/dist/logging/index.d.ts +0 -5
- package/dist/logging/index.js +0 -10
- package/dist/logging/logger.d.ts +0 -33
- package/dist/logging/logger.js +0 -104
- package/dist/proof/generator.d.ts +0 -109
- package/dist/proof/generator.js +0 -236
- package/dist/proof/index.d.ts +0 -5
- package/dist/proof/index.js +0 -11
- package/dist/providers/base.d.ts +0 -95
- package/dist/providers/base.js +0 -47
- package/dist/providers/memory.d.ts +0 -42
- package/dist/providers/memory.js +0 -121
- package/dist/runtime/audit-logger.d.ts +0 -37
- package/dist/runtime/audit-logger.js +0 -9
- package/dist/runtime/base.d.ts +0 -375
- package/dist/runtime/base.js +0 -1491
- package/dist/runtime/ext-apps-constants.d.ts +0 -14
- package/dist/runtime/ext-apps-constants.js +0 -17
- package/dist/services/access-control.service.d.ts +0 -138
- package/dist/services/access-control.service.js +0 -721
- package/dist/services/authorization/authorization-registry.d.ts +0 -29
- package/dist/services/authorization/authorization-registry.js +0 -58
- package/dist/services/authorization/types.d.ts +0 -53
- package/dist/services/authorization/types.js +0 -10
- package/dist/services/batch-delegation.service.d.ts +0 -53
- package/dist/services/batch-delegation.service.js +0 -95
- package/dist/services/crypto.service.d.ts +0 -69
- package/dist/services/crypto.service.js +0 -225
- package/dist/services/delegation-error-formatter.d.ts +0 -124
- package/dist/services/delegation-error-formatter.js +0 -214
- package/dist/services/errors.d.ts +0 -49
- package/dist/services/errors.js +0 -66
- package/dist/services/index.d.ts +0 -9
- package/dist/services/index.js +0 -15
- package/dist/services/oauth-config.service.d.ts +0 -53
- package/dist/services/oauth-config.service.js +0 -141
- package/dist/services/oauth-provider-registry.d.ts +0 -88
- package/dist/services/oauth-provider-registry.js +0 -128
- package/dist/services/oauth-service.d.ts +0 -122
- package/dist/services/oauth-service.js +0 -442
- package/dist/services/oauth-token-retrieval.service.d.ts +0 -49
- package/dist/services/oauth-token-retrieval.service.js +0 -150
- package/dist/services/policy.service.d.ts +0 -130
- package/dist/services/policy.service.js +0 -399
- package/dist/services/proof-verifier.d.ts +0 -98
- package/dist/services/proof-verifier.js +0 -319
- package/dist/services/provider-resolver.d.ts +0 -89
- package/dist/services/provider-resolver.js +0 -196
- package/dist/services/provider-validator.d.ts +0 -55
- package/dist/services/provider-validator.js +0 -135
- package/dist/services/session-registration.service.d.ts +0 -80
- package/dist/services/session-registration.service.js +0 -174
- package/dist/services/storage.service.d.ts +0 -116
- package/dist/services/storage.service.js +0 -411
- package/dist/services/tool-context-builder.d.ts +0 -74
- package/dist/services/tool-context-builder.js +0 -215
- package/dist/services/tool-protection.service.d.ts +0 -193
- package/dist/services/tool-protection.service.js +0 -736
- package/dist/session/index.d.ts +0 -5
- package/dist/session/index.js +0 -11
- package/dist/session/manager.d.ts +0 -113
- package/dist/session/manager.js +0 -273
- package/dist/types/oauth-required-error.d.ts +0 -46
- package/dist/types/oauth-required-error.js +0 -42
- package/dist/types/tool-protection.d.ts +0 -144
- package/dist/types/tool-protection.js +0 -48
- package/dist/utils/cors.d.ts +0 -44
- package/dist/utils/cors.js +0 -71
- package/dist/utils/index.d.ts +0 -8
- package/dist/utils/index.js +0 -24
- package/dist/utils/storage-keys.d.ts +0 -120
- package/dist/utils/storage-keys.js +0 -217
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* ProofVerifier
|
|
4
|
-
*
|
|
5
|
-
* Centralized proof verification service that validates DetachedProof
|
|
6
|
-
* signatures, enforces nonce replay protection, and checks timestamp skew.
|
|
7
|
-
*/
|
|
8
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
-
exports.ProofVerifier = void 0;
|
|
10
|
-
const crypto_service_js_1 = require("./crypto.service.js");
|
|
11
|
-
const proof_1 = require("@kya-os/contracts/proof");
|
|
12
|
-
const json_canonicalize_1 = require("json-canonicalize");
|
|
13
|
-
const errors_js_1 = require("./errors.js");
|
|
14
|
-
class ProofVerifier {
|
|
15
|
-
cryptoService;
|
|
16
|
-
clock;
|
|
17
|
-
nonceCache;
|
|
18
|
-
fetch;
|
|
19
|
-
timestampSkewSeconds;
|
|
20
|
-
nonceTtlSeconds;
|
|
21
|
-
constructor(config) {
|
|
22
|
-
this.cryptoService = new crypto_service_js_1.CryptoService(config.cryptoProvider);
|
|
23
|
-
this.clock = config.clockProvider;
|
|
24
|
-
this.nonceCache = config.nonceCacheProvider;
|
|
25
|
-
this.fetch = config.fetchProvider;
|
|
26
|
-
this.timestampSkewSeconds = config.timestampSkewSeconds ?? 300; // Default 5 minutes
|
|
27
|
-
this.nonceTtlSeconds = config.nonceTtlSeconds ?? 300; // Default 5 minutes
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Verify a DetachedProof
|
|
31
|
-
* Automatically reconstructs canonical payload from proof.meta for signature verification
|
|
32
|
-
* @param proof - The proof to verify
|
|
33
|
-
* @param publicKeyJwk - Ed25519 public key in JWK format (from DID document)
|
|
34
|
-
* @returns Verification result
|
|
35
|
-
*/
|
|
36
|
-
async verifyProof(proof, publicKeyJwk) {
|
|
37
|
-
try {
|
|
38
|
-
// 1. Validate proof structure
|
|
39
|
-
const structureValidation = await this.validateProofStructure(proof);
|
|
40
|
-
if (!structureValidation.valid) {
|
|
41
|
-
return structureValidation;
|
|
42
|
-
}
|
|
43
|
-
const validatedProof = structureValidation.proof;
|
|
44
|
-
// 2. Check nonce replay protection (scoped to agent DID to prevent cross-agent replay attacks)
|
|
45
|
-
const nonceValidation = await this.validateNonce(validatedProof.meta.nonce, validatedProof.meta.did);
|
|
46
|
-
if (!nonceValidation.valid) {
|
|
47
|
-
return nonceValidation;
|
|
48
|
-
}
|
|
49
|
-
// 3. Check timestamp skew
|
|
50
|
-
const timestampValidation = await this.validateTimestamp(validatedProof.meta.ts);
|
|
51
|
-
if (!timestampValidation.valid) {
|
|
52
|
-
return timestampValidation;
|
|
53
|
-
}
|
|
54
|
-
// 4. Reconstruct canonical payload from proof meta
|
|
55
|
-
const canonicalPayloadString = this.buildCanonicalPayload(validatedProof.meta);
|
|
56
|
-
const canonicalPayloadBytes = new TextEncoder().encode(canonicalPayloadString);
|
|
57
|
-
// 5. Verify JWS signature with detached canonical payload
|
|
58
|
-
const signatureValidation = await this.verifySignature(validatedProof.jws, publicKeyJwk, canonicalPayloadBytes, validatedProof.meta.kid);
|
|
59
|
-
if (!signatureValidation.valid) {
|
|
60
|
-
return signatureValidation;
|
|
61
|
-
}
|
|
62
|
-
// 6. Add nonce to cache to prevent replay (scoped to agent DID)
|
|
63
|
-
await this.addNonceToCache(validatedProof.meta.nonce, validatedProof.meta.did);
|
|
64
|
-
return {
|
|
65
|
-
valid: true,
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
// Security-safe failure: never throw, always return error result
|
|
70
|
-
return {
|
|
71
|
-
valid: false,
|
|
72
|
-
reason: "Proof verification error",
|
|
73
|
-
errorCode: errors_js_1.PROOF_VERIFICATION_ERROR_CODES.VERIFICATION_ERROR,
|
|
74
|
-
error: error instanceof Error ? error : new Error(String(error)),
|
|
75
|
-
details: {
|
|
76
|
-
errorMessage: error instanceof Error ? error.message : String(error),
|
|
77
|
-
},
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Verify proof with detached payload (for CLI/verifier compatibility)
|
|
83
|
-
* @param proof - The proof to verify
|
|
84
|
-
* @param canonicalPayload - Canonical JSON payload (for detached JWS) as string or Uint8Array
|
|
85
|
-
* @param publicKeyJwk - Ed25519 public key in JWK format
|
|
86
|
-
* @returns Verification result
|
|
87
|
-
*/
|
|
88
|
-
async verifyProofDetached(proof, canonicalPayload, publicKeyJwk) {
|
|
89
|
-
try {
|
|
90
|
-
// 1. Validate proof structure
|
|
91
|
-
const structureValidation = await this.validateProofStructure(proof);
|
|
92
|
-
if (!structureValidation.valid) {
|
|
93
|
-
return structureValidation;
|
|
94
|
-
}
|
|
95
|
-
const validatedProof = structureValidation.proof;
|
|
96
|
-
// 2. Check nonce replay protection (scoped to agent DID to prevent cross-agent replay attacks)
|
|
97
|
-
const nonceValidation = await this.validateNonce(validatedProof.meta.nonce, validatedProof.meta.did);
|
|
98
|
-
if (!nonceValidation.valid) {
|
|
99
|
-
return nonceValidation;
|
|
100
|
-
}
|
|
101
|
-
// 3. Check timestamp skew
|
|
102
|
-
const timestampValidation = await this.validateTimestamp(validatedProof.meta.ts);
|
|
103
|
-
if (!timestampValidation.valid) {
|
|
104
|
-
return timestampValidation;
|
|
105
|
-
}
|
|
106
|
-
// 4. Convert canonical payload to Uint8Array if needed
|
|
107
|
-
const canonicalPayloadBytes = canonicalPayload instanceof Uint8Array
|
|
108
|
-
? canonicalPayload
|
|
109
|
-
: new TextEncoder().encode(canonicalPayload);
|
|
110
|
-
// 5. Verify JWS signature with detached payload
|
|
111
|
-
const signatureValidation = await this.verifySignature(validatedProof.jws, publicKeyJwk, canonicalPayloadBytes, validatedProof.meta.kid);
|
|
112
|
-
if (!signatureValidation.valid) {
|
|
113
|
-
return signatureValidation;
|
|
114
|
-
}
|
|
115
|
-
// 6. Add nonce to cache (scoped to agent DID)
|
|
116
|
-
await this.addNonceToCache(validatedProof.meta.nonce, validatedProof.meta.did);
|
|
117
|
-
return {
|
|
118
|
-
valid: true,
|
|
119
|
-
};
|
|
120
|
-
}
|
|
121
|
-
catch (error) {
|
|
122
|
-
// Security-safe failure: never throw, always return error result
|
|
123
|
-
return {
|
|
124
|
-
valid: false,
|
|
125
|
-
reason: "Proof verification error",
|
|
126
|
-
errorCode: errors_js_1.PROOF_VERIFICATION_ERROR_CODES.VERIFICATION_ERROR,
|
|
127
|
-
error: error instanceof Error ? error : new Error(String(error)),
|
|
128
|
-
details: {
|
|
129
|
-
errorMessage: error instanceof Error ? error.message : String(error),
|
|
130
|
-
},
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* Validate proof structure using Zod schema
|
|
136
|
-
* @private
|
|
137
|
-
*/
|
|
138
|
-
async validateProofStructure(proof) {
|
|
139
|
-
const validationResult = proof_1.DetachedProofSchema.safeParse(proof);
|
|
140
|
-
if (!validationResult.success) {
|
|
141
|
-
return {
|
|
142
|
-
valid: false,
|
|
143
|
-
reason: "Invalid proof structure",
|
|
144
|
-
errorCode: errors_js_1.PROOF_VERIFICATION_ERROR_CODES.INVALID_PROOF_STRUCTURE,
|
|
145
|
-
error: new Error(`Proof validation failed: ${validationResult.error.message}`),
|
|
146
|
-
details: {
|
|
147
|
-
zodErrors: validationResult.error.errors,
|
|
148
|
-
},
|
|
149
|
-
};
|
|
150
|
-
}
|
|
151
|
-
return {
|
|
152
|
-
valid: true,
|
|
153
|
-
proof: validationResult.data,
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Validate nonce replay protection
|
|
158
|
-
* @private
|
|
159
|
-
*/
|
|
160
|
-
async validateNonce(nonce, agentDid) {
|
|
161
|
-
const nonceUsed = await this.nonceCache.has(nonce, agentDid);
|
|
162
|
-
if (nonceUsed) {
|
|
163
|
-
return {
|
|
164
|
-
valid: false,
|
|
165
|
-
reason: "Nonce already used (replay attack detected)",
|
|
166
|
-
errorCode: errors_js_1.PROOF_VERIFICATION_ERROR_CODES.NONCE_REPLAY_DETECTED,
|
|
167
|
-
details: {
|
|
168
|
-
nonce,
|
|
169
|
-
agentDid,
|
|
170
|
-
},
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
return { valid: true };
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Validate timestamp skew
|
|
177
|
-
* @private
|
|
178
|
-
*/
|
|
179
|
-
async validateTimestamp(timestamp) {
|
|
180
|
-
// Convert seconds to milliseconds for clock provider (which uses Date.now())
|
|
181
|
-
const timestampMs = timestamp * 1000;
|
|
182
|
-
if (!this.clock.isWithinSkew(timestampMs, this.timestampSkewSeconds)) {
|
|
183
|
-
return {
|
|
184
|
-
valid: false,
|
|
185
|
-
reason: `Timestamp out of skew window (skew: ${this.timestampSkewSeconds}s)`,
|
|
186
|
-
errorCode: errors_js_1.PROOF_VERIFICATION_ERROR_CODES.TIMESTAMP_SKEW_EXCEEDED,
|
|
187
|
-
details: {
|
|
188
|
-
timestamp,
|
|
189
|
-
timestampMs,
|
|
190
|
-
skewSeconds: this.timestampSkewSeconds,
|
|
191
|
-
currentTime: this.clock.now(),
|
|
192
|
-
},
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
return { valid: true };
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* Verify JWS signature
|
|
199
|
-
* @private
|
|
200
|
-
*/
|
|
201
|
-
async verifySignature(jws, publicKeyJwk, canonicalPayloadBytes, expectedKid) {
|
|
202
|
-
const signatureValid = await this.cryptoService.verifyJWS(jws, publicKeyJwk, {
|
|
203
|
-
detachedPayload: canonicalPayloadBytes,
|
|
204
|
-
expectedKid,
|
|
205
|
-
alg: "EdDSA",
|
|
206
|
-
});
|
|
207
|
-
if (!signatureValid) {
|
|
208
|
-
return {
|
|
209
|
-
valid: false,
|
|
210
|
-
reason: "Invalid JWS signature",
|
|
211
|
-
errorCode: errors_js_1.PROOF_VERIFICATION_ERROR_CODES.INVALID_JWS_SIGNATURE,
|
|
212
|
-
details: {
|
|
213
|
-
jwsLength: jws.length,
|
|
214
|
-
expectedKid,
|
|
215
|
-
actualKid: publicKeyJwk.kid,
|
|
216
|
-
},
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
return { valid: true };
|
|
220
|
-
}
|
|
221
|
-
/**
|
|
222
|
-
* Add nonce to cache to prevent replay (scoped to agent DID)
|
|
223
|
-
* @private
|
|
224
|
-
*/
|
|
225
|
-
async addNonceToCache(nonce, agentDid) {
|
|
226
|
-
// Pass TTL in seconds, not absolute timestamp
|
|
227
|
-
await this.nonceCache.add(nonce, this.nonceTtlSeconds, agentDid);
|
|
228
|
-
}
|
|
229
|
-
/**
|
|
230
|
-
* Fetch public key from DID document
|
|
231
|
-
* @param did - DID to resolve
|
|
232
|
-
* @param kid - Key ID (optional, defaults to first verification method)
|
|
233
|
-
* @returns Ed25519 JWK or null if not found
|
|
234
|
-
* @throws {ProofVerificationError} If DID resolution fails with specific error code
|
|
235
|
-
*/
|
|
236
|
-
async fetchPublicKeyFromDID(did, kid) {
|
|
237
|
-
try {
|
|
238
|
-
const didDoc = await this.fetch.resolveDID(did);
|
|
239
|
-
if (!didDoc) {
|
|
240
|
-
throw new errors_js_1.ProofVerificationError(errors_js_1.PROOF_VERIFICATION_ERROR_CODES.DID_DOCUMENT_NOT_FOUND, `DID document not found: ${did}`, { did });
|
|
241
|
-
}
|
|
242
|
-
if (!didDoc.verificationMethod ||
|
|
243
|
-
didDoc.verificationMethod.length === 0) {
|
|
244
|
-
throw new errors_js_1.ProofVerificationError(errors_js_1.PROOF_VERIFICATION_ERROR_CODES.VERIFICATION_METHOD_NOT_FOUND, `No verification methods found in DID document: ${did}`, { did });
|
|
245
|
-
}
|
|
246
|
-
// Find verification method by kid or use first one
|
|
247
|
-
let verificationMethod;
|
|
248
|
-
if (kid) {
|
|
249
|
-
const kidWithHash = kid.startsWith("#") ? kid : `#${kid}`;
|
|
250
|
-
verificationMethod = didDoc.verificationMethod.find((vm) => vm.id === kidWithHash || vm.id === `${did}${kidWithHash}`);
|
|
251
|
-
if (!verificationMethod) {
|
|
252
|
-
throw new errors_js_1.ProofVerificationError(errors_js_1.PROOF_VERIFICATION_ERROR_CODES.VERIFICATION_METHOD_NOT_FOUND, `Verification method not found for kid: ${kid}`, {
|
|
253
|
-
did,
|
|
254
|
-
kid,
|
|
255
|
-
availableKids: didDoc.verificationMethod.map((vm) => vm.id),
|
|
256
|
-
});
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
verificationMethod = didDoc.verificationMethod[0];
|
|
261
|
-
}
|
|
262
|
-
if (!verificationMethod?.publicKeyJwk) {
|
|
263
|
-
throw new errors_js_1.ProofVerificationError(errors_js_1.PROOF_VERIFICATION_ERROR_CODES.PUBLIC_KEY_NOT_FOUND, `Public key JWK not found in verification method`, { did, kid, verificationMethodId: verificationMethod?.id });
|
|
264
|
-
}
|
|
265
|
-
const jwk = verificationMethod.publicKeyJwk;
|
|
266
|
-
// Validate it's an Ed25519 key
|
|
267
|
-
if (jwk.kty !== "OKP" || jwk.crv !== "Ed25519" || !jwk.x) {
|
|
268
|
-
throw new errors_js_1.ProofVerificationError(errors_js_1.PROOF_VERIFICATION_ERROR_CODES.INVALID_JWK_FORMAT, `Unsupported key type or curve: kty=${jwk.kty}, crv=${jwk.crv}`, { did, kid, jwk: { kty: jwk.kty, crv: jwk.crv } });
|
|
269
|
-
}
|
|
270
|
-
return jwk;
|
|
271
|
-
}
|
|
272
|
-
catch (error) {
|
|
273
|
-
if (error instanceof errors_js_1.ProofVerificationError) {
|
|
274
|
-
throw error;
|
|
275
|
-
}
|
|
276
|
-
console.error("[ProofVerifier] Failed to fetch public key from DID:", error);
|
|
277
|
-
throw new errors_js_1.ProofVerificationError(errors_js_1.PROOF_VERIFICATION_ERROR_CODES.DID_RESOLUTION_FAILED, `DID resolution failed: ${error instanceof Error ? error.message : String(error)}`, {
|
|
278
|
-
did,
|
|
279
|
-
kid,
|
|
280
|
-
originalError: error instanceof Error ? error.message : String(error),
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
/**
|
|
285
|
-
* Build canonical payload from proof meta
|
|
286
|
-
*
|
|
287
|
-
* CRITICAL: This must reconstruct the exact JWS payload structure that was originally signed.
|
|
288
|
-
* The original JWS payload uses standard JWT claims (aud, sub, iss) plus custom proof claims,
|
|
289
|
-
* NOT the proof.meta structure directly.
|
|
290
|
-
*
|
|
291
|
-
* @param meta - Proof metadata
|
|
292
|
-
* @returns Canonical JSON string matching the original JWS payload structure
|
|
293
|
-
*/
|
|
294
|
-
buildCanonicalPayload(meta) {
|
|
295
|
-
// Reconstruct the original JWS payload structure that was signed
|
|
296
|
-
// This matches the structure used in proof generation (proof.ts, proof-generator.ts)
|
|
297
|
-
const payload = {
|
|
298
|
-
// Standard JWT claims (RFC 7519) - these are what was actually signed
|
|
299
|
-
aud: meta.audience, // Audience (who the token is for)
|
|
300
|
-
sub: meta.did, // Subject (agent DID)
|
|
301
|
-
iss: meta.did, // Issuer (agent DID - self-issued)
|
|
302
|
-
// Custom MCP-I proof claims
|
|
303
|
-
requestHash: meta.requestHash,
|
|
304
|
-
responseHash: meta.responseHash,
|
|
305
|
-
ts: meta.ts,
|
|
306
|
-
nonce: meta.nonce,
|
|
307
|
-
sessionId: meta.sessionId,
|
|
308
|
-
// Optional claims (only include if present)
|
|
309
|
-
...(meta.scopeId && { scopeId: meta.scopeId }),
|
|
310
|
-
...(meta.delegationRef && { delegationRef: meta.delegationRef }),
|
|
311
|
-
...(meta.clientDid && { clientDid: meta.clientDid }),
|
|
312
|
-
};
|
|
313
|
-
// Canonicalize the reconstructed payload using the same function as proof generation
|
|
314
|
-
// CRITICAL: Must use json-canonicalize canonicalize() to match proof.ts exactly
|
|
315
|
-
return (0, json_canonicalize_1.canonicalize)(payload);
|
|
316
|
-
}
|
|
317
|
-
}
|
|
318
|
-
exports.ProofVerifier = ProofVerifier;
|
|
319
|
-
//# sourceMappingURL=proof-verifier.js.map
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider Resolver
|
|
3
|
-
*
|
|
4
|
-
* Resolves OAuth provider for tools using priority-based resolution strategy.
|
|
5
|
-
* Supports Phase 2+ tool-specific providers with backward compatibility for Phase 1.
|
|
6
|
-
*
|
|
7
|
-
* @package @kya-os/mcp-i-core
|
|
8
|
-
*/
|
|
9
|
-
import type { ToolProtection } from "@kya-os/contracts/tool-protection";
|
|
10
|
-
import type { OAuthProviderRegistry } from "./oauth-provider-registry.js";
|
|
11
|
-
import type { OAuthConfigService } from "./oauth-config.service.js";
|
|
12
|
-
/**
|
|
13
|
-
* Error thrown when a tool is configured for consent-only mode (no OAuth needed)
|
|
14
|
-
* This is NOT an error condition - it's a signal to skip OAuth flow
|
|
15
|
-
*/
|
|
16
|
-
export declare class ConsentOnlyModeError extends Error {
|
|
17
|
-
readonly toolProtection: ToolProtection;
|
|
18
|
-
constructor(toolProtection: ToolProtection);
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Error thrown when a tool requires credential/password-based authentication
|
|
22
|
-
* This is NOT an error condition - it's a signal to use credential auth flow
|
|
23
|
-
* (username/password, email/password, etc.) instead of OAuth
|
|
24
|
-
*/
|
|
25
|
-
export declare class CredentialAuthModeError extends Error {
|
|
26
|
-
readonly toolProtection: ToolProtection;
|
|
27
|
-
/** The credential provider ID configured for this tool */
|
|
28
|
-
readonly provider: string;
|
|
29
|
-
constructor(toolProtection: ToolProtection, provider: string);
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Resolves OAuth provider for tools with priority-based fallback strategy
|
|
33
|
-
*
|
|
34
|
-
* Priority order:
|
|
35
|
-
* 0. Check for consent-only mode (authorization.type === 'none') - skip OAuth
|
|
36
|
-
* 1. Tool-specific oauthProvider field (Phase 2+ preferred)
|
|
37
|
-
* 2. Scope prefix inference (fallback)
|
|
38
|
-
* 3. Project-configured provider from AgentShield dashboard
|
|
39
|
-
* 4. Error if no provider can be resolved
|
|
40
|
-
*/
|
|
41
|
-
export declare class ProviderResolver {
|
|
42
|
-
private registry;
|
|
43
|
-
private configService;
|
|
44
|
-
constructor(registry: OAuthProviderRegistry, configService: OAuthConfigService);
|
|
45
|
-
/**
|
|
46
|
-
* Check if a tool is configured for consent-only mode
|
|
47
|
-
* Consent-only means delegation is required but no OAuth provider is needed
|
|
48
|
-
*
|
|
49
|
-
* @param toolProtection - Tool protection configuration
|
|
50
|
-
* @returns true if consent-only mode
|
|
51
|
-
*/
|
|
52
|
-
isConsentOnlyMode(toolProtection: ToolProtection): boolean;
|
|
53
|
-
/**
|
|
54
|
-
* Check if a tool is configured for credential/password-based authentication
|
|
55
|
-
* This includes username/password, email/password, etc.
|
|
56
|
-
*
|
|
57
|
-
* @param toolProtection - Tool protection configuration
|
|
58
|
-
* @returns Object with isCredential flag and optional provider ID
|
|
59
|
-
*/
|
|
60
|
-
isCredentialAuthMode(toolProtection: ToolProtection): {
|
|
61
|
-
isCredential: boolean;
|
|
62
|
-
provider?: string;
|
|
63
|
-
};
|
|
64
|
-
/**
|
|
65
|
-
* Resolve OAuth provider for a tool
|
|
66
|
-
*
|
|
67
|
-
* @param toolProtection - Tool protection configuration
|
|
68
|
-
* @param projectId - Project ID for fetching provider config
|
|
69
|
-
* @returns Provider name (never null - throws if cannot resolve)
|
|
70
|
-
* @throws ConsentOnlyModeError if tool is consent-only (not a real error)
|
|
71
|
-
* @throws CredentialAuthModeError if tool requires password/credential auth
|
|
72
|
-
* @throws Error if provider cannot be resolved
|
|
73
|
-
*/
|
|
74
|
-
resolveProvider(toolProtection: ToolProtection, projectId: string): Promise<string>;
|
|
75
|
-
/**
|
|
76
|
-
* Infer provider from scope prefixes
|
|
77
|
-
*
|
|
78
|
-
* Used as Priority 2 fallback when oauthProvider is not specified.
|
|
79
|
-
* Examples:
|
|
80
|
-
* - github:repo:read → github
|
|
81
|
-
* - gmail:read → google
|
|
82
|
-
* - microsoft:calendar:read → microsoft
|
|
83
|
-
*
|
|
84
|
-
* @param scopes - Required scopes for the tool
|
|
85
|
-
* @returns Provider name if uniquely inferred, null otherwise
|
|
86
|
-
*/
|
|
87
|
-
private inferProviderFromScopes;
|
|
88
|
-
}
|
|
89
|
-
//# sourceMappingURL=provider-resolver.d.ts.map
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Provider Resolver
|
|
4
|
-
*
|
|
5
|
-
* Resolves OAuth provider for tools using priority-based resolution strategy.
|
|
6
|
-
* Supports Phase 2+ tool-specific providers with backward compatibility for Phase 1.
|
|
7
|
-
*
|
|
8
|
-
* @package @kya-os/mcp-i-core
|
|
9
|
-
*/
|
|
10
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
-
exports.ProviderResolver = exports.CredentialAuthModeError = exports.ConsentOnlyModeError = void 0;
|
|
12
|
-
/**
|
|
13
|
-
* Error thrown when a tool is configured for consent-only mode (no OAuth needed)
|
|
14
|
-
* This is NOT an error condition - it's a signal to skip OAuth flow
|
|
15
|
-
*/
|
|
16
|
-
class ConsentOnlyModeError extends Error {
|
|
17
|
-
toolProtection;
|
|
18
|
-
constructor(toolProtection) {
|
|
19
|
-
super("Tool is configured for consent-only mode (no OAuth provider required)");
|
|
20
|
-
this.toolProtection = toolProtection;
|
|
21
|
-
this.name = "ConsentOnlyModeError";
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
exports.ConsentOnlyModeError = ConsentOnlyModeError;
|
|
25
|
-
/**
|
|
26
|
-
* Error thrown when a tool requires credential/password-based authentication
|
|
27
|
-
* This is NOT an error condition - it's a signal to use credential auth flow
|
|
28
|
-
* (username/password, email/password, etc.) instead of OAuth
|
|
29
|
-
*/
|
|
30
|
-
class CredentialAuthModeError extends Error {
|
|
31
|
-
toolProtection;
|
|
32
|
-
/** The credential provider ID configured for this tool */
|
|
33
|
-
provider;
|
|
34
|
-
constructor(toolProtection, provider) {
|
|
35
|
-
super(`Tool requires credential authentication with provider "${provider}"`);
|
|
36
|
-
this.toolProtection = toolProtection;
|
|
37
|
-
this.name = "CredentialAuthModeError";
|
|
38
|
-
this.provider = provider;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
exports.CredentialAuthModeError = CredentialAuthModeError;
|
|
42
|
-
/**
|
|
43
|
-
* Resolves OAuth provider for tools with priority-based fallback strategy
|
|
44
|
-
*
|
|
45
|
-
* Priority order:
|
|
46
|
-
* 0. Check for consent-only mode (authorization.type === 'none') - skip OAuth
|
|
47
|
-
* 1. Tool-specific oauthProvider field (Phase 2+ preferred)
|
|
48
|
-
* 2. Scope prefix inference (fallback)
|
|
49
|
-
* 3. Project-configured provider from AgentShield dashboard
|
|
50
|
-
* 4. Error if no provider can be resolved
|
|
51
|
-
*/
|
|
52
|
-
class ProviderResolver {
|
|
53
|
-
registry;
|
|
54
|
-
configService;
|
|
55
|
-
constructor(registry, configService) {
|
|
56
|
-
this.registry = registry;
|
|
57
|
-
this.configService = configService;
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Check if a tool is configured for consent-only mode
|
|
61
|
-
* Consent-only means delegation is required but no OAuth provider is needed
|
|
62
|
-
*
|
|
63
|
-
* @param toolProtection - Tool protection configuration
|
|
64
|
-
* @returns true if consent-only mode
|
|
65
|
-
*/
|
|
66
|
-
isConsentOnlyMode(toolProtection) {
|
|
67
|
-
// Check explicit authorization.type === 'none'
|
|
68
|
-
if (toolProtection.authorization?.type === "none") {
|
|
69
|
-
return true;
|
|
70
|
-
}
|
|
71
|
-
return false;
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Check if a tool is configured for credential/password-based authentication
|
|
75
|
-
* This includes username/password, email/password, etc.
|
|
76
|
-
*
|
|
77
|
-
* @param toolProtection - Tool protection configuration
|
|
78
|
-
* @returns Object with isCredential flag and optional provider ID
|
|
79
|
-
*/
|
|
80
|
-
isCredentialAuthMode(toolProtection) {
|
|
81
|
-
// Check explicit authorization.type === 'password'
|
|
82
|
-
if (toolProtection.authorization?.type === "password") {
|
|
83
|
-
return {
|
|
84
|
-
isCredential: true,
|
|
85
|
-
provider: toolProtection.authorization.provider || "credentials",
|
|
86
|
-
};
|
|
87
|
-
}
|
|
88
|
-
return { isCredential: false };
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* Resolve OAuth provider for a tool
|
|
92
|
-
*
|
|
93
|
-
* @param toolProtection - Tool protection configuration
|
|
94
|
-
* @param projectId - Project ID for fetching provider config
|
|
95
|
-
* @returns Provider name (never null - throws if cannot resolve)
|
|
96
|
-
* @throws ConsentOnlyModeError if tool is consent-only (not a real error)
|
|
97
|
-
* @throws CredentialAuthModeError if tool requires password/credential auth
|
|
98
|
-
* @throws Error if provider cannot be resolved
|
|
99
|
-
*/
|
|
100
|
-
async resolveProvider(toolProtection, projectId) {
|
|
101
|
-
// Priority 0a: Check for consent-only mode (no OAuth required)
|
|
102
|
-
if (this.isConsentOnlyMode(toolProtection)) {
|
|
103
|
-
console.error(`[ProviderResolver] Tool is consent-only mode (authorization.type=none), skipping OAuth resolution`);
|
|
104
|
-
throw new ConsentOnlyModeError(toolProtection);
|
|
105
|
-
}
|
|
106
|
-
// Priority 0b: Check for credential/password auth mode (not OAuth)
|
|
107
|
-
const credentialCheck = this.isCredentialAuthMode(toolProtection);
|
|
108
|
-
if (credentialCheck.isCredential) {
|
|
109
|
-
console.error(`[ProviderResolver] Tool requires credential auth (authorization.type=password), provider="${credentialCheck.provider}"`);
|
|
110
|
-
throw new CredentialAuthModeError(toolProtection, credentialCheck.provider);
|
|
111
|
-
}
|
|
112
|
-
// Priority 1: Tool-specific provider (Phase 2+ preferred)
|
|
113
|
-
if (toolProtection.oauthProvider) {
|
|
114
|
-
// Ensure registry is loaded before checking
|
|
115
|
-
if (this.registry.getProviderNames().length === 0) {
|
|
116
|
-
await this.registry.loadFromAgentShield(projectId);
|
|
117
|
-
}
|
|
118
|
-
if (!this.registry.hasProvider(toolProtection.oauthProvider)) {
|
|
119
|
-
throw new Error(`Provider "${toolProtection.oauthProvider}" not configured for project "${projectId}". ` +
|
|
120
|
-
`Add provider in project settings.`);
|
|
121
|
-
}
|
|
122
|
-
return toolProtection.oauthProvider;
|
|
123
|
-
}
|
|
124
|
-
// Priority 2: Scope prefix inference (fallback)
|
|
125
|
-
const inferredProvider = this.inferProviderFromScopes(toolProtection.requiredScopes || []);
|
|
126
|
-
if (inferredProvider) {
|
|
127
|
-
// Ensure registry is loaded before checking
|
|
128
|
-
if (this.registry.getProviderNames().length === 0) {
|
|
129
|
-
await this.registry.loadFromAgentShield(projectId);
|
|
130
|
-
}
|
|
131
|
-
if (this.registry.hasProvider(inferredProvider)) {
|
|
132
|
-
console.error(`[ProviderResolver] Inferred provider "${inferredProvider}" from scopes`);
|
|
133
|
-
return inferredProvider;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
// Priority 3: Use explicitly configured provider from AgentShield dashboard
|
|
137
|
-
// This is the provider the user has actually configured, not just any available provider
|
|
138
|
-
await this.registry.loadFromAgentShield(projectId);
|
|
139
|
-
const configuredProvider = this.registry.getConfiguredProvider();
|
|
140
|
-
if (configuredProvider && this.registry.hasProvider(configuredProvider)) {
|
|
141
|
-
console.warn(`[ProviderResolver] Tool does not specify oauthProvider. ` +
|
|
142
|
-
`Using project-configured provider "${configuredProvider}" as fallback. ` +
|
|
143
|
-
`Consider explicitly setting oauthProvider in tool protection config.`);
|
|
144
|
-
return configuredProvider;
|
|
145
|
-
}
|
|
146
|
-
// Priority 4: Error if no provider is configured
|
|
147
|
-
// NOTE: We intentionally do NOT fall back to "first available provider" anymore
|
|
148
|
-
// because AgentShield returns ALL providers (even unconfigured ones).
|
|
149
|
-
// Only use providers explicitly configured by the user.
|
|
150
|
-
throw new Error(`Tool requires OAuth but no provider is configured for project "${projectId}". ` +
|
|
151
|
-
`Configure an OAuth provider in AgentShield dashboard.`);
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Infer provider from scope prefixes
|
|
155
|
-
*
|
|
156
|
-
* Used as Priority 2 fallback when oauthProvider is not specified.
|
|
157
|
-
* Examples:
|
|
158
|
-
* - github:repo:read → github
|
|
159
|
-
* - gmail:read → google
|
|
160
|
-
* - microsoft:calendar:read → microsoft
|
|
161
|
-
*
|
|
162
|
-
* @param scopes - Required scopes for the tool
|
|
163
|
-
* @returns Provider name if uniquely inferred, null otherwise
|
|
164
|
-
*/
|
|
165
|
-
inferProviderFromScopes(scopes) {
|
|
166
|
-
if (!scopes || scopes.length === 0) {
|
|
167
|
-
return null;
|
|
168
|
-
}
|
|
169
|
-
// Extract first part of scope (before first colon)
|
|
170
|
-
const scopePrefixes = scopes.map((scope) => {
|
|
171
|
-
const parts = scope.split(":");
|
|
172
|
-
return parts[0].toLowerCase();
|
|
173
|
-
});
|
|
174
|
-
// Provider mapping
|
|
175
|
-
const providerMap = {
|
|
176
|
-
github: "github",
|
|
177
|
-
google: "google",
|
|
178
|
-
gmail: "google", // gmail:read → google
|
|
179
|
-
calendar: "google", // calendar:read → google (if ambiguous, use project default)
|
|
180
|
-
microsoft: "microsoft",
|
|
181
|
-
outlook: "microsoft",
|
|
182
|
-
slack: "slack",
|
|
183
|
-
auth0: "auth0",
|
|
184
|
-
okta: "okta",
|
|
185
|
-
};
|
|
186
|
-
// Find unique provider
|
|
187
|
-
const providers = new Set(scopePrefixes.map((prefix) => providerMap[prefix]).filter(Boolean));
|
|
188
|
-
if (providers.size === 1) {
|
|
189
|
-
return Array.from(providers)[0];
|
|
190
|
-
}
|
|
191
|
-
// Ambiguous or no prefix → return null (use project-level provider)
|
|
192
|
-
return null;
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
exports.ProviderResolver = ProviderResolver;
|
|
196
|
-
//# sourceMappingURL=provider-resolver.js.map
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Provider Validator
|
|
3
|
-
*
|
|
4
|
-
* Validates OAuth provider configurations for custom IDP support.
|
|
5
|
-
* Ensures provider configurations are valid before registration.
|
|
6
|
-
*
|
|
7
|
-
* @package @kya-os/mcp-i-core
|
|
8
|
-
*/
|
|
9
|
-
import type { OAuthProvider } from "@kya-os/contracts/config";
|
|
10
|
-
/**
|
|
11
|
-
* Validation error for provider configuration issues
|
|
12
|
-
*/
|
|
13
|
-
export declare class ProviderValidationError extends Error {
|
|
14
|
-
readonly field?: string | undefined;
|
|
15
|
-
constructor(message: string, field?: string | undefined);
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Service for validating OAuth provider configurations
|
|
19
|
-
*/
|
|
20
|
-
export declare class ProviderValidator {
|
|
21
|
-
/**
|
|
22
|
-
* Validate provider configuration
|
|
23
|
-
*
|
|
24
|
-
* @param provider - Provider configuration to validate
|
|
25
|
-
* @param name - Provider name (for error messages)
|
|
26
|
-
* @throws ProviderValidationError if validation fails
|
|
27
|
-
*/
|
|
28
|
-
validate(provider: OAuthProvider, name: string): void;
|
|
29
|
-
/**
|
|
30
|
-
* Validate URL format
|
|
31
|
-
*
|
|
32
|
-
* @param url - URL to validate
|
|
33
|
-
* @param providerName - Provider name (for error messages)
|
|
34
|
-
* @param fieldName - Field name (for error messages)
|
|
35
|
-
* @throws ProviderValidationError if URL is invalid
|
|
36
|
-
*/
|
|
37
|
-
private validateUrl;
|
|
38
|
-
/**
|
|
39
|
-
* Validate custom parameters don't override reserved OAuth parameters
|
|
40
|
-
*
|
|
41
|
-
* @param customParams - Custom parameters to validate
|
|
42
|
-
* @param providerName - Provider name (for error messages)
|
|
43
|
-
* @throws ProviderValidationError if reserved parameter is overridden
|
|
44
|
-
*/
|
|
45
|
-
private validateCustomParams;
|
|
46
|
-
/**
|
|
47
|
-
* Test provider endpoint reachability (optional)
|
|
48
|
-
*
|
|
49
|
-
* @param provider - Provider configuration
|
|
50
|
-
* @param fetchProvider - Fetch implementation
|
|
51
|
-
* @returns True if endpoint is reachable, false otherwise
|
|
52
|
-
*/
|
|
53
|
-
testProvider(provider: OAuthProvider, fetchProvider: typeof fetch): Promise<boolean>;
|
|
54
|
-
}
|
|
55
|
-
//# sourceMappingURL=provider-validator.d.ts.map
|