@de-otio/chaoskb-client 0.3.4 → 0.3.7

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 (134) hide show
  1. package/dist/cli/bootstrap.d.ts +11 -3
  2. package/dist/cli/bootstrap.d.ts.map +1 -1
  3. package/dist/cli/bootstrap.js +181 -126
  4. package/dist/cli/bootstrap.js.map +1 -1
  5. package/dist/cli/commands/config.d.ts +7 -4
  6. package/dist/cli/commands/config.d.ts.map +1 -1
  7. package/dist/cli/commands/config.js +161 -134
  8. package/dist/cli/commands/config.js.map +1 -1
  9. package/dist/cli/commands/devices.d.ts.map +1 -1
  10. package/dist/cli/commands/devices.js +58 -33
  11. package/dist/cli/commands/devices.js.map +1 -1
  12. package/dist/cli/commands/export.d.ts.map +1 -1
  13. package/dist/cli/commands/export.js +6 -9
  14. package/dist/cli/commands/export.js.map +1 -1
  15. package/dist/cli/commands/import.js +1 -1
  16. package/dist/cli/commands/import.js.map +1 -1
  17. package/dist/cli/commands/projects.d.ts.map +1 -1
  18. package/dist/cli/commands/projects.js +33 -10
  19. package/dist/cli/commands/projects.js.map +1 -1
  20. package/dist/cli/commands/rotate-key.d.ts +3 -3
  21. package/dist/cli/commands/rotate-key.d.ts.map +1 -1
  22. package/dist/cli/commands/rotate-key.js +88 -35
  23. package/dist/cli/commands/rotate-key.js.map +1 -1
  24. package/dist/cli/commands/setup-sync.d.ts.map +1 -1
  25. package/dist/cli/commands/setup-sync.js +22 -4
  26. package/dist/cli/commands/setup-sync.js.map +1 -1
  27. package/dist/cli/mcp-server.d.ts.map +1 -1
  28. package/dist/cli/mcp-server.js +90 -42
  29. package/dist/cli/mcp-server.js.map +1 -1
  30. package/dist/crypto/aad.d.ts +2 -5
  31. package/dist/crypto/aad.d.ts.map +1 -1
  32. package/dist/crypto/aad.js +2 -8
  33. package/dist/crypto/aad.js.map +1 -1
  34. package/dist/crypto/aead.d.ts +8 -16
  35. package/dist/crypto/aead.d.ts.map +1 -1
  36. package/dist/crypto/aead.js +10 -36
  37. package/dist/crypto/aead.js.map +1 -1
  38. package/dist/crypto/blob-id.d.ts +2 -3
  39. package/dist/crypto/blob-id.d.ts.map +1 -1
  40. package/dist/crypto/blob-id.js +2 -30
  41. package/dist/crypto/blob-id.js.map +1 -1
  42. package/dist/crypto/canonical-json.d.ts +5 -3
  43. package/dist/crypto/canonical-json.d.ts.map +1 -1
  44. package/dist/crypto/canonical-json.js +5 -85
  45. package/dist/crypto/canonical-json.js.map +1 -1
  46. package/dist/crypto/commitment.d.ts +3 -9
  47. package/dist/crypto/commitment.d.ts.map +1 -1
  48. package/dist/crypto/commitment.js +3 -27
  49. package/dist/crypto/commitment.js.map +1 -1
  50. package/dist/crypto/encryption-service.d.ts +3 -0
  51. package/dist/crypto/encryption-service.d.ts.map +1 -1
  52. package/dist/crypto/encryption-service.js +10 -6
  53. package/dist/crypto/encryption-service.js.map +1 -1
  54. package/dist/crypto/envelope-cbor.d.ts +4 -34
  55. package/dist/crypto/envelope-cbor.d.ts.map +1 -1
  56. package/dist/crypto/envelope-cbor.js +4 -121
  57. package/dist/crypto/envelope-cbor.js.map +1 -1
  58. package/dist/crypto/envelope.d.ts +1 -31
  59. package/dist/crypto/envelope.d.ts.map +1 -1
  60. package/dist/crypto/envelope.js +31 -137
  61. package/dist/crypto/envelope.js.map +1 -1
  62. package/dist/crypto/hkdf.d.ts +7 -11
  63. package/dist/crypto/hkdf.d.ts.map +1 -1
  64. package/dist/crypto/hkdf.js +9 -18
  65. package/dist/crypto/hkdf.js.map +1 -1
  66. package/dist/crypto/index.d.ts +9 -4
  67. package/dist/crypto/index.d.ts.map +1 -1
  68. package/dist/crypto/index.js +9 -4
  69. package/dist/crypto/index.js.map +1 -1
  70. package/dist/crypto/ssh-keys.d.ts +17 -10
  71. package/dist/crypto/ssh-keys.d.ts.map +1 -1
  72. package/dist/crypto/ssh-keys.js +28 -108
  73. package/dist/crypto/ssh-keys.js.map +1 -1
  74. package/dist/crypto/types.d.ts +18 -88
  75. package/dist/crypto/types.d.ts.map +1 -1
  76. package/dist/crypto/types.js +3 -0
  77. package/dist/crypto/types.js.map +1 -1
  78. package/dist/pipeline/content-pipeline.d.ts.map +1 -1
  79. package/dist/pipeline/content-pipeline.js +26 -3
  80. package/dist/pipeline/content-pipeline.js.map +1 -1
  81. package/dist/pipeline/extract.d.ts +8 -0
  82. package/dist/pipeline/extract.d.ts.map +1 -1
  83. package/dist/pipeline/extract.js +15 -4
  84. package/dist/pipeline/extract.js.map +1 -1
  85. package/dist/pipeline/fetch-browser.d.ts +29 -0
  86. package/dist/pipeline/fetch-browser.d.ts.map +1 -0
  87. package/dist/pipeline/fetch-browser.js +98 -0
  88. package/dist/pipeline/fetch-browser.js.map +1 -0
  89. package/dist/pipeline/safety.d.ts +12 -0
  90. package/dist/pipeline/safety.d.ts.map +1 -0
  91. package/dist/pipeline/safety.js +24 -0
  92. package/dist/pipeline/safety.js.map +1 -0
  93. package/dist/pipeline/types.d.ts +2 -0
  94. package/dist/pipeline/types.d.ts.map +1 -1
  95. package/dist/pipeline/validate.d.ts.map +1 -1
  96. package/dist/pipeline/validate.js +19 -46
  97. package/dist/pipeline/validate.js.map +1 -1
  98. package/package.json +5 -1
  99. package/dist/crypto/argon2.d.ts +0 -11
  100. package/dist/crypto/argon2.d.ts.map +0 -1
  101. package/dist/crypto/argon2.js +0 -33
  102. package/dist/crypto/argon2.js.map +0 -1
  103. package/dist/crypto/invite.d.ts +0 -31
  104. package/dist/crypto/invite.d.ts.map +0 -1
  105. package/dist/crypto/invite.js +0 -139
  106. package/dist/crypto/invite.js.map +0 -1
  107. package/dist/crypto/keyring.d.ts +0 -37
  108. package/dist/crypto/keyring.d.ts.map +0 -1
  109. package/dist/crypto/keyring.js +0 -219
  110. package/dist/crypto/keyring.js.map +0 -1
  111. package/dist/crypto/known-keys.d.ts +0 -34
  112. package/dist/crypto/known-keys.d.ts.map +0 -1
  113. package/dist/crypto/known-keys.js +0 -114
  114. package/dist/crypto/known-keys.js.map +0 -1
  115. package/dist/crypto/project-keys.d.ts +0 -26
  116. package/dist/crypto/project-keys.d.ts.map +0 -1
  117. package/dist/crypto/project-keys.js +0 -69
  118. package/dist/crypto/project-keys.js.map +0 -1
  119. package/dist/crypto/secure-buffer.d.ts +0 -31
  120. package/dist/crypto/secure-buffer.d.ts.map +0 -1
  121. package/dist/crypto/secure-buffer.js +0 -61
  122. package/dist/crypto/secure-buffer.js.map +0 -1
  123. package/dist/crypto/tiers/enhanced.d.ts +0 -25
  124. package/dist/crypto/tiers/enhanced.d.ts.map +0 -1
  125. package/dist/crypto/tiers/enhanced.js +0 -56
  126. package/dist/crypto/tiers/enhanced.js.map +0 -1
  127. package/dist/crypto/tiers/maximum.d.ts +0 -19
  128. package/dist/crypto/tiers/maximum.d.ts.map +0 -1
  129. package/dist/crypto/tiers/maximum.js +0 -25
  130. package/dist/crypto/tiers/maximum.js.map +0 -1
  131. package/dist/crypto/tiers/standard.d.ts +0 -27
  132. package/dist/crypto/tiers/standard.d.ts.map +0 -1
  133. package/dist/crypto/tiers/standard.js +0 -155
  134. package/dist/crypto/tiers/standard.js.map +0 -1
