@kya-os/mcp-i-core 1.3.12 → 1.3.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config/remote-config.js +9 -12
- package/dist/runtime/base.js +11 -0
- package/dist/services/access-control.service.js +5 -0
- package/dist/services/tool-protection.service.js +17 -8
- package/package.json +2 -2
- package/.turbo/turbo-build.log +0 -4
- package/.turbo/turbo-test$colon$coverage.log +0 -4586
- package/.turbo/turbo-test.log +0 -3169
- package/COMPLIANCE_IMPROVEMENT_REPORT.md +0 -483
- package/Composer 3.md +0 -615
- package/GPT-5.md +0 -1169
- package/OPUS-plan.md +0 -352
- package/PHASE_3_AND_4.1_SUMMARY.md +0 -585
- package/PHASE_3_SUMMARY.md +0 -317
- package/PHASE_4.1.3_SUMMARY.md +0 -428
- package/PHASE_4.1_COMPLETE.md +0 -525
- package/PHASE_4_USER_DID_IDENTITY_LINKING_PLAN.md +0 -1240
- package/SCHEMA_COMPLIANCE_REPORT.md +0 -275
- package/TEST_PLAN.md +0 -571
- package/coverage/coverage-final.json +0 -60
- package/dist/cache/oauth-config-cache.d.ts.map +0 -1
- package/dist/cache/oauth-config-cache.js.map +0 -1
- package/dist/cache/tool-protection-cache.d.ts.map +0 -1
- package/dist/cache/tool-protection-cache.js.map +0 -1
- package/dist/compliance/index.d.ts.map +0 -1
- package/dist/compliance/index.js.map +0 -1
- package/dist/compliance/schema-registry.d.ts.map +0 -1
- package/dist/compliance/schema-registry.js.map +0 -1
- package/dist/compliance/schema-verifier.d.ts.map +0 -1
- package/dist/compliance/schema-verifier.js.map +0 -1
- package/dist/config/remote-config.d.ts.map +0 -1
- package/dist/config/remote-config.js.map +0 -1
- package/dist/config.d.ts.map +0 -1
- package/dist/config.js.map +0 -1
- package/dist/delegation/audience-validator.d.ts.map +0 -1
- package/dist/delegation/audience-validator.js.map +0 -1
- package/dist/delegation/bitstring.d.ts.map +0 -1
- package/dist/delegation/bitstring.js.map +0 -1
- package/dist/delegation/cascading-revocation.d.ts.map +0 -1
- package/dist/delegation/cascading-revocation.js.map +0 -1
- package/dist/delegation/delegation-graph.d.ts.map +0 -1
- package/dist/delegation/delegation-graph.js.map +0 -1
- package/dist/delegation/did-key-resolver.d.ts.map +0 -1
- package/dist/delegation/did-key-resolver.js.map +0 -1
- package/dist/delegation/index.d.ts.map +0 -1
- package/dist/delegation/index.js.map +0 -1
- package/dist/delegation/statuslist-manager.d.ts.map +0 -1
- package/dist/delegation/statuslist-manager.js.map +0 -1
- package/dist/delegation/storage/index.d.ts.map +0 -1
- package/dist/delegation/storage/index.js.map +0 -1
- package/dist/delegation/storage/memory-graph-storage.d.ts.map +0 -1
- package/dist/delegation/storage/memory-graph-storage.js.map +0 -1
- package/dist/delegation/storage/memory-statuslist-storage.d.ts.map +0 -1
- package/dist/delegation/storage/memory-statuslist-storage.js.map +0 -1
- package/dist/delegation/utils.d.ts.map +0 -1
- package/dist/delegation/utils.js.map +0 -1
- package/dist/delegation/vc-issuer.d.ts.map +0 -1
- package/dist/delegation/vc-issuer.js.map +0 -1
- package/dist/delegation/vc-verifier.d.ts.map +0 -1
- package/dist/delegation/vc-verifier.js.map +0 -1
- package/dist/identity/idp-token-resolver.d.ts.map +0 -1
- package/dist/identity/idp-token-resolver.js.map +0 -1
- package/dist/identity/idp-token-storage.interface.d.ts.map +0 -1
- package/dist/identity/idp-token-storage.interface.js.map +0 -1
- package/dist/identity/user-did-manager.d.ts.map +0 -1
- package/dist/identity/user-did-manager.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/providers/base.d.ts.map +0 -1
- package/dist/providers/base.js.map +0 -1
- package/dist/providers/memory.d.ts.map +0 -1
- package/dist/providers/memory.js.map +0 -1
- package/dist/runtime/audit-logger.d.ts.map +0 -1
- package/dist/runtime/audit-logger.js.map +0 -1
- package/dist/runtime/base.d.ts.map +0 -1
- package/dist/runtime/base.js.map +0 -1
- package/dist/services/access-control.service.d.ts.map +0 -1
- package/dist/services/access-control.service.js.map +0 -1
- package/dist/services/authorization/authorization-registry.d.ts.map +0 -1
- package/dist/services/authorization/authorization-registry.js.map +0 -1
- package/dist/services/authorization/types.d.ts.map +0 -1
- package/dist/services/authorization/types.js.map +0 -1
- package/dist/services/batch-delegation.service.d.ts.map +0 -1
- package/dist/services/batch-delegation.service.js.map +0 -1
- package/dist/services/crypto.service.d.ts.map +0 -1
- package/dist/services/crypto.service.js.map +0 -1
- package/dist/services/errors.d.ts.map +0 -1
- package/dist/services/errors.js.map +0 -1
- package/dist/services/index.d.ts.map +0 -1
- package/dist/services/index.js.map +0 -1
- package/dist/services/oauth-config.service.d.ts.map +0 -1
- package/dist/services/oauth-config.service.js.map +0 -1
- package/dist/services/oauth-provider-registry.d.ts.map +0 -1
- package/dist/services/oauth-provider-registry.js.map +0 -1
- package/dist/services/oauth-service.d.ts.map +0 -1
- package/dist/services/oauth-service.js.map +0 -1
- package/dist/services/oauth-token-retrieval.service.d.ts.map +0 -1
- package/dist/services/oauth-token-retrieval.service.js.map +0 -1
- package/dist/services/proof-verifier.d.ts.map +0 -1
- package/dist/services/proof-verifier.js.map +0 -1
- package/dist/services/provider-resolver.d.ts.map +0 -1
- package/dist/services/provider-resolver.js.map +0 -1
- package/dist/services/provider-validator.d.ts.map +0 -1
- package/dist/services/provider-validator.js.map +0 -1
- package/dist/services/session-registration.service.d.ts.map +0 -1
- package/dist/services/session-registration.service.js.map +0 -1
- package/dist/services/storage.service.d.ts.map +0 -1
- package/dist/services/storage.service.js.map +0 -1
- package/dist/services/tool-context-builder.d.ts.map +0 -1
- package/dist/services/tool-context-builder.js.map +0 -1
- package/dist/services/tool-protection.service.d.ts.map +0 -1
- package/dist/services/tool-protection.service.js.map +0 -1
- package/dist/types/oauth-required-error.d.ts.map +0 -1
- package/dist/types/oauth-required-error.js.map +0 -1
- package/dist/types/tool-protection.d.ts.map +0 -1
- package/dist/types/tool-protection.js.map +0 -1
- package/dist/utils/base58.d.ts.map +0 -1
- package/dist/utils/base58.js.map +0 -1
- package/dist/utils/base64.d.ts.map +0 -1
- package/dist/utils/base64.js.map +0 -1
- package/dist/utils/cors.d.ts.map +0 -1
- package/dist/utils/cors.js.map +0 -1
- package/dist/utils/did-helpers.d.ts.map +0 -1
- package/dist/utils/did-helpers.js.map +0 -1
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js.map +0 -1
- package/dist/utils/storage-keys.d.ts.map +0 -1
- package/dist/utils/storage-keys.js.map +0 -1
- package/docs/API_REFERENCE.md +0 -1362
- package/docs/COMPLIANCE_MATRIX.md +0 -691
- package/docs/STATUSLIST2021_GUIDE.md +0 -696
- package/docs/W3C_VC_DELEGATION_GUIDE.md +0 -710
- package/src/__tests__/cache/tool-protection-cache.test.ts +0 -640
- package/src/__tests__/config/provider-runtime-config.test.ts +0 -309
- package/src/__tests__/delegation-e2e.test.ts +0 -690
- package/src/__tests__/identity/user-did-manager.test.ts +0 -232
- package/src/__tests__/index.test.ts +0 -56
- package/src/__tests__/integration/full-flow.test.ts +0 -789
- package/src/__tests__/integration.test.ts +0 -281
- package/src/__tests__/providers/base.test.ts +0 -173
- package/src/__tests__/providers/memory.test.ts +0 -319
- package/src/__tests__/regression/phase2-regression.test.ts +0 -429
- package/src/__tests__/runtime/audit-logger.test.ts +0 -154
- package/src/__tests__/runtime/base-extensions.test.ts +0 -595
- package/src/__tests__/runtime/base.test.ts +0 -869
- package/src/__tests__/runtime/delegation-flow.test.ts +0 -164
- package/src/__tests__/runtime/proof-client-did.test.ts +0 -376
- package/src/__tests__/runtime/route-interception.test.ts +0 -686
- package/src/__tests__/runtime/tool-protection-enforcement.test.ts +0 -908
- package/src/__tests__/services/agentshield-integration.test.ts +0 -791
- package/src/__tests__/services/cache-busting.test.ts +0 -125
- package/src/__tests__/services/oauth-service-pkce.test.ts +0 -556
- package/src/__tests__/services/provider-resolver-edge-cases.test.ts +0 -591
- package/src/__tests__/services/tool-protection-merged-config.test.ts +0 -485
- package/src/__tests__/services/tool-protection-oauth-provider.test.ts +0 -480
- package/src/__tests__/services/tool-protection.service.test.ts +0 -1373
- package/src/__tests__/utils/mock-providers.ts +0 -340
- package/src/cache/oauth-config-cache.d.ts +0 -69
- package/src/cache/oauth-config-cache.d.ts.map +0 -1
- package/src/cache/oauth-config-cache.js.map +0 -1
- package/src/cache/oauth-config-cache.ts +0 -123
- package/src/cache/tool-protection-cache.ts +0 -171
- package/src/compliance/EXAMPLE.md +0 -412
- package/src/compliance/__tests__/schema-verifier.test.ts +0 -797
- package/src/compliance/index.ts +0 -8
- package/src/compliance/schema-registry.ts +0 -460
- package/src/compliance/schema-verifier.ts +0 -708
- package/src/config/__tests__/merged-config.spec.ts +0 -445
- package/src/config/__tests__/remote-config.spec.ts +0 -268
- package/src/config/remote-config.ts +0 -264
- package/src/config.ts +0 -312
- package/src/delegation/__tests__/audience-validator.test.ts +0 -112
- package/src/delegation/__tests__/bitstring.test.ts +0 -346
- package/src/delegation/__tests__/cascading-revocation.test.ts +0 -628
- package/src/delegation/__tests__/delegation-graph.test.ts +0 -584
- package/src/delegation/__tests__/did-key-resolver.test.ts +0 -265
- package/src/delegation/__tests__/utils.test.ts +0 -152
- package/src/delegation/__tests__/vc-issuer.test.ts +0 -442
- package/src/delegation/__tests__/vc-verifier.test.ts +0 -922
- package/src/delegation/audience-validator.ts +0 -52
- package/src/delegation/bitstring.ts +0 -278
- package/src/delegation/cascading-revocation.ts +0 -370
- package/src/delegation/delegation-graph.ts +0 -299
- package/src/delegation/did-key-resolver.ts +0 -179
- package/src/delegation/index.ts +0 -14
- package/src/delegation/statuslist-manager.ts +0 -353
- package/src/delegation/storage/__tests__/memory-graph-storage.test.ts +0 -366
- package/src/delegation/storage/__tests__/memory-statuslist-storage.test.ts +0 -228
- package/src/delegation/storage/index.ts +0 -9
- package/src/delegation/storage/memory-graph-storage.ts +0 -178
- package/src/delegation/storage/memory-statuslist-storage.ts +0 -77
- package/src/delegation/utils.ts +0 -221
- package/src/delegation/vc-issuer.ts +0 -232
- package/src/delegation/vc-verifier.ts +0 -568
- package/src/identity/idp-token-resolver.ts +0 -181
- package/src/identity/idp-token-storage.interface.ts +0 -94
- package/src/identity/user-did-manager.ts +0 -526
- package/src/index.ts +0 -310
- package/src/providers/base.d.ts +0 -91
- package/src/providers/base.d.ts.map +0 -1
- package/src/providers/base.js.map +0 -1
- package/src/providers/base.ts +0 -96
- package/src/providers/memory.ts +0 -142
- package/src/runtime/audit-logger.ts +0 -39
- package/src/runtime/base.ts +0 -1392
- package/src/services/__tests__/access-control.integration.test.ts +0 -443
- package/src/services/__tests__/access-control.proof-response-validation.test.ts +0 -578
- package/src/services/__tests__/access-control.service.test.ts +0 -970
- package/src/services/__tests__/batch-delegation.service.test.ts +0 -351
- package/src/services/__tests__/crypto.service.test.ts +0 -531
- package/src/services/__tests__/oauth-provider-registry.test.ts +0 -142
- package/src/services/__tests__/proof-verifier.integration.test.ts +0 -485
- package/src/services/__tests__/proof-verifier.test.ts +0 -489
- package/src/services/__tests__/provider-resolution.integration.test.ts +0 -202
- package/src/services/__tests__/provider-resolver.test.ts +0 -213
- package/src/services/__tests__/storage.service.test.ts +0 -358
- package/src/services/access-control.service.ts +0 -990
- package/src/services/authorization/authorization-registry.ts +0 -66
- package/src/services/authorization/types.ts +0 -71
- package/src/services/batch-delegation.service.ts +0 -137
- package/src/services/crypto.service.ts +0 -302
- package/src/services/errors.ts +0 -76
- package/src/services/index.ts +0 -18
- package/src/services/oauth-config.service.d.ts +0 -53
- package/src/services/oauth-config.service.d.ts.map +0 -1
- package/src/services/oauth-config.service.js.map +0 -1
- package/src/services/oauth-config.service.ts +0 -192
- package/src/services/oauth-provider-registry.d.ts +0 -57
- package/src/services/oauth-provider-registry.d.ts.map +0 -1
- package/src/services/oauth-provider-registry.js.map +0 -1
- package/src/services/oauth-provider-registry.ts +0 -141
- package/src/services/oauth-service.ts +0 -544
- package/src/services/oauth-token-retrieval.service.ts +0 -245
- package/src/services/proof-verifier.ts +0 -478
- package/src/services/provider-resolver.d.ts +0 -48
- package/src/services/provider-resolver.d.ts.map +0 -1
- package/src/services/provider-resolver.js.map +0 -1
- package/src/services/provider-resolver.ts +0 -146
- package/src/services/provider-validator.ts +0 -170
- package/src/services/session-registration.service.ts +0 -251
- package/src/services/storage.service.ts +0 -566
- package/src/services/tool-context-builder.ts +0 -237
- package/src/services/tool-protection.service.ts +0 -1070
- package/src/types/oauth-required-error.ts +0 -63
- package/src/types/tool-protection.ts +0 -155
- package/src/utils/__tests__/did-helpers.test.ts +0 -156
- package/src/utils/base58.ts +0 -109
- package/src/utils/base64.ts +0 -148
- package/src/utils/cors.ts +0 -83
- package/src/utils/did-helpers.ts +0 -210
- package/src/utils/index.ts +0 -8
- package/src/utils/storage-keys.ts +0 -278
- package/tsconfig.json +0 -21
- package/vitest.config.ts +0 -56
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Delegation Verification Flow Integration Tests
|
|
3
|
-
*
|
|
4
|
-
* Tests the complete flow: handshake → session creation → tool call → delegation verification
|
|
5
|
-
* Ensures that session.agentDid is correctly used in delegation verification.
|
|
6
|
-
*
|
|
7
|
-
* @package @kya-os/mcp-i-core/__tests__/runtime
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { describe, it, expect, beforeEach } from "vitest";
|
|
11
|
-
import { MCPIRuntimeBase } from "../../runtime/base";
|
|
12
|
-
import { ProviderRuntimeConfig } from "../../config";
|
|
13
|
-
import {
|
|
14
|
-
createMockProviders,
|
|
15
|
-
MockClockProvider,
|
|
16
|
-
MockIdentityProvider,
|
|
17
|
-
MockNonceCacheProvider,
|
|
18
|
-
} from "../utils/mock-providers";
|
|
19
|
-
import type { DelegationRecord } from "@kya-os/contracts/delegation";
|
|
20
|
-
|
|
21
|
-
describe("Delegation Verification Flow", () => {
|
|
22
|
-
let runtime: MCPIRuntimeBase;
|
|
23
|
-
let config: ProviderRuntimeConfig;
|
|
24
|
-
let mockProviders: ReturnType<typeof createMockProviders>;
|
|
25
|
-
|
|
26
|
-
beforeEach(async () => {
|
|
27
|
-
mockProviders = createMockProviders();
|
|
28
|
-
config = {
|
|
29
|
-
...mockProviders,
|
|
30
|
-
environment: "development",
|
|
31
|
-
session: {
|
|
32
|
-
timestampSkewSeconds: 120,
|
|
33
|
-
ttlMinutes: 30,
|
|
34
|
-
},
|
|
35
|
-
audit: {
|
|
36
|
-
enabled: false, // Disable audit for cleaner test output
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
runtime = new MCPIRuntimeBase(config);
|
|
40
|
-
await runtime.initialize();
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("should verify delegation using session.agentDid", async () => {
|
|
44
|
-
const agentDid = "did:key:zagent123";
|
|
45
|
-
const userDid = "did:web:user.example.com";
|
|
46
|
-
|
|
47
|
-
// 1. Perform handshake with agentDid
|
|
48
|
-
const handshakeRequest = {
|
|
49
|
-
nonce: "test-nonce-123",
|
|
50
|
-
audience: "https://server.example.com",
|
|
51
|
-
timestamp: Math.floor(Date.now() / 1000),
|
|
52
|
-
agentDid,
|
|
53
|
-
clientDid: userDid,
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const handshakeResponse = await runtime.handleHandshake(handshakeRequest);
|
|
57
|
-
expect(handshakeResponse.sessionId).toBeDefined();
|
|
58
|
-
|
|
59
|
-
// 2. Get session and verify agentDid is correct
|
|
60
|
-
const session = await runtime.getCurrentSession();
|
|
61
|
-
expect(session).toBeDefined();
|
|
62
|
-
expect(session?.agentDid).toBe(agentDid); // ✅ Should be client's agent DID, not server DID
|
|
63
|
-
expect(session?.serverDid).toBe("did:key:zmock123"); // ✅ Should be server's DID
|
|
64
|
-
|
|
65
|
-
// 3. Create a delegation with subjectDid matching agentDid
|
|
66
|
-
// (In real scenario, this would be verified via delegation verifier)
|
|
67
|
-
const delegation: DelegationRecord = {
|
|
68
|
-
id: "del_test_001",
|
|
69
|
-
issuerDid: userDid,
|
|
70
|
-
subjectDid: agentDid, // ✅ Matches session.agentDid
|
|
71
|
-
controller: "user_alice",
|
|
72
|
-
vcId: "vc_test_001",
|
|
73
|
-
constraints: {
|
|
74
|
-
scopes: ["tool:execute"],
|
|
75
|
-
},
|
|
76
|
-
createdAt: Date.now(),
|
|
77
|
-
expiresAt: Date.now() + 3600000, // 1 hour
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
// 4. Verify that delegation.subjectDid matches session.agentDid
|
|
81
|
-
expect(delegation.subjectDid).toBe(session?.agentDid);
|
|
82
|
-
expect(delegation.subjectDid).not.toBe(session?.serverDid); // ✅ Should NOT match server DID
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("should fail when session.agentDid does not match delegation.subjectDid", async () => {
|
|
86
|
-
const agentDid = "did:key:zagent123";
|
|
87
|
-
const wrongAgentDid = "did:key:zwrong456";
|
|
88
|
-
const userDid = "did:web:user.example.com";
|
|
89
|
-
|
|
90
|
-
// 1. Perform handshake with agentDid
|
|
91
|
-
const handshakeRequest = {
|
|
92
|
-
nonce: "test-nonce-456",
|
|
93
|
-
audience: "https://server.example.com",
|
|
94
|
-
timestamp: Math.floor(Date.now() / 1000),
|
|
95
|
-
agentDid,
|
|
96
|
-
clientDid: userDid,
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
await runtime.handleHandshake(handshakeRequest);
|
|
100
|
-
|
|
101
|
-
// 2. Get session
|
|
102
|
-
const session = await runtime.getCurrentSession();
|
|
103
|
-
expect(session?.agentDid).toBe(agentDid);
|
|
104
|
-
|
|
105
|
-
// 3. Create delegation with wrong subjectDid
|
|
106
|
-
const delegation: DelegationRecord = {
|
|
107
|
-
id: "del_test_002",
|
|
108
|
-
issuerDid: userDid,
|
|
109
|
-
subjectDid: wrongAgentDid, // ❌ Does NOT match session.agentDid
|
|
110
|
-
controller: "user_bob",
|
|
111
|
-
vcId: "vc_test_002",
|
|
112
|
-
constraints: {
|
|
113
|
-
scopes: ["tool:execute"],
|
|
114
|
-
},
|
|
115
|
-
createdAt: Date.now(),
|
|
116
|
-
expiresAt: Date.now() + 3600000,
|
|
117
|
-
};
|
|
118
|
-
|
|
119
|
-
// 4. Verify mismatch
|
|
120
|
-
expect(delegation.subjectDid).not.toBe(session?.agentDid);
|
|
121
|
-
expect(delegation.subjectDid).toBe(wrongAgentDid);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it("should handle session without agentDid gracefully", async () => {
|
|
125
|
-
const userDid = "did:web:user.example.com";
|
|
126
|
-
|
|
127
|
-
// 1. Perform handshake WITHOUT agentDid
|
|
128
|
-
const handshakeRequest = {
|
|
129
|
-
nonce: "test-nonce-789",
|
|
130
|
-
audience: "https://server.example.com",
|
|
131
|
-
timestamp: Math.floor(Date.now() / 1000),
|
|
132
|
-
// agentDid not provided
|
|
133
|
-
clientDid: userDid,
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
await runtime.handleHandshake(handshakeRequest);
|
|
137
|
-
|
|
138
|
-
// 2. Get session
|
|
139
|
-
const session = await runtime.getCurrentSession();
|
|
140
|
-
expect(session?.agentDid).toBeUndefined(); // ✅ Should be undefined, not fallback to clientDid
|
|
141
|
-
expect(session?.serverDid).toBe("did:key:zmock123"); // ✅ Server DID should still be set
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it("should verify serverDid is set correctly in session", async () => {
|
|
145
|
-
const agentDid = "did:key:zagent789";
|
|
146
|
-
const identity = await runtime.getIdentity();
|
|
147
|
-
|
|
148
|
-
// 1. Perform handshake
|
|
149
|
-
const handshakeRequest = {
|
|
150
|
-
nonce: "test-nonce-server",
|
|
151
|
-
audience: "https://server.example.com",
|
|
152
|
-
timestamp: Math.floor(Date.now() / 1000),
|
|
153
|
-
agentDid,
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
await runtime.handleHandshake(handshakeRequest);
|
|
157
|
-
|
|
158
|
-
// 2. Verify serverDid matches identity.did
|
|
159
|
-
const session = await runtime.getCurrentSession();
|
|
160
|
-
expect(session?.serverDid).toBe(identity.did);
|
|
161
|
-
expect(session?.serverDid).not.toBe(agentDid); // ✅ Should NOT match agent DID
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
|
|
@@ -1,376 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Proof Client DID Tests
|
|
3
|
-
*
|
|
4
|
-
* Tests for proof generation with clientDid tracking and extraction.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
8
|
-
import { MCPIRuntimeBase } from '../../runtime/base';
|
|
9
|
-
import { ProviderRuntimeConfig } from '../../config';
|
|
10
|
-
import { createMockProviders, MockClockProvider } from '../utils/mock-providers';
|
|
11
|
-
|
|
12
|
-
describe('MCPIRuntimeBase - Proof Client DID', () => {
|
|
13
|
-
let runtime: MCPIRuntimeBase;
|
|
14
|
-
let config: ProviderRuntimeConfig;
|
|
15
|
-
let mockProviders: ReturnType<typeof createMockProviders>;
|
|
16
|
-
|
|
17
|
-
beforeEach(async () => {
|
|
18
|
-
vi.clearAllMocks();
|
|
19
|
-
mockProviders = createMockProviders();
|
|
20
|
-
config = {
|
|
21
|
-
...mockProviders,
|
|
22
|
-
environment: 'development',
|
|
23
|
-
session: {
|
|
24
|
-
timestampSkewSeconds: 120,
|
|
25
|
-
ttlMinutes: 30
|
|
26
|
-
},
|
|
27
|
-
audit: {
|
|
28
|
-
enabled: false
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
runtime = new MCPIRuntimeBase(config);
|
|
32
|
-
await runtime.initialize();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
describe('createProof with clientDid', () => {
|
|
36
|
-
it('should include clientDid in proof when provided in session', async () => {
|
|
37
|
-
const testData = { result: 'success' };
|
|
38
|
-
const session = {
|
|
39
|
-
id: 'session123',
|
|
40
|
-
audience: 'https://client.example.com',
|
|
41
|
-
nonce: 'test-nonce',
|
|
42
|
-
clientDid: 'did:key:zclient123'
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const proof = await runtime.createProof(testData, session);
|
|
46
|
-
|
|
47
|
-
expect(proof).toBeDefined();
|
|
48
|
-
expect(proof.did).toBe('did:key:zmock123'); // Agent DID
|
|
49
|
-
expect(proof.sessionId).toBe('session123');
|
|
50
|
-
expect(proof.audience).toBe('https://client.example.com');
|
|
51
|
-
// Note: clientDid is stored in proofData but not directly in proof object
|
|
52
|
-
// The proof structure includes sessionId which can be used to retrieve clientDid
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
it('should include userDid in proof when provided in session', async () => {
|
|
56
|
-
const testData = { result: 'success' };
|
|
57
|
-
const session = {
|
|
58
|
-
id: 'session123',
|
|
59
|
-
audience: 'https://client.example.com',
|
|
60
|
-
nonce: 'test-nonce',
|
|
61
|
-
userDid: 'did:key:zuser456'
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const proof = await runtime.createProof(testData, session);
|
|
65
|
-
|
|
66
|
-
expect(proof).toBeDefined();
|
|
67
|
-
expect(proof.sessionId).toBe('session123');
|
|
68
|
-
// userDid is stored in session context
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it('should work without clientDid or userDid (backward compatibility)', async () => {
|
|
72
|
-
const testData = { result: 'success' };
|
|
73
|
-
const session = {
|
|
74
|
-
id: 'session123',
|
|
75
|
-
audience: 'https://client.example.com',
|
|
76
|
-
nonce: 'test-nonce'
|
|
77
|
-
};
|
|
78
|
-
|
|
79
|
-
const proof = await runtime.createProof(testData, session);
|
|
80
|
-
|
|
81
|
-
expect(proof).toBeDefined();
|
|
82
|
-
expect(proof.did).toBe('did:key:zmock123');
|
|
83
|
-
expect(proof.sessionId).toBe('session123');
|
|
84
|
-
expect(proof.audience).toBe('https://client.example.com');
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it('should prioritize clientDid over userDid when both provided', async () => {
|
|
88
|
-
const testData = { result: 'success' };
|
|
89
|
-
const session = {
|
|
90
|
-
id: 'session123',
|
|
91
|
-
audience: 'https://client.example.com',
|
|
92
|
-
nonce: 'test-nonce',
|
|
93
|
-
clientDid: 'did:key:zclient123',
|
|
94
|
-
userDid: 'did:key:zuser456'
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
const proof = await runtime.createProof(testData, session);
|
|
98
|
-
|
|
99
|
-
expect(proof).toBeDefined();
|
|
100
|
-
expect(proof.sessionId).toBe('session123');
|
|
101
|
-
// clientDid takes precedence in session context
|
|
102
|
-
});
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
describe('processToolCall with clientDid', () => {
|
|
106
|
-
const mockHandler = vi.fn().mockResolvedValue({ result: 'success' });
|
|
107
|
-
|
|
108
|
-
it('should include clientDid in proof when session has clientDid', async () => {
|
|
109
|
-
const session = {
|
|
110
|
-
id: 'session123',
|
|
111
|
-
audience: 'https://client.example.com',
|
|
112
|
-
nonce: 'test-nonce',
|
|
113
|
-
clientDid: 'did:key:zclient123'
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
await runtime.processToolCall(
|
|
117
|
-
'testTool',
|
|
118
|
-
{ arg: 'value' },
|
|
119
|
-
mockHandler,
|
|
120
|
-
session
|
|
121
|
-
);
|
|
122
|
-
|
|
123
|
-
const proof = runtime.getLastProof();
|
|
124
|
-
expect(proof).toBeDefined();
|
|
125
|
-
expect(proof.sessionId).toBe('session123');
|
|
126
|
-
expect(proof.audience).toBe('https://client.example.com');
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
it('should extract clientDid from handshake session', async () => {
|
|
130
|
-
// Create session via handshake
|
|
131
|
-
const handshakeResponse = await runtime.handleHandshake({
|
|
132
|
-
clientDid: 'did:key:zhandshake123',
|
|
133
|
-
audience: 'https://client.example.com'
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
const session = await runtime.getCurrentSession();
|
|
137
|
-
const proof = await runtime.createProof(
|
|
138
|
-
{ test: 'data' },
|
|
139
|
-
session
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
expect(proof.sessionId).toBe(handshakeResponse.sessionId);
|
|
143
|
-
expect(session.clientDid).toBe('did:key:zhandshake123');
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
it('should handle anonymous session from handshake (Phase 5)', async () => {
|
|
147
|
-
// Phase 5: Sessions start anonymous - no userDid at handshake
|
|
148
|
-
const configWithUserDid = {
|
|
149
|
-
...config,
|
|
150
|
-
identity: {
|
|
151
|
-
enabled: true,
|
|
152
|
-
generateUserDids: true,
|
|
153
|
-
environment: 'development'
|
|
154
|
-
}
|
|
155
|
-
};
|
|
156
|
-
const runtimeWithUserDid = new MCPIRuntimeBase(configWithUserDid);
|
|
157
|
-
await runtimeWithUserDid.initialize();
|
|
158
|
-
|
|
159
|
-
const handshakeResponse = await runtimeWithUserDid.handleHandshake({
|
|
160
|
-
audience: 'https://client.example.com'
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
const session = await runtimeWithUserDid.getCurrentSession();
|
|
164
|
-
expect(session).toBeDefined();
|
|
165
|
-
|
|
166
|
-
// Phase 5: Sessions start anonymous without userDid
|
|
167
|
-
// userDid is only set after OAuth identity resolution
|
|
168
|
-
expect(session.userDid).toBeUndefined();
|
|
169
|
-
expect(session.identityState).toBe('anonymous');
|
|
170
|
-
|
|
171
|
-
const proof = await runtimeWithUserDid.createProof(
|
|
172
|
-
{ test: 'data' },
|
|
173
|
-
session
|
|
174
|
-
);
|
|
175
|
-
expect(proof.sessionId).toBe(handshakeResponse.sessionId);
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
describe('verifyProof with clientDid context', () => {
|
|
180
|
-
let validProof: any;
|
|
181
|
-
const testData = { foo: 'bar' };
|
|
182
|
-
|
|
183
|
-
beforeEach(async () => {
|
|
184
|
-
// Set up DID document for verification
|
|
185
|
-
const fetchProvider = mockProviders.fetchProvider as any;
|
|
186
|
-
fetchProvider.setDIDDocument('did:key:zmock123', {
|
|
187
|
-
verificationMethod: [{
|
|
188
|
-
publicKeyBase64: 'mock-public-key'
|
|
189
|
-
}]
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
const session = {
|
|
193
|
-
id: 'session123',
|
|
194
|
-
audience: 'https://client.example.com',
|
|
195
|
-
nonce: 'test-nonce',
|
|
196
|
-
clientDid: 'did:key:zclient123'
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
validProof = await runtime.createProof(testData, session);
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
it('should verify proof with clientDid in session context', async () => {
|
|
203
|
-
const nonceCache = mockProviders.nonceCacheProvider as any;
|
|
204
|
-
nonceCache.clear();
|
|
205
|
-
|
|
206
|
-
const isValid = await runtime.verifyProof(testData, validProof);
|
|
207
|
-
expect(isValid).toBe(true);
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
it('should verify proof independently of clientDid presence', async () => {
|
|
211
|
-
// Create proof without clientDid
|
|
212
|
-
const proofWithoutClientDid = await runtime.createProof(testData, {
|
|
213
|
-
id: 'session456',
|
|
214
|
-
audience: 'https://client.example.com',
|
|
215
|
-
nonce: 'other-nonce'
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
const nonceCache = mockProviders.nonceCacheProvider as any;
|
|
219
|
-
nonceCache.clear();
|
|
220
|
-
|
|
221
|
-
const isValid = await runtime.verifyProof(testData, proofWithoutClientDid);
|
|
222
|
-
expect(isValid).toBe(true);
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
describe('clientDid extraction from session', () => {
|
|
227
|
-
it('should retrieve clientDid from active session', async () => {
|
|
228
|
-
const handshakeResponse = await runtime.handleHandshake({
|
|
229
|
-
clientDid: 'did:key:zclient789',
|
|
230
|
-
audience: 'https://client.example.com'
|
|
231
|
-
});
|
|
232
|
-
|
|
233
|
-
const session = await runtime.getCurrentSession();
|
|
234
|
-
expect(session.clientDid).toBe('did:key:zclient789');
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
it('should handle anonymous session when no clientDid provided (Phase 5)', async () => {
|
|
238
|
-
// Phase 5: Sessions start anonymous - userDid and clientDid may both be undefined
|
|
239
|
-
const configWithUserDid = {
|
|
240
|
-
...config,
|
|
241
|
-
identity: {
|
|
242
|
-
enabled: true,
|
|
243
|
-
generateUserDids: true,
|
|
244
|
-
environment: 'development'
|
|
245
|
-
}
|
|
246
|
-
};
|
|
247
|
-
const runtimeWithUserDid = new MCPIRuntimeBase(configWithUserDid);
|
|
248
|
-
await runtimeWithUserDid.initialize();
|
|
249
|
-
|
|
250
|
-
const handshakeResponse = await runtimeWithUserDid.handleHandshake({
|
|
251
|
-
audience: 'https://client.example.com'
|
|
252
|
-
});
|
|
253
|
-
|
|
254
|
-
const session = await runtimeWithUserDid.getCurrentSession();
|
|
255
|
-
expect(session).toBeDefined();
|
|
256
|
-
|
|
257
|
-
// Phase 5: Sessions start anonymous without userDid
|
|
258
|
-
// userDid is only set after OAuth identity resolution
|
|
259
|
-
expect(session.userDid).toBeUndefined();
|
|
260
|
-
expect(session.identityState).toBe('anonymous');
|
|
261
|
-
|
|
262
|
-
// clientDid can also be undefined in anonymous sessions
|
|
263
|
-
// Both will be set after OAuth completes
|
|
264
|
-
|
|
265
|
-
// Verify proof includes the session
|
|
266
|
-
const proof = await runtimeWithUserDid.createProof(
|
|
267
|
-
{ test: 'data' },
|
|
268
|
-
session
|
|
269
|
-
);
|
|
270
|
-
expect(proof.sessionId).toBe(handshakeResponse.sessionId);
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
describe('edge cases', () => {
|
|
275
|
-
it('should handle empty clientDid string gracefully', async () => {
|
|
276
|
-
const session = {
|
|
277
|
-
id: 'session123',
|
|
278
|
-
audience: 'https://client.example.com',
|
|
279
|
-
nonce: 'test-nonce',
|
|
280
|
-
clientDid: ''
|
|
281
|
-
};
|
|
282
|
-
|
|
283
|
-
const proof = await runtime.createProof({ test: 'data' }, session);
|
|
284
|
-
expect(proof).toBeDefined();
|
|
285
|
-
expect(proof.sessionId).toBe('session123');
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
it('should handle null clientDid gracefully', async () => {
|
|
289
|
-
const session = {
|
|
290
|
-
id: 'session123',
|
|
291
|
-
audience: 'https://client.example.com',
|
|
292
|
-
nonce: 'test-nonce',
|
|
293
|
-
clientDid: null as any
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
const proof = await runtime.createProof({ test: 'data' }, session);
|
|
297
|
-
expect(proof).toBeDefined();
|
|
298
|
-
expect(proof.sessionId).toBe('session123');
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
it('should handle undefined clientDid gracefully', async () => {
|
|
302
|
-
const session = {
|
|
303
|
-
id: 'session123',
|
|
304
|
-
audience: 'https://client.example.com',
|
|
305
|
-
nonce: 'test-nonce'
|
|
306
|
-
// clientDid is undefined
|
|
307
|
-
};
|
|
308
|
-
|
|
309
|
-
const proof = await runtime.createProof({ test: 'data' }, session);
|
|
310
|
-
expect(proof).toBeDefined();
|
|
311
|
-
expect(proof.sessionId).toBe('session123');
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
it('should handle invalid DID format in clientDid', async () => {
|
|
315
|
-
const session = {
|
|
316
|
-
id: 'session123',
|
|
317
|
-
audience: 'https://client.example.com',
|
|
318
|
-
nonce: 'test-nonce',
|
|
319
|
-
clientDid: 'invalid-did-format'
|
|
320
|
-
};
|
|
321
|
-
|
|
322
|
-
const proof = await runtime.createProof({ test: 'data' }, session);
|
|
323
|
-
expect(proof).toBeDefined();
|
|
324
|
-
// Proof should still be created even with invalid DID format
|
|
325
|
-
expect(proof.sessionId).toBe('session123');
|
|
326
|
-
});
|
|
327
|
-
});
|
|
328
|
-
|
|
329
|
-
describe('proof metadata consistency', () => {
|
|
330
|
-
it('should maintain consistent proof structure with clientDid', async () => {
|
|
331
|
-
const session = {
|
|
332
|
-
id: 'session123',
|
|
333
|
-
audience: 'https://client.example.com',
|
|
334
|
-
nonce: 'test-nonce',
|
|
335
|
-
clientDid: 'did:key:zclient123'
|
|
336
|
-
};
|
|
337
|
-
|
|
338
|
-
const proof1 = await runtime.createProof({ test: 'data1' }, session);
|
|
339
|
-
const proof2 = await runtime.createProof({ test: 'data2' }, session);
|
|
340
|
-
|
|
341
|
-
// Both proofs should have same sessionId and audience
|
|
342
|
-
expect(proof1.sessionId).toBe(proof2.sessionId);
|
|
343
|
-
expect(proof1.audience).toBe(proof2.audience);
|
|
344
|
-
|
|
345
|
-
// But different nonces (if not pre-provided)
|
|
346
|
-
// Since we're using same nonce, they should be same
|
|
347
|
-
expect(proof1.nonce).toBe(proof2.nonce);
|
|
348
|
-
|
|
349
|
-
// Different timestamps
|
|
350
|
-
expect(proof1.timestamp).toBeLessThanOrEqual(proof2.timestamp);
|
|
351
|
-
});
|
|
352
|
-
|
|
353
|
-
it('should use different proofs for different sessions', async () => {
|
|
354
|
-
const session1 = {
|
|
355
|
-
id: 'session1',
|
|
356
|
-
audience: 'https://client.example.com',
|
|
357
|
-
nonce: 'nonce1',
|
|
358
|
-
clientDid: 'did:key:zclient1'
|
|
359
|
-
};
|
|
360
|
-
|
|
361
|
-
const session2 = {
|
|
362
|
-
id: 'session2',
|
|
363
|
-
audience: 'https://client.example.com',
|
|
364
|
-
nonce: 'nonce2',
|
|
365
|
-
clientDid: 'did:key:zclient2'
|
|
366
|
-
};
|
|
367
|
-
|
|
368
|
-
const proof1 = await runtime.createProof({ test: 'data' }, session1);
|
|
369
|
-
const proof2 = await runtime.createProof({ test: 'data' }, session2);
|
|
370
|
-
|
|
371
|
-
expect(proof1.sessionId).not.toBe(proof2.sessionId);
|
|
372
|
-
expect(proof1.nonce).not.toBe(proof2.nonce);
|
|
373
|
-
});
|
|
374
|
-
});
|
|
375
|
-
});
|
|
376
|
-
|