@kya-os/mcp-i-core 1.3.21 → 1.3.23
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/runtime/base.js
CHANGED
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.MCPIRuntimeBase = void 0;
|
|
11
11
|
const tool_protection_js_1 = require("../types/tool-protection.js");
|
|
12
12
|
const crypto_service_js_1 = require("../services/crypto.service.js");
|
|
13
|
+
const access_control_service_js_1 = require("../services/access-control.service.js");
|
|
13
14
|
const agentshield_api_1 = require("@kya-os/contracts/agentshield-api");
|
|
14
15
|
const user_did_manager_1 = require("../identity/user-did-manager");
|
|
15
16
|
class MCPIRuntimeBase {
|
|
@@ -466,6 +467,64 @@ class MCPIRuntimeBase {
|
|
|
466
467
|
});
|
|
467
468
|
}
|
|
468
469
|
}
|
|
470
|
+
// ✅ SECURITY: Validate authorization method matches tool requirements
|
|
471
|
+
// This prevents stale delegations from working after tool auth method changes
|
|
472
|
+
// Only validates when:
|
|
473
|
+
// 1. Tool has authorization requirement defined
|
|
474
|
+
// 2. Credential contains authorization data (AgentShield API verifier)
|
|
475
|
+
const toolAuth = protection.authorization;
|
|
476
|
+
const delegationAuth = credential?.authorization;
|
|
477
|
+
if (toolAuth && delegationAuth) {
|
|
478
|
+
// Both tool and delegation have authorization - compare them
|
|
479
|
+
if (!(0, access_control_service_js_1.authorizationMatches)(delegationAuth, toolAuth)) {
|
|
480
|
+
const authMismatchReason = `Authorization method mismatch: delegation has ${delegationAuth.type}${delegationAuth.provider ? `:${delegationAuth.provider}` : ""}${delegationAuth.credentialType ? `:${delegationAuth.credentialType}` : ""} but tool requires ${toolAuth.type}${toolAuth.provider ? `:${toolAuth.provider}` : ""}${toolAuth.credentialType ? `:${toolAuth.credentialType}` : ""}`;
|
|
481
|
+
if (this.config.audit?.enabled) {
|
|
482
|
+
console.error("[MCP-I] ❌ Authorization method validation FAILED", {
|
|
483
|
+
tool: toolName,
|
|
484
|
+
agentDid: identity.did.slice(0, 20) + "...",
|
|
485
|
+
reason: authMismatchReason,
|
|
486
|
+
delegationAuth,
|
|
487
|
+
toolAuth,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
// Throw DelegationRequiredError to force re-authorization with correct method
|
|
491
|
+
const interceptedCall = {
|
|
492
|
+
toolName,
|
|
493
|
+
args,
|
|
494
|
+
sessionId: session?.id || "unknown",
|
|
495
|
+
timestamp: this.clock.now(),
|
|
496
|
+
expiresAt: this.clock.calculateExpiry(1800),
|
|
497
|
+
};
|
|
498
|
+
const resumeToken = this.generateResumeToken(interceptedCall);
|
|
499
|
+
const consentUrl = this.buildConsentUrl(toolName, protection.requiredScopes, session, resumeToken, undefined, protection.oauthProvider);
|
|
500
|
+
this.interceptedCalls.set(resumeToken, interceptedCall);
|
|
501
|
+
this.cleanupExpiredInterceptedCalls();
|
|
502
|
+
throw new tool_protection_js_1.DelegationRequiredError(toolName, protection.requiredScopes, consentUrl, interceptedCall, resumeToken);
|
|
503
|
+
}
|
|
504
|
+
// Authorization method validation passed
|
|
505
|
+
if (this.config.audit?.enabled) {
|
|
506
|
+
console.log("[MCP-I] ✅ Authorization method validation PASSED", {
|
|
507
|
+
tool: toolName,
|
|
508
|
+
agentDid: identity.did.slice(0, 20) + "...",
|
|
509
|
+
authType: delegationAuth.type,
|
|
510
|
+
provider: delegationAuth.provider || "N/A",
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
else if (toolAuth && !delegationAuth) {
|
|
515
|
+
// Tool requires authorization but credential doesn't have auth data
|
|
516
|
+
// This can happen with legacy delegations or incomplete credential data
|
|
517
|
+
if (this.config.audit?.enabled) {
|
|
518
|
+
console.warn("[MCP-I] ⚠️ Tool requires authorization but credential missing auth data", {
|
|
519
|
+
tool: toolName,
|
|
520
|
+
agentDid: identity.did.slice(0, 20) + "...",
|
|
521
|
+
toolAuth,
|
|
522
|
+
note: "Allowing execution - legacy delegation or incomplete data",
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
// Allow execution for backward compatibility with legacy delegations
|
|
526
|
+
// New delegations from AgentShield will always have authorization data
|
|
527
|
+
}
|
|
469
528
|
// Verification succeeded
|
|
470
529
|
if (this.config.audit?.enabled) {
|
|
471
530
|
console.log("[MCP-I] ✅ Delegation verification SUCCEEDED", {
|
|
@@ -688,12 +688,18 @@ function authorizationMatches(delegationAuth, toolAuth) {
|
|
|
688
688
|
// Compare type
|
|
689
689
|
if (delegationAuth.type !== toolAuth.type)
|
|
690
690
|
return false;
|
|
691
|
-
// For OAuth, compare provider
|
|
691
|
+
// For OAuth, compare provider (undefined in toolAuth means "any provider is acceptable")
|
|
692
692
|
if (delegationAuth.type === 'oauth') {
|
|
693
|
+
// If tool doesn't specify a provider, any provider is acceptable
|
|
694
|
+
if (!toolAuth.provider)
|
|
695
|
+
return true;
|
|
693
696
|
return delegationAuth.provider === toolAuth.provider;
|
|
694
697
|
}
|
|
695
|
-
// For credential, compare credentialType
|
|
698
|
+
// For credential, compare credentialType (undefined in toolAuth means "any type is acceptable")
|
|
696
699
|
if (delegationAuth.type === 'credential') {
|
|
700
|
+
// If tool doesn't specify a credential type, any type is acceptable
|
|
701
|
+
if (!toolAuth.credentialType)
|
|
702
|
+
return true;
|
|
697
703
|
return delegationAuth.credentialType === toolAuth.credentialType;
|
|
698
704
|
}
|
|
699
705
|
// For 'none' type, they match if both are 'none'
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kya-os/mcp-i-core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.23",
|
|
4
4
|
"description": "Core runtime and types for MCP-I framework",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"prepublishOnly": "npm run build && node ../create-mcpi-app/scripts/validate-no-workspace.js"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@kya-os/contracts": "^1.6.
|
|
31
|
+
"@kya-os/contracts": "^1.6.16",
|
|
32
32
|
"jose": "^5.6.3",
|
|
33
33
|
"json-canonicalize": "^2.0.0",
|
|
34
34
|
"zod": "^3.25.76"
|