agent-passport-system 1.22.0 → 1.25.0
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/README.md +4 -4
- package/dist/src/core/aps-txt.d.ts +120 -0
- package/dist/src/core/aps-txt.d.ts.map +1 -0
- package/dist/src/core/aps-txt.js +172 -0
- package/dist/src/core/aps-txt.js.map +1 -0
- package/dist/src/core/gateway.d.ts +12 -0
- package/dist/src/core/gateway.d.ts.map +1 -1
- package/dist/src/core/gateway.js +106 -2
- package/dist/src/core/gateway.js.map +1 -1
- package/dist/src/core/governance-consumer.d.ts +113 -0
- package/dist/src/core/governance-consumer.d.ts.map +1 -0
- package/dist/src/core/governance-consumer.js +124 -0
- package/dist/src/core/governance-consumer.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/storage/index.d.ts +5 -0
- package/dist/src/storage/index.d.ts.map +1 -0
- package/dist/src/storage/index.js +6 -0
- package/dist/src/storage/index.js.map +1 -0
- package/dist/src/storage/receipt-bundle.d.ts +52 -0
- package/dist/src/storage/receipt-bundle.d.ts.map +1 -0
- package/dist/src/storage/receipt-bundle.js +178 -0
- package/dist/src/storage/receipt-bundle.js.map +1 -0
- package/dist/src/storage/types.d.ts +138 -0
- package/dist/src/storage/types.d.ts.map +1 -0
- package/dist/src/storage/types.js +15 -0
- package/dist/src/storage/types.js.map +1 -0
- package/dist/src/storage/volatile-backend.d.ts +65 -0
- package/dist/src/storage/volatile-backend.d.ts.map +1 -0
- package/dist/src/storage/volatile-backend.js +291 -0
- package/dist/src/storage/volatile-backend.js.map +1 -0
- package/dist/src/types/gateway.d.ts +4 -0
- package/dist/src/types/gateway.d.ts.map +1 -1
- package/dist/src/types/passport.d.ts +9 -0
- package/dist/src/types/passport.d.ts.map +1 -1
- package/dist/src/types/passport.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
Cryptographic identity, ethical governance, economic attribution, data source registration, protocol-native communication, intent architecture, cascade revocation, coordination primitives, and agentic commerce for autonomous AI agents.
|
|
11
11
|
|
|
12
|
-
**42 core modules + 32 v2 constitutional modules.
|
|
12
|
+
**42 core modules + 32 v2 constitutional modules. 1480 tests. Zero heavy dependencies. Running code. MCP server included.**
|
|
13
13
|
|
|
14
14
|
> *As AI agents from different creators, running different models, serving different humans begin to collaborate — who is responsible, under what authority, according to what values, and who benefits?*
|
|
15
15
|
|
|
@@ -409,7 +409,7 @@ Or zero-install remote mode:
|
|
|
409
409
|
npx agent-passport-system-mcp setup --remote
|
|
410
410
|
```
|
|
411
411
|
|
|
412
|
-
**
|
|
412
|
+
**108 tools across all 48 modules, role-scoped access control.** Identity, delegation, agora, values/policy, coordination, and commerce — all accessible via MCP. Every operation Ed25519 signed. Auto-configures Claude Desktop and Cursor.
|
|
413
413
|
|
|
414
414
|
Every operation is Ed25519 signed. Role is auto-detected from task assignments. Role-specific prompts served via MCP prompts API. File-backed task persistence at `~/.agent-passport-tasks.json`.
|
|
415
415
|
|
|
@@ -431,7 +431,7 @@ PyPI: [agent-passport-system](https://pypi.org/project/agent-passport-system/)
|
|
|
431
431
|
|
|
432
432
|
```bash
|
|
433
433
|
npm test
|
|
434
|
-
#
|
|
434
|
+
# 1480 tests across 58 files, 384 suites, 0 failures
|
|
435
435
|
```
|
|
436
436
|
|
|
437
437
|
Includes 50 adversarial tests across 4 test files: Merkle tree tampering, attribution gaming resistance, compliance violations, floor negotiation attacks, wrong-key attestations, cross-chain confused deputy, taint laundering, permit bypass, causal chain manipulation.
|
|
@@ -527,7 +527,7 @@ src/ 32 source files
|
|
|
527
527
|
reputation-authority.ts — Reputation/tier types
|
|
528
528
|
cross-chain.ts — Cross-chain taint/SAO types
|
|
529
529
|
data-source.ts — Data source/access receipt types
|
|
530
|
-
tests/
|
|
530
|
+
tests/ 78 test files, 1480 tests (384 suites)
|
|
531
531
|
adversarial.ts — 50 adversarial cases
|
|
532
532
|
adversarial-paper.test.ts — 22 paper-linked attack scenarios
|
|
533
533
|
adversarial-causal-chain.test.ts — 18 causal chain attacks
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* aps.txt — Site-Wide Governance Declaration
|
|
3
|
+
*
|
|
4
|
+
* Like robots.txt but for AI governance. A file at yourdomain.com/aps.txt
|
|
5
|
+
* declares site-wide governance: publisher identity, default terms,
|
|
6
|
+
* revocation endpoint, and MCP upgrade path.
|
|
7
|
+
*
|
|
8
|
+
* Any agent visiting any page on the domain checks aps.txt first.
|
|
9
|
+
* One file governs the entire site.
|
|
10
|
+
*
|
|
11
|
+
* Format: JSON, signed with Ed25519, served at /.well-known/aps.txt or /aps.txt
|
|
12
|
+
*/
|
|
13
|
+
import type { GovernanceTerms, RevocationPolicy } from './governance-block.js';
|
|
14
|
+
export interface ApsTxt {
|
|
15
|
+
/** APS protocol identifier */
|
|
16
|
+
'@context': 'https://aeoess.com/governance/v1';
|
|
17
|
+
'@type': 'ApsTxt';
|
|
18
|
+
/** Domain this declaration covers */
|
|
19
|
+
domain: string;
|
|
20
|
+
/** Publisher's DID */
|
|
21
|
+
publisher_did: string;
|
|
22
|
+
/** Publisher name (human-readable) */
|
|
23
|
+
publisher_name: string;
|
|
24
|
+
/** Default terms for all content on this domain */
|
|
25
|
+
default_terms: GovernanceTerms;
|
|
26
|
+
/** Default revocation policy */
|
|
27
|
+
default_revocation_policy: RevocationPolicy;
|
|
28
|
+
/** URL for revocation status checks */
|
|
29
|
+
revocation_endpoint?: string;
|
|
30
|
+
/** MCP endpoint for full enforcement channel */
|
|
31
|
+
mcp_endpoint?: string;
|
|
32
|
+
/** Per-path overrides (e.g. /api/* has different terms than /blog/*) */
|
|
33
|
+
path_overrides?: PathOverride[];
|
|
34
|
+
/** When this declaration was generated */
|
|
35
|
+
generated_at: string;
|
|
36
|
+
/** Ed25519 signature */
|
|
37
|
+
signature: string;
|
|
38
|
+
}
|
|
39
|
+
export interface PathOverride {
|
|
40
|
+
/** Glob pattern (e.g. "/api/*", "/blog/*", "/data/**") */
|
|
41
|
+
pattern: string;
|
|
42
|
+
/** Terms override for this path */
|
|
43
|
+
terms: GovernanceTerms;
|
|
44
|
+
/** Optional revocation policy override */
|
|
45
|
+
revocation_policy?: RevocationPolicy;
|
|
46
|
+
}
|
|
47
|
+
export interface GenerateApsTxtInput {
|
|
48
|
+
domain: string;
|
|
49
|
+
publisherName: string;
|
|
50
|
+
publicKey: string;
|
|
51
|
+
privateKey: string;
|
|
52
|
+
defaultTerms: GovernanceTerms;
|
|
53
|
+
defaultRevocationPolicy?: RevocationPolicy;
|
|
54
|
+
revocationEndpoint?: string;
|
|
55
|
+
mcpEndpoint?: string;
|
|
56
|
+
pathOverrides?: PathOverride[];
|
|
57
|
+
}
|
|
58
|
+
export declare function generateApsTxt(input: GenerateApsTxtInput): ApsTxt;
|
|
59
|
+
export declare function verifyApsTxt(doc: ApsTxt, publicKey: string): {
|
|
60
|
+
valid: boolean;
|
|
61
|
+
errors: string[];
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* Resolve terms for a specific path using aps.txt path overrides.
|
|
65
|
+
* Falls back to default_terms if no override matches.
|
|
66
|
+
*/
|
|
67
|
+
export declare function resolveTermsForPath(doc: ApsTxt, path: string): GovernanceTerms;
|
|
68
|
+
/**
|
|
69
|
+
* Serialize aps.txt to a JSON string ready to serve as a file.
|
|
70
|
+
*/
|
|
71
|
+
export declare function serializeApsTxt(doc: ApsTxt): string;
|
|
72
|
+
/**
|
|
73
|
+
* Parse an aps.txt JSON string back to an object.
|
|
74
|
+
*/
|
|
75
|
+
export declare function parseApsTxt(content: string): ApsTxt | null;
|
|
76
|
+
import type { GovernanceBlock } from './governance-block.js';
|
|
77
|
+
/**
|
|
78
|
+
* Generate HTTP response headers for governance.
|
|
79
|
+
* Works for ANY response type — HTML, JSON, images, PDFs.
|
|
80
|
+
*/
|
|
81
|
+
export declare function governanceHeaders(block: GovernanceBlock): Record<string, string>;
|
|
82
|
+
/**
|
|
83
|
+
* Parse governance from HTTP response headers.
|
|
84
|
+
*/
|
|
85
|
+
export declare function parseGovernanceHeaders(headers: Record<string, string>): GovernanceBlock | null;
|
|
86
|
+
export interface ChainedGovernanceBlock extends GovernanceBlock {
|
|
87
|
+
/** Reference to the parent governance block this is derived from */
|
|
88
|
+
parent_block_hash: string;
|
|
89
|
+
/** What type of derivation (summary, embedding, rag_chunk, etc.) */
|
|
90
|
+
derivation_type: string;
|
|
91
|
+
/** The derivative agent's DID (different from original publisher) */
|
|
92
|
+
derivative_agent_did: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Create a chained governance block for derivative content.
|
|
96
|
+
* The derivative carries its own governance AND the chain back to the source.
|
|
97
|
+
*/
|
|
98
|
+
export declare function createChainedGovernanceBlock(input: {
|
|
99
|
+
/** The derivative content */
|
|
100
|
+
content: string;
|
|
101
|
+
/** The derivative agent's keys */
|
|
102
|
+
publicKey: string;
|
|
103
|
+
privateKey: string;
|
|
104
|
+
/** Terms the derivative is published under */
|
|
105
|
+
terms: GovernanceTerms;
|
|
106
|
+
/** The original governance block this derives from */
|
|
107
|
+
parentBlock: GovernanceBlock;
|
|
108
|
+
/** Type of derivation */
|
|
109
|
+
derivationType: string;
|
|
110
|
+
revocationPolicy?: RevocationPolicy;
|
|
111
|
+
}): ChainedGovernanceBlock;
|
|
112
|
+
/**
|
|
113
|
+
* Verify a chained governance block, including parent hash consistency.
|
|
114
|
+
*/
|
|
115
|
+
export declare function verifyChainedBlock(chain: ChainedGovernanceBlock, content: string, derivativePublicKey: string, parentBlock?: GovernanceBlock): {
|
|
116
|
+
valid: boolean;
|
|
117
|
+
chainValid: boolean;
|
|
118
|
+
errors: string[];
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=aps-txt.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aps-txt.d.ts","sourceRoot":"","sources":["../../../src/core/aps-txt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
// Copyright 2024-2026 Tymofii Pidlisnyi. Apache-2.0 license. See LICENSE.
|
|
2
|
+
/**
|
|
3
|
+
* aps.txt — Site-Wide Governance Declaration
|
|
4
|
+
*
|
|
5
|
+
* Like robots.txt but for AI governance. A file at yourdomain.com/aps.txt
|
|
6
|
+
* declares site-wide governance: publisher identity, default terms,
|
|
7
|
+
* revocation endpoint, and MCP upgrade path.
|
|
8
|
+
*
|
|
9
|
+
* Any agent visiting any page on the domain checks aps.txt first.
|
|
10
|
+
* One file governs the entire site.
|
|
11
|
+
*
|
|
12
|
+
* Format: JSON, signed with Ed25519, served at /.well-known/aps.txt or /aps.txt
|
|
13
|
+
*/
|
|
14
|
+
import { createHash } from 'node:crypto';
|
|
15
|
+
import { sign, verify, canonicalize, createDID } from '../index.js';
|
|
16
|
+
import { DEFAULT_REVOCATION_POLICY } from './governance-block.js';
|
|
17
|
+
export function generateApsTxt(input) {
|
|
18
|
+
const publisherDid = createDID(input.publicKey);
|
|
19
|
+
const now = new Date().toISOString();
|
|
20
|
+
const doc = {
|
|
21
|
+
'@context': 'https://aeoess.com/governance/v1',
|
|
22
|
+
'@type': 'ApsTxt',
|
|
23
|
+
domain: input.domain,
|
|
24
|
+
publisher_did: publisherDid,
|
|
25
|
+
publisher_name: input.publisherName,
|
|
26
|
+
default_terms: input.defaultTerms,
|
|
27
|
+
default_revocation_policy: input.defaultRevocationPolicy || DEFAULT_REVOCATION_POLICY,
|
|
28
|
+
generated_at: now,
|
|
29
|
+
...(input.revocationEndpoint && { revocation_endpoint: input.revocationEndpoint }),
|
|
30
|
+
...(input.mcpEndpoint && { mcp_endpoint: input.mcpEndpoint }),
|
|
31
|
+
...(input.pathOverrides?.length && { path_overrides: input.pathOverrides }),
|
|
32
|
+
};
|
|
33
|
+
const payload = canonicalize(doc);
|
|
34
|
+
const signature = sign(payload, input.privateKey);
|
|
35
|
+
return { ...doc, signature };
|
|
36
|
+
}
|
|
37
|
+
export function verifyApsTxt(doc, publicKey) {
|
|
38
|
+
const errors = [];
|
|
39
|
+
const { signature, ...rest } = doc;
|
|
40
|
+
const payload = canonicalize(rest);
|
|
41
|
+
const sigValid = verify(payload, signature, publicKey);
|
|
42
|
+
if (!sigValid)
|
|
43
|
+
errors.push('Signature verification failed');
|
|
44
|
+
const expectedDid = createDID(publicKey);
|
|
45
|
+
if (doc.publisher_did !== expectedDid)
|
|
46
|
+
errors.push(`DID mismatch: expected ${expectedDid}`);
|
|
47
|
+
return { valid: errors.length === 0, errors };
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve terms for a specific path using aps.txt path overrides.
|
|
51
|
+
* Falls back to default_terms if no override matches.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveTermsForPath(doc, path) {
|
|
54
|
+
if (doc.path_overrides) {
|
|
55
|
+
for (const override of doc.path_overrides) {
|
|
56
|
+
if (matchGlob(override.pattern, path)) {
|
|
57
|
+
return { ...doc.default_terms, ...override.terms };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return doc.default_terms;
|
|
62
|
+
}
|
|
63
|
+
function matchGlob(pattern, path) {
|
|
64
|
+
// Simple glob: * matches one segment, ** matches multiple segments
|
|
65
|
+
const regex = pattern
|
|
66
|
+
.replace(/\*\*/g, '§DOUBLESTAR§')
|
|
67
|
+
.replace(/\*/g, '[^/]*')
|
|
68
|
+
.replace(/§DOUBLESTAR§/g, '.*');
|
|
69
|
+
return new RegExp(`^${regex}$`).test(path);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Serialize aps.txt to a JSON string ready to serve as a file.
|
|
73
|
+
*/
|
|
74
|
+
export function serializeApsTxt(doc) {
|
|
75
|
+
return JSON.stringify(doc, null, 2);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Parse an aps.txt JSON string back to an object.
|
|
79
|
+
*/
|
|
80
|
+
export function parseApsTxt(content) {
|
|
81
|
+
try {
|
|
82
|
+
const parsed = JSON.parse(content);
|
|
83
|
+
if (parsed['@type'] !== 'ApsTxt')
|
|
84
|
+
return null;
|
|
85
|
+
return parsed;
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Generate HTTP response headers for governance.
|
|
93
|
+
* Works for ANY response type — HTML, JSON, images, PDFs.
|
|
94
|
+
*/
|
|
95
|
+
export function governanceHeaders(block) {
|
|
96
|
+
const compact = JSON.stringify(block);
|
|
97
|
+
const b64 = Buffer.from(compact).toString('base64');
|
|
98
|
+
return {
|
|
99
|
+
'X-APS-Governance': b64,
|
|
100
|
+
'X-APS-DID': block.source_did,
|
|
101
|
+
'X-APS-Content-Hash': block.content_hash,
|
|
102
|
+
'X-APS-Terms-Training': block.terms.training || 'not_specified',
|
|
103
|
+
'X-APS-Terms-Inference': block.terms.inference || 'not_specified',
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Parse governance from HTTP response headers.
|
|
108
|
+
*/
|
|
109
|
+
export function parseGovernanceHeaders(headers) {
|
|
110
|
+
const b64 = headers['x-aps-governance'] || headers['X-APS-Governance'];
|
|
111
|
+
if (!b64)
|
|
112
|
+
return null;
|
|
113
|
+
try {
|
|
114
|
+
return JSON.parse(Buffer.from(b64, 'base64').toString('utf-8'));
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Create a chained governance block for derivative content.
|
|
122
|
+
* The derivative carries its own governance AND the chain back to the source.
|
|
123
|
+
*/
|
|
124
|
+
export function createChainedGovernanceBlock(input) {
|
|
125
|
+
const contentHash = `sha256:${createHash('sha256').update(input.content).digest('hex')}`;
|
|
126
|
+
const derivativeDid = createDID(input.publicKey);
|
|
127
|
+
const parentBlockHash = `sha256:${createHash('sha256').update(canonicalize(input.parentBlock)).digest('hex')}`;
|
|
128
|
+
const now = new Date().toISOString();
|
|
129
|
+
const block = {
|
|
130
|
+
'@context': 'https://aeoess.com/governance/v1',
|
|
131
|
+
'@type': 'GovernanceBlock',
|
|
132
|
+
source_did: input.parentBlock.source_did,
|
|
133
|
+
content_hash: contentHash,
|
|
134
|
+
published_at: now,
|
|
135
|
+
governance_generated_at: now,
|
|
136
|
+
terms: input.terms,
|
|
137
|
+
revocation_policy: input.revocationPolicy || input.parentBlock.revocation_policy,
|
|
138
|
+
parent_block_hash: parentBlockHash,
|
|
139
|
+
derivation_type: input.derivationType,
|
|
140
|
+
derivative_agent_did: derivativeDid,
|
|
141
|
+
};
|
|
142
|
+
const payload = canonicalize(block);
|
|
143
|
+
const signature = sign(payload, input.privateKey);
|
|
144
|
+
return { ...block, signature };
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Verify a chained governance block, including parent hash consistency.
|
|
148
|
+
*/
|
|
149
|
+
export function verifyChainedBlock(chain, content, derivativePublicKey, parentBlock) {
|
|
150
|
+
const errors = [];
|
|
151
|
+
// Verify derivative signature
|
|
152
|
+
const { signature, ...rest } = chain;
|
|
153
|
+
const payload = canonicalize(rest);
|
|
154
|
+
const sigValid = verify(payload, signature, derivativePublicKey);
|
|
155
|
+
if (!sigValid)
|
|
156
|
+
errors.push('Derivative signature verification failed');
|
|
157
|
+
// Verify content hash
|
|
158
|
+
const expectedHash = `sha256:${createHash('sha256').update(content).digest('hex')}`;
|
|
159
|
+
if (chain.content_hash !== expectedHash)
|
|
160
|
+
errors.push('Content hash mismatch');
|
|
161
|
+
// Verify parent chain if parent provided
|
|
162
|
+
let chainValid = true;
|
|
163
|
+
if (parentBlock) {
|
|
164
|
+
const expectedParentHash = `sha256:${createHash('sha256').update(canonicalize(parentBlock)).digest('hex')}`;
|
|
165
|
+
if (chain.parent_block_hash !== expectedParentHash) {
|
|
166
|
+
errors.push('Parent block hash mismatch — chain broken');
|
|
167
|
+
chainValid = false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return { valid: sigValid && errors.length === 0, chainValid, errors };
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=aps-txt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aps-txt.js","sourceRoot":"","sources":["../../../src/core/aps-txt.ts"],"names":[],"mappings":"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"}
|
|
@@ -15,8 +15,20 @@ export declare class ProxyGateway {
|
|
|
15
15
|
private requestsSinceCleanup;
|
|
16
16
|
private agentLocks;
|
|
17
17
|
private executor;
|
|
18
|
+
private storage?;
|
|
18
19
|
private stats;
|
|
19
20
|
constructor(config: GatewayConfig, executor: ToolExecutor);
|
|
21
|
+
/**
|
|
22
|
+
* Load persisted state from StorageBackend into in-memory Maps.
|
|
23
|
+
* Call after constructor when using persistent storage.
|
|
24
|
+
* Performs integrity verification on startup.
|
|
25
|
+
*/
|
|
26
|
+
loadFromStorage(): Promise<{
|
|
27
|
+
loaded: boolean;
|
|
28
|
+
agents: number;
|
|
29
|
+
receipts: number;
|
|
30
|
+
errors: string[];
|
|
31
|
+
}>;
|
|
20
32
|
registerAgent(passport: RegisteredAgent['passport'], attestation: FloorAttestation, delegations: Delegation[], role?: GatewayAgentRole): {
|
|
21
33
|
registered: boolean;
|
|
22
34
|
error?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../src/core/gateway.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"gateway.d.ts","sourceRoot":"","sources":["../../../src/core/gateway.ts"],"names":[],"mappings":"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"}
|
package/dist/src/core/gateway.js
CHANGED
|
@@ -50,6 +50,7 @@ export class ProxyGateway {
|
|
|
50
50
|
requestsSinceCleanup = 0; // V5-MED-4: auto-cleanup counter
|
|
51
51
|
agentLocks = new Map(); // Per-agent sequential execution (concurrency fix)
|
|
52
52
|
executor;
|
|
53
|
+
storage;
|
|
53
54
|
stats = {
|
|
54
55
|
totalRequests: 0,
|
|
55
56
|
totalPermitted: 0,
|
|
@@ -89,13 +90,70 @@ export class ProxyGateway {
|
|
|
89
90
|
};
|
|
90
91
|
this.validator = config.validator || new FloorValidatorV1();
|
|
91
92
|
this.executor = executor;
|
|
92
|
-
|
|
93
|
-
|
|
93
|
+
this.storage = config.storage;
|
|
94
|
+
// B-1 security warning: only if no persistent storage
|
|
95
|
+
if (!this.storage && typeof console !== 'undefined') {
|
|
94
96
|
console.warn('[ProxyGateway] WARNING: All security state (revocations, registrations, replay protection) ' +
|
|
95
97
|
'is stored in-memory. Process restart will erase all security state. ' +
|
|
96
98
|
'NOT SAFE FOR PRODUCTION. Implement a persistent StorageBackend for production use.');
|
|
97
99
|
}
|
|
98
100
|
}
|
|
101
|
+
// ── Storage Persistence (write-through cache) ──
|
|
102
|
+
// Maps remain the hot path for sync lookups.
|
|
103
|
+
// StorageBackend persists behind them for durability.
|
|
104
|
+
// On restart: loadFromStorage() hydrates Maps from backend.
|
|
105
|
+
/**
|
|
106
|
+
* Load persisted state from StorageBackend into in-memory Maps.
|
|
107
|
+
* Call after constructor when using persistent storage.
|
|
108
|
+
* Performs integrity verification on startup.
|
|
109
|
+
*/
|
|
110
|
+
async loadFromStorage() {
|
|
111
|
+
if (!this.storage)
|
|
112
|
+
return { loaded: false, agents: 0, receipts: 0, errors: ['No storage backend configured'] };
|
|
113
|
+
// Integrity check first
|
|
114
|
+
const report = await this.storage.verifyIntegrity();
|
|
115
|
+
if (report.errors.length > 0) {
|
|
116
|
+
return { loaded: false, agents: 0, receipts: report.receiptCount, errors: report.errors };
|
|
117
|
+
}
|
|
118
|
+
// Load agents
|
|
119
|
+
const agents = await this.storage.listAgents();
|
|
120
|
+
for (const stored of agents) {
|
|
121
|
+
// Re-register: load delegations for this agent
|
|
122
|
+
const delegations = await this.storage.getDelegationsForAgent(stored.passport.passport?.publicKey || '');
|
|
123
|
+
const delegationMap = new Map();
|
|
124
|
+
for (const d of delegations) {
|
|
125
|
+
const revoked = await this.storage.isRevoked(d.delegationId);
|
|
126
|
+
if (!revoked)
|
|
127
|
+
delegationMap.set(d.delegationId, d);
|
|
128
|
+
}
|
|
129
|
+
// Load reputation if it exists
|
|
130
|
+
let reputation;
|
|
131
|
+
let authorityTier;
|
|
132
|
+
if (this.config.enableReputationGating) {
|
|
133
|
+
reputation = (await this.storage.getReputation(stored.agentId, '*')) ?? undefined;
|
|
134
|
+
if (reputation) {
|
|
135
|
+
const score = computeEffectiveScore(reputation.mu, reputation.sigma);
|
|
136
|
+
const demotions = await this.storage.getDemotionCount(stored.agentId);
|
|
137
|
+
const tierDef = resolveAuthorityTier(score, demotions);
|
|
138
|
+
authorityTier = {
|
|
139
|
+
tier: tierDef.tier, name: tierDef.name,
|
|
140
|
+
origin: 'earned', autonomyLevel: tierDef.autonomyLevel,
|
|
141
|
+
maxDelegationDepth: tierDef.maxDelegationDepth,
|
|
142
|
+
maxSpendPerAction: tierDef.maxSpendPerAction, demotionCount: demotions,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
this.agents.set(stored.agentId, {
|
|
147
|
+
passport: stored.passport,
|
|
148
|
+
attestation: stored.attestation,
|
|
149
|
+
delegations: delegationMap,
|
|
150
|
+
role: stored.metadata?.role ?? 'executor',
|
|
151
|
+
reputation, authorityTier,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
this.stats.activeAgents = this.agents.size;
|
|
155
|
+
return { loaded: true, agents: agents.length, receipts: report.receiptCount, errors: [] };
|
|
156
|
+
}
|
|
99
157
|
// ── Agent Registration ──
|
|
100
158
|
registerAgent(passport, attestation, delegations, role = 'executor') {
|
|
101
159
|
// Verify passport (SignedPassport wraps AgentPassport)
|
|
@@ -148,6 +206,20 @@ export class ProxyGateway {
|
|
|
148
206
|
activeEscalations: this.config.enableEscalation ? [] : undefined,
|
|
149
207
|
});
|
|
150
208
|
this.stats.activeAgents = this.agents.size;
|
|
209
|
+
// Write-through to persistent storage (fire-and-forget)
|
|
210
|
+
if (this.storage) {
|
|
211
|
+
const s = this.storage;
|
|
212
|
+
(async () => {
|
|
213
|
+
try {
|
|
214
|
+
await s.putAgent({ agentId, passport, attestation, registeredAt: new Date().toISOString() });
|
|
215
|
+
for (const d of delegations)
|
|
216
|
+
await s.putDelegation(d);
|
|
217
|
+
if (reputation)
|
|
218
|
+
await s.putReputation(reputation);
|
|
219
|
+
}
|
|
220
|
+
catch (e) { /* storage write failure — logged but not fatal */ }
|
|
221
|
+
})();
|
|
222
|
+
}
|
|
151
223
|
return { registered: true };
|
|
152
224
|
}
|
|
153
225
|
/** Check if an agent is registered with evaluator role (B-9 security hardening) */
|
|
@@ -696,6 +768,22 @@ export class ProxyGateway {
|
|
|
696
768
|
escalationId: usedEscalationId,
|
|
697
769
|
reversibility: request.reversibility,
|
|
698
770
|
};
|
|
771
|
+
// ── Persist to storage (write-through) ──
|
|
772
|
+
if (this.storage && receipt) {
|
|
773
|
+
const s = this.storage;
|
|
774
|
+
const agentRep = agent.reputation;
|
|
775
|
+
(async () => {
|
|
776
|
+
try {
|
|
777
|
+
await s.transaction(async (tx) => {
|
|
778
|
+
await tx.appendReceipt(receipt);
|
|
779
|
+
await tx.checkAndStoreNonce(request.requestId, Math.floor((this.config.requestIdTTLMs || 3600000) / 1000));
|
|
780
|
+
if (agentRep)
|
|
781
|
+
await tx.putReputation(agentRep);
|
|
782
|
+
});
|
|
783
|
+
}
|
|
784
|
+
catch (_e) { /* storage write failure — in-memory state is still authoritative */ }
|
|
785
|
+
})();
|
|
786
|
+
}
|
|
699
787
|
this.config.onToolCall?.(request, result);
|
|
700
788
|
return result;
|
|
701
789
|
}
|
|
@@ -975,6 +1063,22 @@ export class ProxyGateway {
|
|
|
975
1063
|
}
|
|
976
1064
|
const proof = { requestSignature: approval.intent.signature, decisionSignature: approval.decision.signature, receiptSignature: receipt.signature, policyReceipt };
|
|
977
1065
|
this.stats.pendingApprovals = Array.from(this.approvals.values()).filter(a => !a.consumed).length;
|
|
1066
|
+
// ── Persist to storage (write-through, 2-phase path) ──
|
|
1067
|
+
if (this.storage && receipt) {
|
|
1068
|
+
const s = this.storage;
|
|
1069
|
+
const agentRep = agent.reputation;
|
|
1070
|
+
(async () => {
|
|
1071
|
+
try {
|
|
1072
|
+
await s.transaction(async (tx) => {
|
|
1073
|
+
await tx.appendReceipt(receipt);
|
|
1074
|
+
await tx.checkAndStoreNonce(approval.requestId, Math.floor((this.config.requestIdTTLMs || 3600000) / 1000));
|
|
1075
|
+
if (agentRep)
|
|
1076
|
+
await tx.putReputation(agentRep);
|
|
1077
|
+
});
|
|
1078
|
+
}
|
|
1079
|
+
catch (_e) { /* storage write failure — in-memory state is still authoritative */ }
|
|
1080
|
+
})();
|
|
1081
|
+
}
|
|
978
1082
|
return {
|
|
979
1083
|
executed: true, requestId: approval.requestId,
|
|
980
1084
|
result: toolResult.result, toolError: toolResult.success ? undefined : toolResult.error,
|