@@ -1,37 +0,0 @@
1
- import type { IKeyringService, ISecureBuffer } from './types.js';
2
- /**
3
- * OS keyring integration via shell commands.
4
- * Uses execFile (not exec) to prevent shell injection.
5
- *
6
- * macOS: security add-generic-password / find-generic-password / delete-generic-password
7
- * Linux: secret-tool store / lookup / clear
8
- * Windows: cmdkey /add: / /list: / /delete:
9
- */
10
- export declare class KeyringService implements IKeyringService {
11
- private readonly platform;
12
- constructor(platform?: NodeJS.Platform);
13
- /**
14
- * Store a secret in the OS keyring.
15
- */
16
- store(service: string, account: string, secret: ISecureBuffer): Promise<void>;
17
- /**
18
- * Retrieve a secret from the OS keyring.
19
- * Returns null if not found.
20
- */
21
- retrieve(service: string, account: string): Promise<ISecureBuffer | null>;
22
- /**
23
- * Delete a secret from the OS keyring.
24
- * Returns true if deleted, false if not found.
25
- */
26
- delete(service: string, account: string): Promise<boolean>;
27
- private storeMacOS;
28
- private retrieveMacOS;
29
- private deleteMacOS;
30
- private storeLinux;
31
- private retrieveLinux;
32
- private deleteLinux;
33
- private storeWindows;
34
- private retrieveWindows;
35
- private deleteWindows;
36
- }
37
- //# sourceMappingURL=keyring.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"keyring.d.ts","sourceRoot":"","sources":["../../crypto/keyring.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIjE;;;;;;;GAOG;AACH,qBAAa,cAAe,YAAW,eAAe;IACpD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkB;gBAE/B,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ;IAItC;;OAEG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBnF;;;OAGG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAyB/E;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;YAuBlD,UAAU;YAqBV,aAAa;YAUb,WAAW;YAUX,UAAU;YAkBV,aAAa;YASb,WAAW;YAUX,YAAY;YAWZ,eAAe;YA4Cf,aAAa;CAI5B"}
@@ -1,219 +0,0 @@
1
- import { execFile } from 'node:child_process';
2
- import { promisify } from 'node:util';
3
- import { SecureBuffer } from './secure-buffer.js';
4
- const execFileAsync = promisify(execFile);
5
- /**
6
- * OS keyring integration via shell commands.
7
- * Uses execFile (not exec) to prevent shell injection.
8
- *
9
- * macOS: security add-generic-password / find-generic-password / delete-generic-password
10
- * Linux: secret-tool store / lookup / clear
11
- * Windows: cmdkey /add: / /list: / /delete:
12
- */
13
- export class KeyringService {
14
- platform;
15
- constructor(platform) {
16
- this.platform = platform ?? process.platform;
17
- }
18
- /**
19
- * Store a secret in the OS keyring.
20
- */
21
- async store(service, account, secret) {
22
- const secretHex = secret.buffer.toString('hex');
23
- try {
24
- switch (this.platform) {
25
- case 'darwin':
26
- await this.storeMacOS(service, account, secretHex);
27
- break;
28
- case 'linux':
29
- await this.storeLinux(service, account, secretHex);
30
- break;
31
- case 'win32':
32
- await this.storeWindows(service, account, secretHex);
33
- break;
34
- default:
35
- throw new Error(`Unsupported platform: ${this.platform}`);
36
- }
37
- }
38
- finally {
39
- // We can't zero the hex string (JS strings are immutable),
40
- // but we at least don't hold onto it.
41
- }
42
- }
43
- /**
44
- * Retrieve a secret from the OS keyring.
45
- * Returns null if not found.
46
- */
47
- async retrieve(service, account) {
48
- try {
49
- let secretHex;
50
- switch (this.platform) {
51
- case 'darwin':
52
- secretHex = await this.retrieveMacOS(service, account);
53
- break;
54
- case 'linux':
55
- secretHex = await this.retrieveLinux(service, account);
56
- break;
57
- case 'win32':
58
- secretHex = await this.retrieveWindows(service, account);
59
- break;
60
- default:
61
- throw new Error(`Unsupported platform: ${this.platform}`);
62
- }
63
- const bytes = Buffer.from(secretHex.trim(), 'hex');
64
- return SecureBuffer.from(bytes);
65
- }
66
- catch {
67
- return null;
68
- }
69
- }
70
- /**
71
- * Delete a secret from the OS keyring.
72
- * Returns true if deleted, false if not found.
73
- */
74
- async delete(service, account) {
75
- try {
76
- switch (this.platform) {
77
- case 'darwin':
78
- await this.deleteMacOS(service, account);
79
- break;
80
- case 'linux':
81
- await this.deleteLinux(service, account);
82
- break;
83
- case 'win32':
84
- await this.deleteWindows(service, account);
85
- break;
86
- default:
87
- throw new Error(`Unsupported platform: ${this.platform}`);
88
- }
89
- return true;
90
- }
91
- catch {
92
- return false;
93
- }
94
- }
95
- // --- macOS ---
96
- async storeMacOS(service, account, secret) {
97
- // Delete existing entry first (update = delete + add)
98
- try {
99
- await execFileAsync('security', [
100
- 'delete-generic-password',
101
- '-s', service,
102
- '-a', account,
103
- ]);
104
- }
105
- catch {
106
- // Ignore if not found
107
- }
108
- await execFileAsync('security', [
109
- 'add-generic-password',
110
- '-s', service,
111
- '-a', account,
112
- '-w', secret,
113
- '-U', // update if exists
114
- ]);
115
- }
116
- async retrieveMacOS(service, account) {
117
- const { stdout } = await execFileAsync('security', [
118
- 'find-generic-password',
119
- '-s', service,
120
- '-a', account,
121
- '-w', // output password only
122
- ]);
123
- return stdout.trim();
124
- }
125
- async deleteMacOS(service, account) {
126
- await execFileAsync('security', [
127
- 'delete-generic-password',
128
- '-s', service,
129
- '-a', account,
130
- ]);
131
- }
132
- // --- Linux ---
133
- async storeLinux(service, account, secret) {
134
- // secret-tool reads from stdin
135
- const child = execFileAsync('secret-tool', [
136
- 'store',
137
- '--label', `${service}/${account}`,
138
- 'service', service,
139
- 'account', account,
140
- ]);
141
- // Write secret to stdin
142
- if (child.child.stdin) {
143
- child.child.stdin.write(secret);
144
- child.child.stdin.end();
145
- }
146
- await child;
147
- }
148
- async retrieveLinux(service, account) {
149
- const { stdout } = await execFileAsync('secret-tool', [
150
- 'lookup',
151
- 'service', service,
152
- 'account', account,
153
- ]);
154
- return stdout;
155
- }
156
- async deleteLinux(service, account) {
157
- await execFileAsync('secret-tool', [
158
- 'clear',
159
- 'service', service,
160
- 'account', account,
161
- ]);
162
- }
163
- // --- Windows ---
164
- async storeWindows(service, account, secret) {
165
- const target = `${service}/${account}`;
166
- // Use PowerShell with .NET CredentialManager API (no external modules required)
167
- const script = `
168
- Add-Type -AssemblyName System.Runtime.InteropServices
169
- $cred = New-Object System.Management.Automation.PSCredential('${account.replace(/'/g, "''")}', (ConvertTo-SecureString '${secret.replace(/'/g, "''")}' -AsPlainText -Force))
170
- cmdkey /add:${target} /user:${account} /pass:${secret}
171
- `.trim();
172
- await execFileAsync('powershell', ['-NoProfile', '-Command', script]);
173
- }
174
- async retrieveWindows(service, account) {
175
- const target = `${service}/${account}`;
176
- // Use PowerShell with native .NET Credential API (no external modules needed)
177
- const script = `
178
- Add-Type @"
179
- using System;
180
- using System.Runtime.InteropServices;
181
- public class CredentialHelper {
182
- [DllImport("advapi32.dll", CharSet=CharSet.Unicode, SetLastError=true)]
183
- public static extern bool CredReadW(string target, int type, int flags, out IntPtr credential);
184
- [DllImport("advapi32.dll")]
185
- public static extern void CredFree(IntPtr credential);
186
- [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
187
- public struct CREDENTIAL {
188
- public int Flags; public int Type;
189
- public string TargetName; public string Comment;
190
- public long LastWritten; public int CredentialBlobSize;
191
- public IntPtr CredentialBlob; public int Persist;
192
- public int AttributeCount; public IntPtr Attributes;
193
- public string TargetAlias; public string UserName;
194
- }
195
- public static string Read(string target) {
196
- IntPtr ptr;
197
- if (!CredReadW(target, 1, 0, out ptr)) return "";
198
- var cred = (CREDENTIAL)Marshal.PtrToStructure(ptr, typeof(CREDENTIAL));
199
- var secret = Marshal.PtrToStringUni(cred.CredentialBlob, cred.CredentialBlobSize / 2);
200
- CredFree(ptr);
201
- return secret;
202
- }
203
- }
204
- "@
205
- [CredentialHelper]::Read('${target.replace(/'/g, "''")}')
206
- `.trim();
207
- const { stdout } = await execFileAsync('powershell', ['-NoProfile', '-Command', script]);
208
- const result = stdout.trim();
209
- if (!result) {
210
- throw new Error(`Credential not found: ${target}`);
211
- }
212
- return result;
213
- }
214
- async deleteWindows(service, account) {
215
- const target = `${service}/${account}`;
216
- await execFileAsync('cmdkey', ['/delete:' + target]);
217
- }
218
- }
219
- //# sourceMappingURL=keyring.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"keyring.js","sourceRoot":"","sources":["../../crypto/keyring.ts"],"names":[],"mappings":"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"}
@@ -1,34 +0,0 @@
1
- interface PinnedKey {
2
- fingerprint: string;
3
- publicKey: string;
4
- source: string;
5
- firstSeen: string;
6
- verifiedAt: string;
7
- }
8
- /**
9
- * Pin a key for an identifier (e.g., "github:alice").
10
- * Throws if the identifier is already pinned with a different fingerprint.
11
- */
12
- export declare function pinKey(identifier: string, fingerprint: string, publicKey: string, source: string): void;
13
- /**
14
- * Get a pinned key by identifier.
15
- */
16
- export declare function getPinnedKey(identifier: string): PinnedKey | null;
17
- /**
18
- * Check a key against the pin store.
19
- */
20
- export declare function checkKeyPin(identifier: string, fingerprint: string): 'match' | 'mismatch' | 'new';
21
- /**
22
- * Update a pinned key after verified rotation (e.g., new key confirmed on GitHub).
23
- */
24
- export declare function updatePinnedKey(identifier: string, fingerprint: string, publicKey: string, source: string): void;
25
- export declare class KeyMismatchError extends Error {
26
- readonly identifier: string;
27
- readonly pinnedFingerprint: string;
28
- readonly newFingerprint: string;
29
- readonly pinnedSource: string;
30
- readonly newSource: string;
31
- constructor(identifier: string, pinnedFingerprint: string, newFingerprint: string, pinnedSource: string, newSource: string);
32
- }
33
- export {};
34
- //# sourceMappingURL=known-keys.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"known-keys.d.ts","sourceRoot":"","sources":["../../crypto/known-keys.ts"],"names":[],"mappings":"AASA,UAAU,SAAS;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAkCD;;;GAGG;AACH,wBAAgB,MAAM,CACpB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,IAAI,CA8BN;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAGjE;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,GAClB,OAAO,GAAG,UAAU,GAAG,KAAK,CAO9B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,IAAI,CAUN;AAED,qBAAa,gBAAiB,SAAQ,KAAK;aAEvB,UAAU,EAAE,MAAM;aAClB,iBAAiB,EAAE,MAAM;aACzB,cAAc,EAAE,MAAM;aACtB,YAAY,EAAE,MAAM;aACpB,SAAS,EAAE,MAAM;gBAJjB,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,MAAM,EACzB,cAAc,EAAE,MAAM,EACtB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM;CAUpC"}
@@ -1,114 +0,0 @@
1
- import * as crypto from 'node:crypto';
2
- import * as fs from 'node:fs';
3
- import * as path from 'node:path';
4
- import * as os from 'node:os';
5
- function getKnownKeysPath() {
6
- return path.join(os.homedir(), '.chaoskb', 'known_keys.json');
7
- }
8
- function fingerprintsEqual(a, b) {
9
- const aBuf = Buffer.from(a);
10
- const bBuf = Buffer.from(b);
11
- if (aBuf.length !== bBuf.length)
12
- return false;
13
- return crypto.timingSafeEqual(aBuf, bBuf);
14
- }
15
- /**
16
- * Trust on First Use (TOFU) key pinning for invite recipients.
17
- *
18
- * When we first see a recipient's public key (from GitHub, GitLab, or direct),
19
- * we pin it. On subsequent invites, we check if the key has changed.
20
- * A key mismatch triggers a warning; a conflict with an independent source
21
- * is a hard block.
22
- */
23
- function loadStore() {
24
- try {
25
- return JSON.parse(fs.readFileSync(getKnownKeysPath(), 'utf-8'));
26
- }
27
- catch {
28
- return {};
29
- }
30
- }
31
- function saveStore(store) {
32
- const dir = path.dirname(getKnownKeysPath());
33
- fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
34
- fs.writeFileSync(getKnownKeysPath(), JSON.stringify(store, null, 2), { mode: 0o600 });
35
- }
36
- /**
37
- * Pin a key for an identifier (e.g., "github:alice").
38
- * Throws if the identifier is already pinned with a different fingerprint.
39
- */
40
- export function pinKey(identifier, fingerprint, publicKey, source) {
41
- const store = loadStore();
42
- const existing = store[identifier];
43
- if (existing && !fingerprintsEqual(existing.fingerprint, fingerprint)) {
44
- throw new KeyMismatchError(identifier, existing.fingerprint, fingerprint, existing.source, source);
45
- }
46
- if (existing && fingerprintsEqual(existing.fingerprint, fingerprint)) {
47
- // Same key — update verifiedAt
48
- existing.verifiedAt = new Date().toISOString();
49
- saveStore(store);
50
- return;
51
- }
52
- // New key — pin it
53
- store[identifier] = {
54
- fingerprint,
55
- publicKey,
56
- source,
57
- firstSeen: new Date().toISOString(),
58
- verifiedAt: new Date().toISOString(),
59
- };
60
- saveStore(store);
61
- }
62
- /**
63
- * Get a pinned key by identifier.
64
- */
65
- export function getPinnedKey(identifier) {
66
- const store = loadStore();
67
- return store[identifier] ?? null;
68
- }
69
- /**
70
- * Check a key against the pin store.
71
- */
72
- export function checkKeyPin(identifier, fingerprint) {
73
- const store = loadStore();
74
- const existing = store[identifier];
75
- if (!existing)
76
- return 'new';
77
- if (fingerprintsEqual(existing.fingerprint, fingerprint))
78
- return 'match';
79
- return 'mismatch';
80
- }
81
- /**
82
- * Update a pinned key after verified rotation (e.g., new key confirmed on GitHub).
83
- */
84
- export function updatePinnedKey(identifier, fingerprint, publicKey, source) {
85
- const store = loadStore();
86
- store[identifier] = {
87
- fingerprint,
88
- publicKey,
89
- source,
90
- firstSeen: store[identifier]?.firstSeen ?? new Date().toISOString(),
91
- verifiedAt: new Date().toISOString(),
92
- };
93
- saveStore(store);
94
- }
95
- export class KeyMismatchError extends Error {
96
- identifier;
97
- pinnedFingerprint;
98
- newFingerprint;
99
- pinnedSource;
100
- newSource;
101
- constructor(identifier, pinnedFingerprint, newFingerprint, pinnedSource, newSource) {
102
- super(`Key mismatch for ${identifier}:\n` +
103
- ` Pinned: ${pinnedFingerprint} (source: ${pinnedSource})\n` +
104
- ` Received: ${newFingerprint} (source: ${newSource})\n` +
105
- `This may indicate a compromised key source. The operation was blocked.`);
106
- this.identifier = identifier;
107
- this.pinnedFingerprint = pinnedFingerprint;
108
- this.newFingerprint = newFingerprint;
109
- this.pinnedSource = pinnedSource;
110
- this.newSource = newSource;
111
- this.name = 'KeyMismatchError';
112
- }
113
- }
114
- //# sourceMappingURL=known-keys.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"known-keys.js","sourceRoot":"","sources":["../../crypto/known-keys.ts"],"names":[],"mappings":"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"}
@@ -1,26 +0,0 @@
1
- import type { ISecureBuffer } from './types.js';
2
- /**
3
- * Create a new random project key and wrap it with the personal master key.
4
- *
5
- * Uses HKDF to derive a wrapping key from the master key, then encrypts
6
- * the project key with XChaCha20-Poly1305. AAD can include a project name
7
- * for binding.
8
- *
9
- * @param personalMasterKey - The user's personal master key
10
- * @param projectName - Optional project name for AAD binding
11
- * @returns The project key (SecureBuffer) and the wrapped (encrypted) form
12
- */
13
- export declare function createProjectKey(personalMasterKey: ISecureBuffer, projectName?: string): {
14
- projectKey: ISecureBuffer;
15
- wrappedKey: Uint8Array;
16
- };
17
- /**
18
- * Unwrap a project key using the personal master key.
19
- *
20
- * @param wrappedKey - The wrapped project key (nonce || ciphertext || tag)
21
- * @param personalMasterKey - The user's personal master key
22
- * @param projectName - Optional project name for AAD binding (must match what was used during wrapping)
23
- * @returns The unwrapped project key as a SecureBuffer
24
- */
25
- export declare function unwrapProjectKey(wrappedKey: Uint8Array, personalMasterKey: ISecureBuffer, projectName?: string): ISecureBuffer;
26
- //# sourceMappingURL=project-keys.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"project-keys.d.ts","sourceRoot":"","sources":["../../crypto/project-keys.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAKhD;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,iBAAiB,EAAE,aAAa,EAChC,WAAW,CAAC,EAAE,MAAM,GACnB;IAAE,UAAU,EAAE,aAAa,CAAC;IAAC,UAAU,EAAE,UAAU,CAAA;CAAE,CA8BvD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,UAAU,EACtB,iBAAiB,EAAE,aAAa,EAChC,WAAW,CAAC,EAAE,MAAM,GACnB,aAAa,CA+Bf"}
@@ -1,69 +0,0 @@
1
- import { randomBytes } from 'node:crypto';
2
- import { aeadEncrypt, aeadDecrypt } from './aead.js';
3
- import { deriveKey } from './hkdf.js';
4
- import { SecureBuffer } from './secure-buffer.js';
5
- const PROJECT_KEY_LENGTH = 32;
6
- const WRAP_INFO = 'chaoskb-project-wrap';
7
- /**
8
- * Create a new random project key and wrap it with the personal master key.
9
- *
10
- * Uses HKDF to derive a wrapping key from the master key, then encrypts
11
- * the project key with XChaCha20-Poly1305. AAD can include a project name
12
- * for binding.
13
- *
14
- * @param personalMasterKey - The user's personal master key
15
- * @param projectName - Optional project name for AAD binding
16
- * @returns The project key (SecureBuffer) and the wrapped (encrypted) form
17
- */
18
- export function createProjectKey(personalMasterKey, projectName) {
19
- // Generate random 32-byte project key
20
- const projectKeyBytes = randomBytes(PROJECT_KEY_LENGTH);
21
- // Derive a wrapping key via HKDF
22
- const wrappingKey = deriveKey(new Uint8Array(personalMasterKey.buffer), WRAP_INFO);
23
- // AAD: project name if available, otherwise empty
24
- const aad = projectName
25
- ? new TextEncoder().encode(projectName)
26
- : new Uint8Array(0);
27
- // Encrypt project key with XChaCha20-Poly1305
28
- const { nonce, ciphertext, tag } = aeadEncrypt(wrappingKey, projectKeyBytes, aad);
29
- // Zero wrapping key and plaintext project key bytes
30
- wrappingKey.fill(0);
31
- // Serialize: nonce(24) || ciphertext || tag(16)
32
- const wrappedKey = new Uint8Array(nonce.length + ciphertext.length + tag.length);
33
- wrappedKey.set(nonce, 0);
34
- wrappedKey.set(ciphertext, nonce.length);
35
- wrappedKey.set(tag, nonce.length + ciphertext.length);
36
- const projectKey = SecureBuffer.from(projectKeyBytes);
37
- return { projectKey, wrappedKey };
38
- }
39
- /**
40
- * Unwrap a project key using the personal master key.
41
- *
42
- * @param wrappedKey - The wrapped project key (nonce || ciphertext || tag)
43
- * @param personalMasterKey - The user's personal master key
44
- * @param projectName - Optional project name for AAD binding (must match what was used during wrapping)
45
- * @returns The unwrapped project key as a SecureBuffer
46
- */
47
- export function unwrapProjectKey(wrappedKey, personalMasterKey, projectName) {
48
- const NONCE_SIZE = 24;
49
- const TAG_SIZE = 16;
50
- if (wrappedKey.length < NONCE_SIZE + TAG_SIZE + 1) {
51
- throw new Error('Wrapped key is too short');
52
- }
53
- // Derive the same wrapping key
54
- const wrappingKey = deriveKey(new Uint8Array(personalMasterKey.buffer), WRAP_INFO);
55
- // Split wrapped key into nonce, ciphertext, tag
56
- const nonce = wrappedKey.slice(0, NONCE_SIZE);
57
- const ciphertext = wrappedKey.slice(NONCE_SIZE, wrappedKey.length - TAG_SIZE);
58
- const tag = wrappedKey.slice(wrappedKey.length - TAG_SIZE);
59
- // AAD: project name if available, otherwise empty
60
- const aad = projectName
61
- ? new TextEncoder().encode(projectName)
62
- : new Uint8Array(0);
63
- // Decrypt
64
- const projectKeyBytes = aeadDecrypt(wrappingKey, nonce, ciphertext, tag, aad);
65
- // Zero wrapping key
66
- wrappingKey.fill(0);
67
- return SecureBuffer.from(Buffer.from(projectKeyBytes));
68
- }
69
- //# sourceMappingURL=project-keys.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"project-keys.js","sourceRoot":"","sources":["../../crypto/project-keys.ts"],"names":[],"mappings":"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"}
@@ -1,31 +0,0 @@
1
- import type { ISecureBuffer } from './types.js';
2
- /**
3
- * Memory-locked buffer for sensitive key material.
4
- * Uses sodium_malloc (mlock'd pages) and sodium_memzero on dispose.
5
- */
6
- export declare class SecureBuffer implements ISecureBuffer {
7
- private _buffer;
8
- private _disposed;
9
- private constructor();
10
- /** Read the buffer contents. Throws if disposed. */
11
- get buffer(): Buffer;
12
- /** Byte length of the buffer. */
13
- get length(): number;
14
- /** Whether the buffer has been zeroed and disposed. */
15
- get isDisposed(): boolean;
16
- /**
17
- * Zero the buffer contents and mark as disposed.
18
- * Safe to call multiple times (idempotent).
19
- */
20
- dispose(): void;
21
- /** Support `using` keyword (TC39 Explicit Resource Management). */
22
- [Symbol.dispose](): void;
23
- /**
24
- * Copy data into a new SecureBuffer and zero the source.
25
- * The source buffer is zeroed after copying regardless of type.
26
- */
27
- static from(data: Buffer | Uint8Array): SecureBuffer;
28
- /** Allocate a new zeroed SecureBuffer of the given length. */
29
- static alloc(length: number): SecureBuffer;
30
- }
31
- //# sourceMappingURL=secure-buffer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"secure-buffer.d.ts","sourceRoot":"","sources":["../../crypto/secure-buffer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;;GAGG;AACH,qBAAa,YAAa,YAAW,aAAa;IAChD,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAS;IAE1B,OAAO;IAIP,oDAAoD;IACpD,IAAI,MAAM,IAAI,MAAM,CAKnB;IAED,iCAAiC;IACjC,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,uDAAuD;IACvD,IAAI,UAAU,IAAI,OAAO,CAExB;IAED;;;OAGG;IACH,OAAO,IAAI,IAAI;IAQf,mEAAmE;IACnE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI;IAIxB;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,YAAY;IASpD,8DAA8D;IAC9D,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY;CAK3C"}
@@ -1,61 +0,0 @@
1
- import sodium from 'sodium-native';
2
- /**
3
- * Memory-locked buffer for sensitive key material.
4
- * Uses sodium_malloc (mlock'd pages) and sodium_memzero on dispose.
5
- */
6
- export class SecureBuffer {
7
- _buffer;
8
- _disposed = false;
9
- constructor(length) {
10
- this._buffer = sodium.sodium_malloc(length);
11
- }
12
- /** Read the buffer contents. Throws if disposed. */
13
- get buffer() {
14
- if (this._disposed) {
15
- throw new Error('SecureBuffer has been disposed');
16
- }
17
- return this._buffer;
18
- }
19
- /** Byte length of the buffer. */
20
- get length() {
21
- return this._buffer.byteLength;
22
- }
23
- /** Whether the buffer has been zeroed and disposed. */
24
- get isDisposed() {
25
- return this._disposed;
26
- }
27
- /**
28
- * Zero the buffer contents and mark as disposed.
29
- * Safe to call multiple times (idempotent).
30
- */
31
- dispose() {
32
- if (this._disposed) {
33
- return;
34
- }
35
- sodium.sodium_memzero(this._buffer);
36
- this._disposed = true;
37
- }
38
- /** Support `using` keyword (TC39 Explicit Resource Management). */
39
- [Symbol.dispose]() {
40
- this.dispose();
41
- }
42
- /**
43
- * Copy data into a new SecureBuffer and zero the source.
44
- * The source buffer is zeroed after copying regardless of type.
45
- */
46
- static from(data) {
47
- const sb = new SecureBuffer(data.byteLength);
48
- const buf = Buffer.isBuffer(data) ? data : Buffer.from(data.buffer, data.byteOffset, data.byteLength);
49
- buf.copy(sb._buffer);
50
- // Zero the source
51
- sodium.sodium_memzero(buf);
52
- return sb;
53
- }
54
- /** Allocate a new zeroed SecureBuffer of the given length. */
55
- static alloc(length) {
56
- const sb = new SecureBuffer(length);
57
- sodium.sodium_memzero(sb._buffer);
58
- return sb;
59
- }
60
- }
61
- //# sourceMappingURL=secure-buffer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"secure-buffer.js","sourceRoot":"","sources":["../../crypto/secure-buffer.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,eAAe,CAAC;AAInC;;;GAGG;AACH,MAAM,OAAO,YAAY;IACf,OAAO,CAAS;IAChB,SAAS,GAAG,KAAK,CAAC;IAE1B,YAAoB,MAAc;QAChC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;IAC9C,CAAC;IAED,oDAAoD;IACpD,IAAI,MAAM;QACR,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,iCAAiC;IACjC,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IACjC,CAAC;IAED,uDAAuD;IACvD,IAAI,UAAU;QACZ,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;OAGG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QACD,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,mEAAmE;IACnE,CAAC,MAAM,CAAC,OAAO,CAAC;QACd,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,MAAM,CAAC,IAAI,CAAC,IAAyB;QACnC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7C,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QACrB,kBAAkB;QAClB,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;QAC3B,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,8DAA8D;IAC9D,MAAM,CAAC,KAAK,CAAC,MAAc;QACzB,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;QACpC,MAAM,CAAC,cAAc,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC;QAClC,OAAO,EAAE,CAAC;IACZ,CAAC;CACF"}