@kya-os/mcp-i 1.7.7 → 1.7.9

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.
@@ -77,9 +77,13 @@ export interface VerifyOrHintsResult {
77
77
  user_did: string;
78
78
  scopes: string[];
79
79
  authorization: {
80
- type: "oauth" | "credential" | "none";
80
+ type: "oauth" | "oauth2" | "password" | "credential" | "webauthn" | "siwe" | "none";
81
81
  provider?: string;
82
82
  credentialType?: string;
83
+ rpId?: string;
84
+ userVerification?: "required" | "preferred" | "discouraged";
85
+ chainId?: number;
86
+ domain?: string;
83
87
  };
84
88
  [key: string]: unknown;
85
89
  };
@@ -11,7 +11,7 @@
11
11
  * Related Spec: MCP-I §4.3, W3C VC Data Model 1.1
12
12
  * Python Reference: Edge-Delegation-Verification.md
13
13
  */
14
- import { JWK } from 'jose';
14
+ import type { JWK } from 'jose';
15
15
  import { DelegationCredential } from '@kya-os/contracts/delegation';
16
16
  import { CredentialStatus } from '@kya-os/contracts/vc';
17
17
  /**
@@ -15,7 +15,6 @@
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.DelegationCredentialVerifier = void 0;
17
17
  exports.createDelegationVerifier = createDelegationVerifier;
18
- const jose_1 = require("jose");
19
18
  const crypto_1 = require("crypto");
20
19
  const json_canonicalize_1 = require("json-canonicalize");
21
20
  const delegation_1 = require("@kya-os/contracts/delegation");
@@ -239,34 +238,72 @@ class DelegationCredentialVerifier {
239
238
  durationMs: Date.now() - startTime,
240
239
  };
241
240
  }
242
- // Verify signature using jose
243
- // The signature is over the canonical VC (without proof)
241
+ // Verify Ed25519 signature
242
+ // For Ed25519Signature2020:
243
+ // 1. The signing input is the canonicalized VC (without proofValue)
244
+ // 2. The proofValue is the base64url-encoded Ed25519 signature
244
245
  const vcWithoutProof = { ...vc };
245
246
  delete vcWithoutProof.proof;
246
- const canonicalVC = (0, json_canonicalize_1.canonicalize)(vcWithoutProof);
247
- // Create a hash of the canonical VC (what was actually signed)
248
- const digest = (0, crypto_1.createHash)('sha256').update(canonicalVC, 'utf8').digest();
249
- // The proof.proofValue is a base64url-encoded signature
250
- // We need to verify it
251
- const proofValue = vc.proof?.proofValue || vc.proof?.jws;
252
- if (!proofValue) {
247
+ // The proof.proofValue is base64url-encoded Ed25519 signature
248
+ // The proof.jws is an alternative JWS-based signature format (header.payload.signature)
249
+ const rawProofValue = vc.proof?.proofValue || vc.proof?.jws;
250
+ if (!rawProofValue) {
253
251
  return {
254
252
  valid: false,
255
253
  reason: 'Proof missing proofValue or jws',
256
254
  durationMs: Date.now() - startTime,
257
255
  };
258
256
  }
259
- // For Ed25519Signature2020, the proofValue is the raw signature
260
- // We'll verify it by creating a JWT with the digest and checking the signature
257
+ // Extract signature bytes - handle JWS format (header.payload.signature)
258
+ // JWS compact serialization splits into 3 parts; only the 3rd is the signature
259
+ let signatureBase64url;
260
+ if (rawProofValue.includes('.')) {
261
+ // JWS format: extract the signature (third segment)
262
+ const jwsParts = rawProofValue.split('.');
263
+ if (jwsParts.length !== 3) {
264
+ return {
265
+ valid: false,
266
+ reason: `Invalid JWS format: expected 3 parts, got ${jwsParts.length}`,
267
+ durationMs: Date.now() - startTime,
268
+ };
269
+ }
270
+ signatureBase64url = jwsParts[2];
271
+ }
272
+ else {
273
+ // proofValue is raw base64url signature
274
+ signatureBase64url = rawProofValue;
275
+ }
261
276
  try {
262
- const publicKey = await (0, jose_1.importJWK)(publicKeyJwk, 'EdDSA');
263
- // Create a minimal JWT to verify
264
- // Note: This is a simplified verification - proper implementation
265
- // would verify the exact signature format
266
- // For now, we'll just validate the proof structure is correct
267
- // A full implementation would:
268
- // 1. Reconstruct the signing input
269
- // 2. Verify the signature using the public key
277
+ // For Ed25519Signature2020, we need to:
278
+ // 1. Canonicalize the VC without proofValue
279
+ // 2. Canonicalize the proof options
280
+ // 3. Hash both and concatenate
281
+ // 4. Verify the signature
282
+ // Construct proof options (everything in proof except proofValue)
283
+ const proofOptions = { ...vc.proof };
284
+ delete proofOptions.proofValue;
285
+ delete proofOptions.jws;
286
+ delete proofOptions.signatureValue;
287
+ // Create signing input: hash(canonicalize(document)) + hash(canonicalize(proofOptions))
288
+ const canonicalDoc = (0, json_canonicalize_1.canonicalize)(vcWithoutProof);
289
+ const canonicalProof = (0, json_canonicalize_1.canonicalize)(proofOptions);
290
+ // For Ed25519Signature2020, signing input is:
291
+ // SHA-256(canonicalize(proofOptions)) || SHA-256(canonicalize(document))
292
+ const docHash = (0, crypto_1.createHash)('sha256').update(canonicalDoc, 'utf8').digest();
293
+ const proofHash = (0, crypto_1.createHash)('sha256').update(canonicalProof, 'utf8').digest();
294
+ const signingInput = Buffer.concat([proofHash, docHash]);
295
+ // Decode the base64url signature
296
+ const signatureBytes = Buffer.from(signatureBase64url, 'base64url');
297
+ // Use subtle crypto for Ed25519 verification
298
+ const cryptoKey = await globalThis.crypto.subtle.importKey('jwk', publicKeyJwk, { name: 'Ed25519' }, false, ['verify']);
299
+ const isValid = await globalThis.crypto.subtle.verify({ name: 'Ed25519' }, cryptoKey, signatureBytes, signingInput);
300
+ if (!isValid) {
301
+ return {
302
+ valid: false,
303
+ reason: 'Ed25519 signature verification failed',
304
+ durationMs: Date.now() - startTime,
305
+ };
306
+ }
270
307
  return {
271
308
  valid: true,
272
309
  durationMs: Date.now() - startTime,
@@ -27,9 +27,13 @@ export interface VerifyDelegationResult {
27
27
  user_did: string;
28
28
  scopes: string[];
29
29
  authorization: {
30
- type: 'oauth' | 'credential' | 'none';
30
+ type: 'oauth' | 'oauth2' | 'password' | 'credential' | 'webauthn' | 'siwe' | 'none';
31
31
  provider?: string;
32
32
  credentialType?: string;
33
+ rpId?: string;
34
+ userVerification?: 'required' | 'preferred' | 'discouraged';
35
+ chainId?: number;
36
+ domain?: string;
33
37
  };
34
38
  [key: string]: unknown;
35
39
  };
@@ -23,9 +23,13 @@ export interface ToolProtectionConfig {
23
23
  authorizationUrl?: string;
24
24
  /** Authorization method required for this tool */
25
25
  authorization?: {
26
- type: 'oauth' | 'credential' | 'none';
26
+ type: 'oauth' | 'oauth2' | 'password' | 'credential' | 'webauthn' | 'siwe' | 'none';
27
27
  provider?: string;
28
28
  credentialType?: string;
29
+ rpId?: string;
30
+ userVerification?: 'required' | 'preferred' | 'discouraged';
31
+ chainId?: number;
32
+ domain?: string;
29
33
  };
30
34
  }
31
35
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kya-os/mcp-i",
3
- "version": "1.7.7",
3
+ "version": "1.7.9",
4
4
  "description": "The TypeScript MCP framework with identity features built-in",
5
5
  "type": "commonjs",
6
6
  "main": "dist/index.js",