agents-chain 0.0.1

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.
Files changed (70) hide show
  1. package/README.md +145 -0
  2. package/dist/audit/audit-log.d.ts +44 -0
  3. package/dist/audit/audit-log.d.ts.map +1 -0
  4. package/dist/audit/audit-log.js +88 -0
  5. package/dist/audit/audit-log.js.map +1 -0
  6. package/dist/auth/token-builder.d.ts +32 -0
  7. package/dist/auth/token-builder.d.ts.map +1 -0
  8. package/dist/auth/token-builder.js +38 -0
  9. package/dist/auth/token-builder.js.map +1 -0
  10. package/dist/auth/token-verifier.d.ts +37 -0
  11. package/dist/auth/token-verifier.d.ts.map +1 -0
  12. package/dist/auth/token-verifier.js +86 -0
  13. package/dist/auth/token-verifier.js.map +1 -0
  14. package/dist/chain.d.ts +36 -0
  15. package/dist/chain.d.ts.map +1 -0
  16. package/dist/chain.js +90 -0
  17. package/dist/chain.js.map +1 -0
  18. package/dist/crypto/ed25519.d.ts +63 -0
  19. package/dist/crypto/ed25519.d.ts.map +1 -0
  20. package/dist/crypto/ed25519.js +118 -0
  21. package/dist/crypto/ed25519.js.map +1 -0
  22. package/dist/crypto/utils.d.ts +18 -0
  23. package/dist/crypto/utils.d.ts.map +1 -0
  24. package/dist/crypto/utils.js +38 -0
  25. package/dist/crypto/utils.js.map +1 -0
  26. package/dist/errors/chain-error.d.ts +18 -0
  27. package/dist/errors/chain-error.d.ts.map +1 -0
  28. package/dist/errors/chain-error.js +22 -0
  29. package/dist/errors/chain-error.js.map +1 -0
  30. package/dist/identity/agent-identity.d.ts +33 -0
  31. package/dist/identity/agent-identity.d.ts.map +1 -0
  32. package/dist/identity/agent-identity.js +73 -0
  33. package/dist/identity/agent-identity.js.map +1 -0
  34. package/dist/index.d.ts +9 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +5 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/lib/utils.d.ts +6 -0
  39. package/dist/lib/utils.d.ts.map +1 -0
  40. package/dist/lib/utils.js +25 -0
  41. package/dist/lib/utils.js.map +1 -0
  42. package/dist/memory/encrypted-store.d.ts +29 -0
  43. package/dist/memory/encrypted-store.d.ts.map +1 -0
  44. package/dist/memory/encrypted-store.js +102 -0
  45. package/dist/memory/encrypted-store.js.map +1 -0
  46. package/dist/memory/jti-cache.d.ts +22 -0
  47. package/dist/memory/jti-cache.d.ts.map +1 -0
  48. package/dist/memory/jti-cache.js +43 -0
  49. package/dist/memory/jti-cache.js.map +1 -0
  50. package/dist/types/audit.d.ts +16 -0
  51. package/dist/types/audit.d.ts.map +1 -0
  52. package/dist/types/audit.js +2 -0
  53. package/dist/types/audit.js.map +1 -0
  54. package/dist/types/chain.d.ts +19 -0
  55. package/dist/types/chain.d.ts.map +1 -0
  56. package/dist/types/chain.js +2 -0
  57. package/dist/types/chain.js.map +1 -0
  58. package/dist/types/identity.d.ts +35 -0
  59. package/dist/types/identity.d.ts.map +1 -0
  60. package/dist/types/identity.js +3 -0
  61. package/dist/types/identity.js.map +1 -0
  62. package/dist/wrappers/anthropic-wrapper.d.ts +31 -0
  63. package/dist/wrappers/anthropic-wrapper.d.ts.map +1 -0
  64. package/dist/wrappers/anthropic-wrapper.js +97 -0
  65. package/dist/wrappers/anthropic-wrapper.js.map +1 -0
  66. package/dist/wrappers/openai-wrapper.d.ts +34 -0
  67. package/dist/wrappers/openai-wrapper.d.ts.map +1 -0
  68. package/dist/wrappers/openai-wrapper.js +106 -0
  69. package/dist/wrappers/openai-wrapper.js.map +1 -0
  70. package/package.json +56 -0
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Ed25519 key operations and JWT construction using only node:crypto.
3
+ *
4
+ * - Zero external JWT library dependency
5
+ * - All signing uses EdDSA (Ed25519) via crypto.subtle
6
+ * - Never pass Buffer directly to crypto.subtle — always Uint8Array
7
+ */
8
+ import { type JwtTyp } from "./utils.js";
9
+ export type JwtHeader = {
10
+ alg: "EdDSA";
11
+ typ: JwtTyp;
12
+ kid?: string;
13
+ };
14
+ export type JwtPayload = {
15
+ iss?: string;
16
+ sub?: string;
17
+ aud?: string;
18
+ exp?: number;
19
+ iat?: number;
20
+ jti?: string;
21
+ [key: string]: unknown;
22
+ };
23
+ export type DecodedJwt<T extends JwtPayload = JwtPayload> = {
24
+ header: JwtHeader;
25
+ payload: T;
26
+ signingInput: string;
27
+ signature: string;
28
+ };
29
+ export type VerifyJwtOptions = {
30
+ expectedTyp: JwtTyp;
31
+ };
32
+ export type JwksResponse = {
33
+ keys: JsonWebKey[];
34
+ };
35
+ export declare function generateKeyPair(): Promise<{
36
+ publicKey: CryptoKey;
37
+ privateKey: CryptoKey;
38
+ }>;
39
+ export declare function exportPublicKeyJwk(key: CryptoKey): Promise<JsonWebKey>;
40
+ export declare function exportPrivateKeyJwk(key: CryptoKey): Promise<JsonWebKey>;
41
+ export declare function importPublicKeyJwk(jwk: JsonWebKey): Promise<CryptoKey>;
42
+ export declare function importPrivateKeyJwk(jwk: JsonWebKey): Promise<CryptoKey>;
43
+ /**
44
+ * Compute the SHA-256 JWK thumbprint of an Ed25519 public key.
45
+ * Canonical JSON: only crv, kty, x — sorted lexicographically.
46
+ */
47
+ export declare function computeJwkThumbprint(jwk: JsonWebKey): string;
48
+ /**
49
+ * Sign a compact JWT using Ed25519.
50
+ * The private key signs header.payload — signature covers both parts.
51
+ */
52
+ export declare function signJwt<T extends JwtPayload>(payload: T, privateKey: CryptoKey, typ: JwtTyp): Promise<string>;
53
+ /**
54
+ * Decode a JWT without verifying its signature.
55
+ * Used to extract claims before key lookup. Never trust these claims for auth.
56
+ */
57
+ export declare function decodeJwtUnsafe<T extends JwtPayload = JwtPayload>(token: string): DecodedJwt<T>;
58
+ /**
59
+ * Verify an Ed25519 JWT signature and confirm typ matches.
60
+ * Does NOT check exp/iat/jti — TokenVerifier handles those.
61
+ */
62
+ export declare function verifyJwtSignature<T extends JwtPayload = JwtPayload>(token: string, publicKey: CryptoKey, opts: VerifyJwtOptions): Promise<DecodedJwt<T>>;
63
+ //# sourceMappingURL=ed25519.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ed25519.d.ts","sourceRoot":"","sources":["../../src/crypto/ed25519.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAyD,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAIhG,MAAM,MAAM,SAAS,GAAG;IACpB,GAAG,EAAE,OAAO,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,IAAI;IACxD,MAAM,EAAE,SAAS,CAAC;IAClB,OAAO,EAAE,CAAC,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC3B,WAAW,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACvB,IAAI,EAAE,UAAU,EAAE,CAAC;CACtB,CAAC;AAIF,wBAAsB,eAAe,IAAI,OAAO,CAAC;IAC7C,SAAS,EAAE,SAAS,CAAC;IACrB,UAAU,EAAE,SAAS,CAAC;CACzB,CAAC,CAOD;AAID,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAE5E;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAE7E;AAED,wBAAsB,kBAAkB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAW5E;AAED,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAW7E;AAID;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,UAAU,GAAG,MAAM,CAO5D;AAQD;;;GAGG;AACH,wBAAsB,OAAO,CAAC,CAAC,SAAS,UAAU,EAC9C,OAAO,EAAE,CAAC,EACV,UAAU,EAAE,SAAS,EACrB,GAAG,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAcjB;AASD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EAC7D,KAAK,EAAE,MAAM,GACd,UAAU,CAAC,CAAC,CAAC,CAwBf;AAID;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU,EACtE,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,gBAAgB,GACvB,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAyBxB"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Ed25519 key operations and JWT construction using only node:crypto.
3
+ *
4
+ * - Zero external JWT library dependency
5
+ * - All signing uses EdDSA (Ed25519) via crypto.subtle
6
+ * - Never pass Buffer directly to crypto.subtle — always Uint8Array
7
+ */
8
+ import { createHash } from "node:crypto";
9
+ import { base64UrlDecode, base64UrlEncode, isObject, parseJson } from "./utils.js";
10
+ // ─── Key Generation ───────────────────────────────────────────────────────────
11
+ export async function generateKeyPair() {
12
+ const keypair = await crypto.subtle.generateKey("Ed25519", true, ["sign", "verify"]);
13
+ return { publicKey: keypair.publicKey, privateKey: keypair.privateKey };
14
+ }
15
+ // ─── JWK Export / Import ──────────────────────────────────────────────────────
16
+ export async function exportPublicKeyJwk(key) {
17
+ return crypto.subtle.exportKey("jwk", key);
18
+ }
19
+ export async function exportPrivateKeyJwk(key) {
20
+ return crypto.subtle.exportKey("jwk", key);
21
+ }
22
+ export async function importPublicKeyJwk(jwk) {
23
+ if (jwk.kty !== "OKP" || jwk.crv !== "Ed25519" || !jwk.x) {
24
+ throw new Error("Invalid Ed25519 public JWK: must be OKP/Ed25519 with x field");
25
+ }
26
+ return crypto.subtle.importKey("jwk", jwk, { name: "Ed25519" }, true, ["verify"]);
27
+ }
28
+ export async function importPrivateKeyJwk(jwk) {
29
+ if (jwk.kty !== "OKP" || jwk.crv !== "Ed25519" || !jwk.x || !jwk.d) {
30
+ throw new Error("Invalid Ed25519 private JWK: must be OKP/Ed25519 with x and d fields");
31
+ }
32
+ return crypto.subtle.importKey("jwk", jwk, { name: "Ed25519" }, true, ["sign"]);
33
+ }
34
+ // ─── JWK Thumbprint (RFC 7638) ────────────────────────────────────────────────
35
+ /**
36
+ * Compute the SHA-256 JWK thumbprint of an Ed25519 public key.
37
+ * Canonical JSON: only crv, kty, x — sorted lexicographically.
38
+ */
39
+ export function computeJwkThumbprint(jwk) {
40
+ if (jwk.kty !== "OKP" || jwk.crv !== "Ed25519" || !jwk.x) {
41
+ throw new Error("Invalid Ed25519 JWK for thumbprint computation");
42
+ }
43
+ const canonical = JSON.stringify({ crv: jwk.crv, kty: jwk.kty, x: jwk.x });
44
+ const hash = createHash("sha256").update(canonical).digest();
45
+ return base64UrlEncode(hash);
46
+ }
47
+ // ─── JWT Construction ─────────────────────────────────────────────────────────
48
+ function encodeJwtPart(obj) {
49
+ return base64UrlEncode(Buffer.from(JSON.stringify(obj)));
50
+ }
51
+ /**
52
+ * Sign a compact JWT using Ed25519.
53
+ * The private key signs header.payload — signature covers both parts.
54
+ */
55
+ export async function signJwt(payload, privateKey, typ) {
56
+ const header = { alg: "EdDSA", typ };
57
+ const encodedHeader = encodeJwtPart(header);
58
+ const encodedPayload = encodeJwtPart(payload);
59
+ const signingInput = `${encodedHeader}.${encodedPayload}`;
60
+ const sigBytes = await crypto.subtle.sign("Ed25519", privateKey, new TextEncoder().encode(signingInput) // Uint8Array — NOT Buffer
61
+ );
62
+ const sig = base64UrlEncode(new Uint8Array(sigBytes));
63
+ return `${signingInput}.${sig}`;
64
+ }
65
+ // ─── JWT Decoding (without verification) ─────────────────────────────────────
66
+ function isJwtHeader(value) {
67
+ if (!isObject(value))
68
+ return false;
69
+ return value["alg"] === "EdDSA" && value["typ"] === "agent+jwt";
70
+ }
71
+ /**
72
+ * Decode a JWT without verifying its signature.
73
+ * Used to extract claims before key lookup. Never trust these claims for auth.
74
+ */
75
+ export function decodeJwtUnsafe(token) {
76
+ const parts = token.split(".");
77
+ if (parts.length !== 3) {
78
+ throw new Error("Invalid JWT format: expected 3 dot-separated parts");
79
+ }
80
+ const [headerB64, payloadB64, signature] = parts;
81
+ const rawHeader = parseJson(base64UrlDecode(headerB64).toString("utf8"));
82
+ if (!isJwtHeader(rawHeader)) {
83
+ throw new Error("Invalid JWT header: expected alg=EdDSA, typ=agent+jwt");
84
+ }
85
+ const rawPayload = parseJson(base64UrlDecode(payloadB64).toString("utf8"));
86
+ if (!isObject(rawPayload)) {
87
+ throw new Error("Invalid JWT payload: not a JSON object");
88
+ }
89
+ return {
90
+ header: rawHeader,
91
+ payload: rawPayload,
92
+ signingInput: `${headerB64}.${payloadB64}`,
93
+ signature,
94
+ };
95
+ }
96
+ // ─── JWT Verification ─────────────────────────────────────────────────────────
97
+ /**
98
+ * Verify an Ed25519 JWT signature and confirm typ matches.
99
+ * Does NOT check exp/iat/jti — TokenVerifier handles those.
100
+ */
101
+ export async function verifyJwtSignature(token, publicKey, opts) {
102
+ const decoded = decodeJwtUnsafe(token);
103
+ if (decoded.header.typ !== opts.expectedTyp) {
104
+ throw new Error(`JWT typ mismatch: expected "${opts.expectedTyp}", got "${decoded.header.typ}"`);
105
+ }
106
+ if (decoded.header.alg !== "EdDSA") {
107
+ throw new Error(`JWT alg mismatch: expected "EdDSA", got "${decoded.header.alg}"`);
108
+ }
109
+ const sigBytes = new Uint8Array(base64UrlDecode(decoded.signature));
110
+ const inputBytes = new TextEncoder().encode(decoded.signingInput);
111
+ const valid = await crypto.subtle.verify("Ed25519", publicKey, sigBytes, inputBytes // Uint8Array — NOT Buffer
112
+ );
113
+ if (!valid) {
114
+ throw new Error("JWT signature verification failed: signature does not match");
115
+ }
116
+ return decoded;
117
+ }
118
+ //# sourceMappingURL=ed25519.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ed25519.js","sourceRoot":"","sources":["../../src/crypto/ed25519.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export type JwtTyp = "agent+jwt";
2
+ export declare function base64UrlEncode(buffer: Buffer | Uint8Array): string;
3
+ export declare function base64UrlDecode(str: string): Buffer;
4
+ /**
5
+ * Generate a cryptographically random ID.
6
+ * Format: <prefix>_<22 base64url chars> (128-bit entropy).
7
+ * When a hostname is provided the format is: <hostname>-<suffix>-<22chars>
8
+ */
9
+ export declare function generateId(prefix: string): string;
10
+ /**
11
+ * Build a host-scoped agent ID.
12
+ * Format: <hostname>-agent-<32 hex chars>
13
+ * The 32 hex chars = 128-bit random, making collision negligible.
14
+ */
15
+ export declare function generateAgentId(hostname: string): string;
16
+ export declare function isObject(value: unknown): value is Record<string, unknown>;
17
+ export declare function parseJson<T>(value: string): T;
18
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/crypto/utils.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,MAAM,GAAG,WAAW,CAAC;AAEjC,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAMnE;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGnD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAE7C"}
@@ -0,0 +1,38 @@
1
+ import { randomBytes } from "node:crypto";
2
+ export function base64UrlEncode(buffer) {
3
+ return Buffer.from(buffer)
4
+ .toString("base64")
5
+ .replace(/\+/g, "-")
6
+ .replace(/\//g, "_")
7
+ .replace(/=/g, "");
8
+ }
9
+ export function base64UrlDecode(str) {
10
+ const padded = str + "=".repeat((4 - (str.length % 4)) % 4);
11
+ return Buffer.from(padded.replace(/-/g, "+").replace(/_/g, "/"), "base64");
12
+ }
13
+ /**
14
+ * Generate a cryptographically random ID.
15
+ * Format: <prefix>_<22 base64url chars> (128-bit entropy).
16
+ * When a hostname is provided the format is: <hostname>-<suffix>-<22chars>
17
+ */
18
+ export function generateId(prefix) {
19
+ const suffix = base64UrlEncode(randomBytes(16));
20
+ return `${prefix}_${suffix}`;
21
+ }
22
+ /**
23
+ * Build a host-scoped agent ID.
24
+ * Format: <hostname>-agent-<32 hex chars>
25
+ * The 32 hex chars = 128-bit random, making collision negligible.
26
+ */
27
+ export function generateAgentId(hostname) {
28
+ const random = randomBytes(16).toString("hex"); // 32 hex chars
29
+ const safe = hostname.toLowerCase().replace(/[^a-z0-9]/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "");
30
+ return `${safe}-agent-${random}`;
31
+ }
32
+ export function isObject(value) {
33
+ return typeof value === "object" && value !== null && !Array.isArray(value);
34
+ }
35
+ export function parseJson(value) {
36
+ return JSON.parse(value);
37
+ }
38
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/crypto/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI1C,MAAM,UAAU,eAAe,CAAC,MAA2B;IACvD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SACrB,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW;IACvC,MAAM,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC/E,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,MAAc;IACrC,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,OAAO,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe;IAC/D,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;IACzG,OAAO,GAAG,IAAI,UAAU,MAAM,EAAE,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAChF,CAAC;AAED,MAAM,UAAU,SAAS,CAAI,KAAa;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;AAClC,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * ChainAuthError — thrown when an agent call is blocked by agents-chain.
3
+ *
4
+ * error codes:
5
+ * "capability_denied" — agent does not hold a grant for this capability
6
+ * "constraint_violated" — capability args violate a constraint
7
+ * "token_replayed" — JWT ID has already been used (replay attack)
8
+ * "token_expired" — JWT exp has passed
9
+ * "token_invalid" — JWT is structurally or cryptographically invalid
10
+ * "agent_not_found" — agentId in the JWT does not match registered agent
11
+ */
12
+ export type ChainErrorCode = "capability_denied" | "constraint_violated" | "token_replayed" | "token_expired" | "token_invalid" | "agent_not_found";
13
+ export declare class ChainAuthError extends Error {
14
+ readonly code: ChainErrorCode;
15
+ readonly violations?: string[];
16
+ constructor(code: ChainErrorCode, message: string, violations?: string[]);
17
+ }
18
+ //# sourceMappingURL=chain-error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain-error.d.ts","sourceRoot":"","sources":["../../src/errors/chain-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,MAAM,cAAc,GACpB,mBAAmB,GACnB,qBAAqB,GACrB,gBAAgB,GAChB,eAAe,GACf,eAAe,GACf,iBAAiB,CAAC;AAExB,qBAAa,cAAe,SAAQ,KAAK;IACrC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC;IAC9B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;gBAEnB,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE;CAQ3E"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * ChainAuthError — thrown when an agent call is blocked by agents-chain.
3
+ *
4
+ * error codes:
5
+ * "capability_denied" — agent does not hold a grant for this capability
6
+ * "constraint_violated" — capability args violate a constraint
7
+ * "token_replayed" — JWT ID has already been used (replay attack)
8
+ * "token_expired" — JWT exp has passed
9
+ * "token_invalid" — JWT is structurally or cryptographically invalid
10
+ * "agent_not_found" — agentId in the JWT does not match registered agent
11
+ */
12
+ export class ChainAuthError extends Error {
13
+ constructor(code, message, violations) {
14
+ super(message);
15
+ this.name = "ChainAuthError";
16
+ this.code = code;
17
+ this.violations = violations;
18
+ // Maintain proper prototype chain for instanceof checks
19
+ Object.setPrototypeOf(this, ChainAuthError.prototype);
20
+ }
21
+ }
22
+ //# sourceMappingURL=chain-error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chain-error.js","sourceRoot":"","sources":["../../src/errors/chain-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAUH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAIrC,YAAY,IAAoB,EAAE,OAAe,EAAE,UAAqB;QACpE,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,wDAAwD;QACxD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,cAAc,CAAC,SAAS,CAAC,CAAC;IAC1D,CAAC;CACJ"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * AgentIdentity — holds the Ed25519 keypair and registration record for one agent.
3
+ *
4
+ * The private key is held exclusively in memory as a non-exportable CryptoKey
5
+ * after the initial setup. The public key is stored (encrypted) in the
6
+ * EncryptedStore as a JWK for verification during token checks.
7
+ *
8
+ * Agent ID format: <hostname>-agent-<32 hex chars>
9
+ * Example: myapp-agent-a3f9bc1d2e4f6789abcdef0123456789
10
+ */
11
+ import type { AgentConfig, CapabilityGrant, RegisteredAgent } from "../types/identity.js";
12
+ import type { EncryptedStore } from "../memory/encrypted-store.js";
13
+ export declare class AgentIdentity {
14
+ readonly privateKey: CryptoKey;
15
+ readonly registration: RegisteredAgent;
16
+ private constructor();
17
+ /**
18
+ * Create a new agent identity:
19
+ * 1. Generate an Ed25519 keypair
20
+ * 2. Derive the agentId from hostname
21
+ * 3. Compute the public key thumbprint (used as the JWT `iss`)
22
+ * 4. Store the registration (encrypted) in the provided store
23
+ */
24
+ static create(config: AgentConfig, store: EncryptedStore): Promise<AgentIdentity>;
25
+ static restore(privateKey: CryptoKey, store: EncryptedStore): Promise<AgentIdentity>;
26
+ get agentId(): string;
27
+ get thumbprint(): string;
28
+ get capabilityNames(): string[];
29
+ hasCapability(name: string): boolean;
30
+ getGrant(name: string): CapabilityGrant | undefined;
31
+ getPublicKey(): Promise<CryptoKey>;
32
+ }
33
+ //# sourceMappingURL=agent-identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-identity.d.ts","sourceRoot":"","sources":["../../src/identity/agent-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAInE,qBAAa,aAAa;IACtB,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IAEvC,OAAO;IAKP;;;;;;OAMG;WACU,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;WA0B1E,OAAO,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAS1F,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,UAAU,IAAI,MAAM,CAEvB;IAGD,IAAI,eAAe,IAAI,MAAM,EAAE,CAE9B;IAED,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAIpC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,SAAS;IAI7C,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC;CAG3C"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * AgentIdentity — holds the Ed25519 keypair and registration record for one agent.
3
+ *
4
+ * The private key is held exclusively in memory as a non-exportable CryptoKey
5
+ * after the initial setup. The public key is stored (encrypted) in the
6
+ * EncryptedStore as a JWK for verification during token checks.
7
+ *
8
+ * Agent ID format: <hostname>-agent-<32 hex chars>
9
+ * Example: myapp-agent-a3f9bc1d2e4f6789abcdef0123456789
10
+ */
11
+ import { generateKeyPair, exportPublicKeyJwk, computeJwkThumbprint, importPublicKeyJwk, } from "../crypto/ed25519.js";
12
+ import { generateAgentId } from "../crypto/utils.js";
13
+ const STORE_KEY_IDENTITY = "agent:identity";
14
+ export class AgentIdentity {
15
+ constructor(privateKey, registration) {
16
+ this.privateKey = privateKey;
17
+ this.registration = registration;
18
+ }
19
+ /**
20
+ * Create a new agent identity:
21
+ * 1. Generate an Ed25519 keypair
22
+ * 2. Derive the agentId from hostname
23
+ * 3. Compute the public key thumbprint (used as the JWT `iss`)
24
+ * 4. Store the registration (encrypted) in the provided store
25
+ */
26
+ static async create(config, store) {
27
+ const { publicKey, privateKey } = await generateKeyPair();
28
+ const publicKeyJwk = await exportPublicKeyJwk(publicKey);
29
+ const thumbprint = computeJwkThumbprint(publicKeyJwk);
30
+ const agentId = generateAgentId(config.hostname);
31
+ const grants = config.capabilities.map((cap) => ({
32
+ capability: cap,
33
+ grantedAt: Date.now(),
34
+ }));
35
+ const registration = {
36
+ agentId,
37
+ agentName: config.agentName,
38
+ hostname: config.hostname,
39
+ publicKeyJwk,
40
+ thumbprint,
41
+ capabilities: grants,
42
+ registeredAt: Date.now(),
43
+ };
44
+ store.set(STORE_KEY_IDENTITY, registration);
45
+ return new AgentIdentity(privateKey, registration);
46
+ }
47
+ static async restore(privateKey, store) {
48
+ const registration = store.get(STORE_KEY_IDENTITY);
49
+ if (!registration) {
50
+ throw new Error("AgentIdentity.restore: no identity found in store");
51
+ }
52
+ return new AgentIdentity(privateKey, registration);
53
+ }
54
+ get agentId() {
55
+ return this.registration.agentId;
56
+ }
57
+ get thumbprint() {
58
+ return this.registration.thumbprint;
59
+ }
60
+ get capabilityNames() {
61
+ return this.registration.capabilities.map((g) => g.capability);
62
+ }
63
+ hasCapability(name) {
64
+ return this.registration.capabilities.some((g) => g.capability === name);
65
+ }
66
+ getGrant(name) {
67
+ return this.registration.capabilities.find((g) => g.capability === name);
68
+ }
69
+ async getPublicKey() {
70
+ return importPublicKeyJwk(this.registration.publicKeyJwk);
71
+ }
72
+ }
73
+ //# sourceMappingURL=agent-identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-identity.js","sourceRoot":"","sources":["../../src/identity/agent-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EACH,eAAe,EACf,kBAAkB,EAClB,oBAAoB,EACpB,kBAAkB,GACrB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAIrD,MAAM,kBAAkB,GAAG,gBAAgB,CAAC;AAE5C,MAAM,OAAO,aAAa;IAItB,YAAoB,UAAqB,EAAE,YAA6B;QACpE,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACrC,CAAC;IAED;;;;;;OAMG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAmB,EAAE,KAAqB;QAC1D,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAAM,eAAe,EAAE,CAAC;QAC1D,MAAM,YAAY,GAAG,MAAM,kBAAkB,CAAC,SAAS,CAAC,CAAC;QACzD,MAAM,UAAU,GAAG,oBAAoB,CAAC,YAAY,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAEjD,MAAM,MAAM,GAAsB,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YAChE,UAAU,EAAE,GAAG;YACf,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACxB,CAAC,CAAC,CAAC;QAEJ,MAAM,YAAY,GAAoB;YAClC,OAAO;YACP,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,YAAY;YACZ,UAAU;YACV,YAAY,EAAE,MAAM;YACpB,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;SAC3B,CAAC;QAEF,KAAK,CAAC,GAAG,CAAC,kBAAkB,EAAE,YAAY,CAAC,CAAC;QAE5C,OAAO,IAAI,aAAa,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC;IAED,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,UAAqB,EAAE,KAAqB;QAC7D,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAkB,kBAAkB,CAAC,CAAC;QACpE,IAAI,CAAC,YAAY,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;QACzE,CAAC;QACD,OAAO,IAAI,aAAa,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC;IAGD,IAAI,OAAO;QACP,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC;IACrC,CAAC;IAED,IAAI,UAAU;QACV,OAAO,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC;IACxC,CAAC;IAGD,IAAI,eAAe;QACf,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACnE,CAAC;IAED,aAAa,CAAC,IAAY;QACtB,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC;IAC7E,CAAC;IAED,QAAQ,CAAC,IAAY;QACjB,OAAO,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,IAAI,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,YAAY;QACd,OAAO,kBAAkB,CAAC,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;IAC9D,CAAC;CACJ"}
@@ -0,0 +1,9 @@
1
+ export { AgentsChain } from "./chain.js";
2
+ export { ChainAuthError } from "./errors/chain-error.js";
3
+ export type { ChainErrorCode } from "./errors/chain-error.js";
4
+ export type { AgentConfig, ChainStats, AuditSnapshot } from "./types/chain.js";
5
+ export type { AuditEntry, AuditResult } from "./types/audit.js";
6
+ export type { RegisteredAgent, CapabilityGrant, CapabilityConstraints, ConstraintOperator, ConstraintValue, ConstraintPrimitive, } from "./types/identity.js";
7
+ export { generateKeyPair, exportPublicKeyJwk, exportPrivateKeyJwk, importPublicKeyJwk, computeJwkThumbprint, signJwt, verifyJwtSignature, decodeJwtUnsafe, } from "./crypto/ed25519.js";
8
+ export { generateId, generateAgentId, base64UrlEncode, base64UrlDecode } from "./crypto/utils.js";
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AACzD,YAAY,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAC/E,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChE,YAAY,EACR,eAAe,EACf,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,eAAe,EACf,mBAAmB,GACtB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACH,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,OAAO,EACP,kBAAkB,EAClB,eAAe,GAClB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export { AgentsChain } from "./chain.js";
2
+ export { ChainAuthError } from "./errors/chain-error.js";
3
+ export { generateKeyPair, exportPublicKeyJwk, exportPrivateKeyJwk, importPublicKeyJwk, computeJwkThumbprint, signJwt, verifyJwtSignature, decodeJwtUnsafe, } from "./crypto/ed25519.js";
4
+ export { generateId, generateAgentId, base64UrlEncode, base64UrlDecode } from "./crypto/utils.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAazD,OAAO,EACH,eAAe,EACf,kBAAkB,EAClB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,OAAO,EACP,kBAAkB,EAClB,eAAe,GAClB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,6 @@
1
+ export declare function base64UrlEncode(buffer: Buffer | Uint8Array): string;
2
+ export declare function base64UrlDecode(str: string): Buffer;
3
+ export declare function generateId(prefix: string): string;
4
+ export declare function isObject(value: unknown): value is Record<string, unknown>;
5
+ export declare function parseJson<T>(value: string): T;
6
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAEA,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAMnE;AAGD,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAInD;AAID,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIjD;AAID,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAGD,wBAAgB,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,CAAC,CAE7C"}
@@ -0,0 +1,25 @@
1
+ import { randomBytes } from "node:crypto";
2
+ export function base64UrlEncode(buffer) {
3
+ return Buffer.from(buffer)
4
+ .toString("base64")
5
+ .replace(/\+/g, "-")
6
+ .replace(/\//g, "_")
7
+ .replace(/=/g, "");
8
+ }
9
+ export function base64UrlDecode(str) {
10
+ // Pad to multiple of 4
11
+ const padded = str + "=".repeat((4 - (str.length % 4)) % 4);
12
+ return Buffer.from(padded.replace(/-/g, "+").replace(/_/g, "/"), "base64");
13
+ }
14
+ export function generateId(prefix) {
15
+ // 128-bit random, base64url encoded (~22 chars). Collision risk is negligible.
16
+ const suffix = base64UrlEncode(randomBytes(16));
17
+ return `${prefix}_${suffix}`;
18
+ }
19
+ export function isObject(value) {
20
+ return typeof value === "object" && value !== null;
21
+ }
22
+ export function parseJson(value) {
23
+ return JSON.parse(value);
24
+ }
25
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,MAAM,UAAU,eAAe,CAAC,MAA2B;IACvD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;SACrB,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC;AAGD,MAAM,UAAU,eAAe,CAAC,GAAW;IACvC,uBAAuB;IACvB,MAAM,MAAM,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5D,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC/E,CAAC;AAID,MAAM,UAAU,UAAU,CAAC,MAAc;IACrC,+EAA+E;IAC/E,MAAM,MAAM,GAAG,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC;IAChD,OAAO,GAAG,MAAM,IAAI,MAAM,EAAE,CAAC;AACjC,CAAC;AAID,MAAM,UAAU,QAAQ,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACvD,CAAC;AAGD,MAAM,UAAU,SAAS,CAAI,KAAa;IACtC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;AAClC,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * EncryptedStore — AES-256-GCM in-memory key-value store.
3
+ *
4
+ * Security properties:
5
+ * - Every value is independently encrypted with a fresh random IV.
6
+ * - The encryption key never leaves this module after init.
7
+ * - Plaintext is never held in a variable after encryption/before decryption.
8
+ * - Store is process-local; there is no persistence to disk.
9
+ *
10
+ * Format: "iv:authTag:ciphertext" (all base64, colon-separated)
11
+ */
12
+ export declare class EncryptedStore {
13
+ private readonly key;
14
+ private readonly store;
15
+ private constructor();
16
+ /**
17
+ * Create a new EncryptedStore.
18
+ * @param hexKey Optional 64-char hex string (32 bytes). Generated randomly if omitted.
19
+ */
20
+ static create(hexKey?: string): EncryptedStore;
21
+ set(key: string, value: unknown): void;
22
+ get<T>(key: string): T | undefined;
23
+ append<T>(key: string, item: T): void;
24
+ has(key: string): boolean;
25
+ delete(key: string): void;
26
+ get size(): number;
27
+ clear(): void;
28
+ }
29
+ //# sourceMappingURL=encrypted-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encrypted-store.d.ts","sourceRoot":"","sources":["../../src/memory/encrypted-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,qBAAa,cAAc;IACvB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IAEnD,OAAO;IAIP;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,cAAc;IAa9C,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI;IAoBtC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAmClC,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI;IAMrC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIzB,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,KAAK,IAAI,IAAI;CAGhB"}
@@ -0,0 +1,102 @@
1
+ /**
2
+ * EncryptedStore — AES-256-GCM in-memory key-value store.
3
+ *
4
+ * Security properties:
5
+ * - Every value is independently encrypted with a fresh random IV.
6
+ * - The encryption key never leaves this module after init.
7
+ * - Plaintext is never held in a variable after encryption/before decryption.
8
+ * - Store is process-local; there is no persistence to disk.
9
+ *
10
+ * Format: "iv:authTag:ciphertext" (all base64, colon-separated)
11
+ */
12
+ import { randomBytes, createCipheriv, createDecipheriv } from "node:crypto";
13
+ const ALGORITHM = "aes-256-gcm";
14
+ const IV_BYTES = 12; // 96-bit IV — GCM recommended
15
+ const TAG_BYTES = 16; // 128-bit auth tag — maximum GCM strength
16
+ export class EncryptedStore {
17
+ constructor(key) {
18
+ this.store = new Map();
19
+ this.key = key;
20
+ }
21
+ /**
22
+ * Create a new EncryptedStore.
23
+ * @param hexKey Optional 64-char hex string (32 bytes). Generated randomly if omitted.
24
+ */
25
+ static create(hexKey) {
26
+ let key;
27
+ if (hexKey) {
28
+ if (!/^[0-9a-fA-F]{64}$/.test(hexKey)) {
29
+ throw new Error("encryptionKey must be a 64-character hex string (32 bytes)");
30
+ }
31
+ key = Buffer.from(hexKey, "hex");
32
+ }
33
+ else {
34
+ key = randomBytes(32);
35
+ }
36
+ return new EncryptedStore(key);
37
+ }
38
+ set(key, value) {
39
+ const plaintext = JSON.stringify(value);
40
+ const iv = randomBytes(IV_BYTES);
41
+ const cipher = createCipheriv(ALGORITHM, this.key, iv);
42
+ const encrypted = Buffer.concat([
43
+ cipher.update(plaintext, "utf8"),
44
+ cipher.final(),
45
+ ]);
46
+ const tag = cipher.getAuthTag();
47
+ // Format: base64(iv):base64(tag):base64(ciphertext)
48
+ const encoded = [
49
+ iv.toString("base64"),
50
+ tag.toString("base64"),
51
+ encrypted.toString("base64"),
52
+ ].join(":");
53
+ this.store.set(key, encoded);
54
+ }
55
+ get(key) {
56
+ const encoded = this.store.get(key);
57
+ if (!encoded)
58
+ return undefined;
59
+ const parts = encoded.split(":");
60
+ if (parts.length !== 3) {
61
+ throw new Error(`EncryptedStore: corrupted entry at key "${key}"`);
62
+ }
63
+ const iv = Buffer.from(parts[0], "base64");
64
+ const tag = Buffer.from(parts[1], "base64");
65
+ const ciphertext = Buffer.from(parts[2], "base64");
66
+ if (iv.length !== IV_BYTES) {
67
+ throw new Error(`EncryptedStore: invalid IV length for key "${key}"`);
68
+ }
69
+ if (tag.length !== TAG_BYTES) {
70
+ throw new Error(`EncryptedStore: invalid auth tag length for key "${key}"`);
71
+ }
72
+ const decipher = createDecipheriv(ALGORITHM, this.key, iv);
73
+ decipher.setAuthTag(tag);
74
+ let plaintext;
75
+ try {
76
+ plaintext = decipher.update(ciphertext, undefined, "utf8") + decipher.final("utf8");
77
+ }
78
+ catch {
79
+ // GCM auth tag mismatch — data has been tampered with
80
+ throw new Error(`EncryptedStore: authentication failed for key "${key}" — possible tampering`);
81
+ }
82
+ return JSON.parse(plaintext);
83
+ }
84
+ append(key, item) {
85
+ const existing = this.get(key) ?? [];
86
+ existing.push(item);
87
+ this.set(key, existing);
88
+ }
89
+ has(key) {
90
+ return this.store.has(key);
91
+ }
92
+ delete(key) {
93
+ this.store.delete(key);
94
+ }
95
+ get size() {
96
+ return this.store.size;
97
+ }
98
+ clear() {
99
+ this.store.clear();
100
+ }
101
+ }
102
+ //# sourceMappingURL=encrypted-store.js.map