// Proof-of-enforcement for kb#147, run with: node src/trust-gate.test.mjs // // Deliberately does NOT touch the live agap-mcp container, LiteLLM, or // Vaultwarden — it exercises the exact exported functions server.js calls // (trustRankOf/vaultAllowed/resolveCallerAgent/isVaultTool) against a // synthetic registry + token map, so this is a real test of the enforcement // logic itself, not a mock of it. import assert from 'node:assert/strict'; import { trustRankOf, vaultAllowed, resolveCallerAgent, isVaultTool, trustedRankThreshold, _resetRegistryCacheForTests, } from './trust-gate.js'; const registry = { trust_classes: { human: { rank: 3 }, trusted: { rank: 2 }, sandboxed: { rank: 1 }, untrusted: { rank: 0 }, }, agents: [ { id: 'adolf', trust_class: 'trusted' }, { id: 'claude-coder', trust_class: 'trusted' }, { id: 'torgash', trust_class: 'sandboxed' }, { id: 'researcher', trust_class: 'sandboxed' }, { id: 'kimi-endpoint', trust_class: 'untrusted' }, ], }; const tokenMap = { 'tok-adolf': 'adolf', 'tok-claude-coder': 'claude-coder', 'tok-torgash': 'torgash', 'tok-researcher': 'researcher', }; let passed = 0; function check(label, fn) { fn(); passed++; console.log(`ok - ${label}`); } check('trusted rank threshold resolves from registry', () => { assert.equal(trustedRankThreshold(registry), 2); }); check('trusted agents (adolf, claude-coder) can reach vault', () => { assert.equal(vaultAllowed('adolf', registry), true); assert.equal(vaultAllowed('claude-coder', registry), true); }); check('sandboxed agents (torgash, researcher) CANNOT reach vault', () => { assert.equal(vaultAllowed('torgash', registry), false); assert.equal(vaultAllowed('researcher', registry), false); }); check('untrusted agent cannot reach vault', () => { assert.equal(vaultAllowed('kimi-endpoint', registry), false); }); check('unauthenticated caller (no token resolved) cannot reach vault', () => { assert.equal(vaultAllowed(null, registry), false); assert.equal(trustRankOf(null, registry), -1); }); check('unknown/unregistered agent id fails closed, not open', () => { assert.equal(vaultAllowed('some-new-agent-nobody-declared', registry), false); }); check('resolveCallerAgent maps bearer token -> agent id, else null', () => { assert.equal(resolveCallerAgent('tok-torgash', tokenMap), 'torgash'); assert.equal(resolveCallerAgent('tok-adolf', tokenMap), 'adolf'); assert.equal(resolveCallerAgent('not-a-real-token', tokenMap), null); assert.equal(resolveCallerAgent(null, tokenMap), null); }); check('end-to-end: a sandboxed agent\'s token provably cannot reach vw_* tools', () => { const callerAgentId = resolveCallerAgent('tok-torgash', tokenMap); assert.equal(callerAgentId, 'torgash'); assert.equal(isVaultTool('vw_get_password'), true); assert.equal(vaultAllowed(callerAgentId, registry), false); // <- the acceptance bar }); check('end-to-end: a trusted agent\'s token can reach vw_* tools', () => { const callerAgentId = resolveCallerAgent('tok-adolf', tokenMap); assert.equal(vaultAllowed(callerAgentId, registry), true); }); check('non-vault tool name is unaffected by the gate', () => { assert.equal(isVaultTool('gitea_read_file'), false); assert.equal(isVaultTool('zabbix_get_problems'), false); }); _resetRegistryCacheForTests(null); console.log(`\n${passed} passed`);