sec-seam-delegation-hosted-consent-propose.test.mjs
96 lines 3.7 KB
Raw
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 10 days ago
1 /**
2 * SEC-SEAM-1 / L-SEAM — hosted delegation consent propose with session-bound learner JWT.
3 *
4 * Proves delegate vault-map restriction does not block type:'session' POST
5 * /api/v1/delegation/consents on Business (F26 DELEGATION-WRITE smoke path).
6 */
7
8 import fs from 'node:fs';
9 import path from 'node:path';
10 import { describe, it } from 'node:test';
11 import assert from 'node:assert/strict';
12 import { fileURLToPath } from 'node:url';
13
14 const __dirname = path.dirname(fileURLToPath(import.meta.url));
15 const ROOT = path.resolve(__dirname, '..');
16
17 function readRepo(rel) {
18 return fs.readFileSync(path.join(ROOT, rel), 'utf8');
19 }
20
21 describe('SEC-SEAM delegation hosted consent propose — unit', () => {
22 it('delegation-routes passes sessionBound into createDelegationProposalOnCanister', () => {
23 const src = readRepo('hub/bridge/delegation-routes.mjs');
24 assert.match(src, /function sessionBoundFromReq\(req\)/);
25 assert.match(src, /isSessionBoundActor/);
26 assert.match(
27 src,
28 /app\.post\('\/api\/v1\/delegation\/consents'[\s\S]*sessionBound: sessionBoundFromReq\(req\)/,
29 );
30 assert.match(src, /sessionBound: ctx\.sessionBound === true/);
31 assert.match(src, /proposed_by: ctx\.actorUid/);
32 });
33
34 it('bridge server expands vault allowlist for session-bound actors', () => {
35 const src = readRepo('hub/bridge/server.mjs');
36 assert.match(src, /resolveAllowedVaultIdsForSessionBoundActor/);
37 assert.match(src, /bridgeSessionBoundFromReq/);
38 assert.match(src, /isSessionBoundActor/);
39 });
40
41 it('delegation-hosted-proposal augments canister create body (session + pending eval)', () => {
42 const src = readRepo('lib/agent/delegation-hosted-proposal.mjs');
43 assert.match(src, /augmentProposalCreateRequestBody/);
44 assert.match(src, /sessionBound: opts\.sessionBound === true/);
45 assert.match(src, /evaluation_status = 'pending'/);
46 assert.match(src, /source: DELEGATION_PROPOSAL_SOURCE/);
47 });
48
49 it('delegation-routes logs consent propose failures with Hub code', () => {
50 const src = readRepo('hub/bridge/delegation-routes.mjs');
51 assert.match(src, /POST \/api\/v1\/delegation\/consents/);
52 assert.match(src, /vault context denied/);
53 assert.match(src, /delegation route error/);
54 });
55 });
56
57 describe('SEC-SEAM delegation hosted consent propose — integration (handler)', () => {
58 it('consent propose handler succeeds when delegate agent is active in vault', async () => {
59 const os = await import('node:os');
60 const { writeDelegationPolicy, makeAgentIdentity } = await import('./fixtures/agent/delegation-helpers.mjs');
61 const { seedDelegationFixtures, handleDelegationConsentProposeRequest } = await import(
62 '../lib/agent/delegation.mjs'
63 );
64
65 const dataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'kt-sec-seam-delegation-'));
66 writeDelegationPolicy(dataDir);
67 process.env.DELEGATION_ENABLED = '1';
68 const identity = makeAgentIdentity({
69 agentId: 'agent_l1smoke01',
70 kind: 'delegate',
71 scopeCeiling: 'personal',
72 });
73 seedDelegationFixtures(dataDir, 'Business', identity);
74
75 const result = await handleDelegationConsentProposeRequest({
76 dataDir,
77 vaultId: 'Business',
78 userId: 'google:learner-smoke',
79 delegateAgentId: 'agent_l1smoke01',
80 scope: 'personal',
81 createProposal: async (_dir, input) => ({
82 proposal_id: 'prop_sec_seam_delegation_01',
83 path: input.path,
84 status: 'proposed',
85 vault_id: input.vault_id,
86 }),
87 });
88
89 assert.equal(result.ok, true);
90 assert.equal(result.payload.intent, 'delegation_consent_create');
91 assert.match(String(result.payload.proposal_id), /^prop_/);
92
93 fs.rmSync(dataDir, { recursive: true, force: true });
94 delete process.env.DELEGATION_ENABLED;
95 });
96 });
File History 1 commit
sha256:700fafdd1afa490919f9515d660ca6e75456bcd5bb67513abcd8757a634c01f6 docs: record AIP-b SD-21 land (KN #308) Human 10 days ago