@push.rocks/smartsecret 1.0.2 → 1.2.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.
@@ -0,0 +1,442 @@
1
+ import * as plugins from './smartsecret.plugins.js';
2
+ import { SmartSecretKernelStoreError, createSmartSecretKernelStoreError, } from './smartsecret.kernel.error.js';
3
+ import { deriveSmartSecretKernelEntryDescription, deriveSmartSecretKernelMutexNamespace, deriveSmartSecretKernelServiceDescription, encodeCanonicalBase64Url, normalizeDevIdpV1LegacyAccount, normalizeSmartSecretKernelAccount, normalizeSmartSecretKernelOperationOptions, normalizeSmartSecretKernelStoreOptions, normalizeSmartSecretKernelValue, parseSmartSecretKernelDeleteResult, parseSmartSecretKernelGetResult, parseSmartSecretKernelLegacyDeleteResult, parseSmartSecretKernelLegacyReadResult, parseSmartSecretKernelSetResult, smartSecretKernelDefaultTimeoutMs, smartSecretKernelLegacyService, smartSecretKernelMaximumMessageBytes, } from './smartsecret.kernel.protocol.js';
4
+ const legacyReceiptBrand = Symbol('SmartSecretDevIdpV1LegacyReceipt');
5
+ const kernelStoreConstructionToken = Symbol('SmartSecretKernelStoreConstruction');
6
+ const createDeferred = () => {
7
+ let resolve = () => { };
8
+ let reject = () => { };
9
+ const promise = new Promise((resolveArg, rejectArg) => {
10
+ resolve = resolveArg;
11
+ reject = rejectArg;
12
+ });
13
+ return { promise, resolve, reject };
14
+ };
15
+ const createOperationContext = (optionsArg, mutationArg) => ({
16
+ deadline: performance.now() + optionsArg.timeoutMs,
17
+ ...(optionsArg.signal === undefined ? {} : { signal: optionsArg.signal }),
18
+ mutation: mutationArg,
19
+ dispatched: false,
20
+ });
21
+ const isSupportedRuntime = () => {
22
+ const versionParts = process.versions.node.split('.');
23
+ return (versionParts[0] === '25'
24
+ && process.platform === 'linux'
25
+ && process.arch === 'x64');
26
+ };
27
+ /**
28
+ * Strict Linux kernel-keyring storage for small same-UID process secrets.
29
+ *
30
+ * This class deliberately has no filesystem, Secret Service, or executable
31
+ * discovery fallback. Use create() so the Rust worker is ready before access.
32
+ */
33
+ export class SmartSecretKernelStore {
34
+ constructor(constructionTokenArg, serviceArg, mutexArg, bridgeArg) {
35
+ this.generation = Symbol('SmartSecretKernelStoreGeneration');
36
+ this.receiptRecords = new WeakMap();
37
+ this.lifecycleState = 'ready';
38
+ this.poisoned = false;
39
+ this.operationTail = Promise.resolve();
40
+ if (constructionTokenArg !== kernelStoreConstructionToken) {
41
+ throw createSmartSecretKernelStoreError('INVALID_ARGUMENT');
42
+ }
43
+ this.service = serviceArg;
44
+ this.mutex = mutexArg;
45
+ this.bridge = bridgeArg;
46
+ }
47
+ static async create(optionsArg) {
48
+ const options = normalizeSmartSecretKernelStoreOptions(optionsArg);
49
+ if (!isSupportedRuntime()) {
50
+ throw createSmartSecretKernelStoreError('UNSUPPORTED_RUNTIME');
51
+ }
52
+ const serviceDescription = deriveSmartSecretKernelServiceDescription(options.service);
53
+ let mutex;
54
+ try {
55
+ mutex = new plugins.smartipc.NamedMutex(deriveSmartSecretKernelMutexNamespace(options.service));
56
+ }
57
+ catch {
58
+ throw createSmartSecretKernelStoreError('MUTEX_FAILED');
59
+ }
60
+ const packageRoot = plugins.path.resolve(plugins.path.dirname(plugins.url.fileURLToPath(import.meta.url)), '..');
61
+ const binaryPath = plugins.path.join(packageRoot, 'dist_rust', 'smartsecret-kernel_linux_amd64');
62
+ const bridge = new plugins.smartrust.RustBridge({
63
+ binaryName: 'smartsecret-kernel',
64
+ binaryPath,
65
+ localPaths: [],
66
+ searchSystemPath: false,
67
+ cliArgs: ['--service-ring-description', serviceDescription],
68
+ requestTimeoutMs: smartSecretKernelDefaultTimeoutMs,
69
+ readyTimeoutMs: smartSecretKernelDefaultTimeoutMs,
70
+ maxPayloadSize: smartSecretKernelMaximumMessageBytes,
71
+ });
72
+ let spawned = false;
73
+ try {
74
+ spawned = await bridge.spawn();
75
+ }
76
+ catch {
77
+ spawned = false;
78
+ }
79
+ if (!spawned) {
80
+ let cleanupConfirmed = true;
81
+ try {
82
+ await bridge.terminate({ gracePeriodMs: 0 });
83
+ }
84
+ catch {
85
+ cleanupConfirmed = false;
86
+ }
87
+ throw createSmartSecretKernelStoreError(cleanupConfirmed ? 'WORKER_UNAVAILABLE' : 'WORKER_INTEGRITY_FAILED');
88
+ }
89
+ return new SmartSecretKernelStore(kernelStoreConstructionToken, options.service, mutex, bridge);
90
+ }
91
+ getEntry(accountArg, optionsArg) {
92
+ const account = normalizeSmartSecretKernelAccount(accountArg);
93
+ const options = normalizeSmartSecretKernelOperationOptions(optionsArg);
94
+ const context = createOperationContext(options, false);
95
+ const description = deriveSmartSecretKernelEntryDescription(this.service, account);
96
+ return this.reserveOperation(context, () => this.withKernelLease(context, async () => {
97
+ const parsed = await this.dispatchRead(context, async (requestOptionsArg) => parseSmartSecretKernelGetResult(await this.bridge.sendCommand('getEntry', { description }, requestOptionsArg)));
98
+ if (parsed.kind === 'domainError') {
99
+ return this.throwDomainError(parsed.domainError, context);
100
+ }
101
+ return parsed.found ? parsed.value : null;
102
+ }));
103
+ }
104
+ setEntry(accountArg, valueArg, optionsArg) {
105
+ const account = normalizeSmartSecretKernelAccount(accountArg);
106
+ const options = normalizeSmartSecretKernelOperationOptions(optionsArg);
107
+ const context = createOperationContext(options, true);
108
+ const description = deriveSmartSecretKernelEntryDescription(this.service, account);
109
+ const value = normalizeSmartSecretKernelValue(valueArg);
110
+ let encodedValue;
111
+ try {
112
+ encodedValue = encodeCanonicalBase64Url(value);
113
+ }
114
+ finally {
115
+ value.fill(0);
116
+ }
117
+ return this.reserveOperation(context, () => this.withKernelLease(context, async () => {
118
+ const parsed = await this.dispatchMutation(context, async (requestOptionsArg) => parseSmartSecretKernelSetResult(await this.bridge.sendCommand('setEntry', { description, value: encodedValue }, requestOptionsArg)));
119
+ if (parsed.kind === 'domainError') {
120
+ return this.throwDomainError(parsed.domainError, context);
121
+ }
122
+ }));
123
+ }
124
+ deleteEntry(accountArg, optionsArg) {
125
+ const account = normalizeSmartSecretKernelAccount(accountArg);
126
+ const options = normalizeSmartSecretKernelOperationOptions(optionsArg);
127
+ const context = createOperationContext(options, true);
128
+ const description = deriveSmartSecretKernelEntryDescription(this.service, account);
129
+ return this.reserveOperation(context, () => this.withKernelLease(context, async () => {
130
+ const parsed = await this.dispatchMutation(context, async (requestOptionsArg) => parseSmartSecretKernelDeleteResult(await this.bridge.sendCommand('deleteEntry', { description }, requestOptionsArg)));
131
+ if (parsed.kind === 'domainError') {
132
+ return this.throwDomainError(parsed.domainError, context);
133
+ }
134
+ return parsed.deleted;
135
+ }));
136
+ }
137
+ readDevIdpV1Legacy(accountArg, optionsArg) {
138
+ this.requireLegacyService();
139
+ const account = normalizeDevIdpV1LegacyAccount(accountArg);
140
+ const options = normalizeSmartSecretKernelOperationOptions(optionsArg);
141
+ const context = createOperationContext(options, false);
142
+ return this.reserveOperation(context, () => this.withKernelLease(context, async () => {
143
+ const parsed = await this.dispatchRead(context, async (requestOptionsArg) => parseSmartSecretKernelLegacyReadResult(await this.bridge.sendCommand('readDevIdpV1Legacy', { account }, requestOptionsArg), account));
144
+ if (parsed.kind === 'domainError') {
145
+ return this.throwDomainError(parsed.domainError, context);
146
+ }
147
+ if (!parsed.found)
148
+ return null;
149
+ const receipt = Object.freeze({
150
+ [legacyReceiptBrand]: true,
151
+ });
152
+ this.receiptRecords.set(receipt, {
153
+ generation: this.generation,
154
+ params: Object.freeze(parsed.receiptParams),
155
+ state: 'available',
156
+ });
157
+ return Object.freeze({ value: parsed.value, receipt });
158
+ }));
159
+ }
160
+ deleteDevIdpV1Legacy(receiptArg, optionsArg) {
161
+ this.requireLegacyService();
162
+ const options = normalizeSmartSecretKernelOperationOptions(optionsArg);
163
+ const record = this.requireReceiptRecord(receiptArg);
164
+ if (record.state === 'deleting') {
165
+ if (record.deletionPromise)
166
+ return record.deletionPromise;
167
+ return Promise.reject(createSmartSecretKernelStoreError('RECEIPT_INVALID'));
168
+ }
169
+ if (record.state === 'consumed') {
170
+ return Promise.reject(createSmartSecretKernelStoreError('RECEIPT_INVALID'));
171
+ }
172
+ this.assertCanReserve();
173
+ const context = createOperationContext(options, true);
174
+ record.state = 'deleting';
175
+ const operationPromise = this.reserveOperation(context, () => this.withKernelLease(context, async () => {
176
+ const parsed = await this.dispatchMutation(context, async (requestOptionsArg) => parseSmartSecretKernelLegacyDeleteResult(await this.bridge.sendCommand('deleteDevIdpV1Legacy', record.params, requestOptionsArg)));
177
+ if (parsed.kind === 'domainError') {
178
+ return this.throwDomainError(parsed.domainError, context);
179
+ }
180
+ return parsed.status;
181
+ }));
182
+ const trackedPromise = operationPromise.then((statusArg) => {
183
+ record.state = 'consumed';
184
+ return statusArg;
185
+ }, (errorArg) => {
186
+ const publicError = errorArg instanceof SmartSecretKernelStoreError
187
+ ? errorArg
188
+ : createSmartSecretKernelStoreError('WORKER_INTEGRITY_FAILED');
189
+ if (!context.dispatched
190
+ && (publicError.code === 'OPERATION_ABORTED'
191
+ || publicError.code === 'OPERATION_TIMEOUT')) {
192
+ record.state = 'available';
193
+ record.deletionPromise = undefined;
194
+ }
195
+ else {
196
+ record.state = 'consumed';
197
+ }
198
+ throw publicError;
199
+ });
200
+ record.deletionPromise = trackedPromise;
201
+ return trackedPromise;
202
+ }
203
+ close() {
204
+ if (this.closePromise)
205
+ return this.closePromise;
206
+ this.lifecycleState = 'closing';
207
+ const operationTail = this.operationTail;
208
+ this.closePromise = (async () => {
209
+ await operationTail;
210
+ const terminated = await this.terminateBridgeConfirmed();
211
+ this.lifecycleState = 'closed';
212
+ if (!terminated) {
213
+ this.poisoned = true;
214
+ throw createSmartSecretKernelStoreError('WORKER_INTEGRITY_FAILED');
215
+ }
216
+ })();
217
+ return this.closePromise;
218
+ }
219
+ assertCanReserve() {
220
+ if (this.poisoned) {
221
+ throw createSmartSecretKernelStoreError('STORE_POISONED');
222
+ }
223
+ if (this.lifecycleState !== 'ready') {
224
+ throw createSmartSecretKernelStoreError('STORE_CLOSED');
225
+ }
226
+ }
227
+ reserveOperation(contextArg, operationArg) {
228
+ this.assertCanReserve();
229
+ const predecessor = this.operationTail;
230
+ const tailGate = createDeferred();
231
+ const publicResult = createDeferred();
232
+ this.operationTail = tailGate.promise;
233
+ let queuedFailure;
234
+ let queueTimer;
235
+ let abortListener;
236
+ const failWhileQueued = (codeArg) => {
237
+ if (queuedFailure)
238
+ return;
239
+ queuedFailure = createSmartSecretKernelStoreError(codeArg);
240
+ publicResult.reject(queuedFailure);
241
+ };
242
+ const removeQueueWatchers = () => {
243
+ if (queueTimer) {
244
+ clearTimeout(queueTimer);
245
+ queueTimer = undefined;
246
+ }
247
+ if (abortListener) {
248
+ contextArg.signal?.removeEventListener('abort', abortListener);
249
+ abortListener = undefined;
250
+ }
251
+ };
252
+ if (contextArg.signal?.aborted) {
253
+ failWhileQueued('OPERATION_ABORTED');
254
+ }
255
+ else {
256
+ abortListener = () => failWhileQueued('OPERATION_ABORTED');
257
+ contextArg.signal?.addEventListener('abort', abortListener, { once: true });
258
+ queueTimer = setTimeout(() => failWhileQueued('OPERATION_TIMEOUT'), Math.max(0, contextArg.deadline - performance.now()));
259
+ }
260
+ const execution = predecessor.then(async () => {
261
+ removeQueueWatchers();
262
+ if (queuedFailure) {
263
+ tailGate.resolve();
264
+ return;
265
+ }
266
+ try {
267
+ if (this.poisoned) {
268
+ throw createSmartSecretKernelStoreError('STORE_POISONED');
269
+ }
270
+ publicResult.resolve(await operationArg());
271
+ }
272
+ catch (errorArg) {
273
+ if (errorArg instanceof SmartSecretKernelStoreError) {
274
+ publicResult.reject(errorArg);
275
+ }
276
+ else {
277
+ await this.poisonAndTerminate();
278
+ publicResult.reject(createSmartSecretKernelStoreError(contextArg.mutation && contextArg.dispatched
279
+ ? 'MUTATION_OUTCOME_UNKNOWN'
280
+ : 'WORKER_INTEGRITY_FAILED'));
281
+ }
282
+ }
283
+ finally {
284
+ tailGate.resolve();
285
+ }
286
+ });
287
+ void execution.catch(async () => {
288
+ removeQueueWatchers();
289
+ await this.poisonAndTerminate();
290
+ publicResult.reject(createSmartSecretKernelStoreError(contextArg.mutation && contextArg.dispatched
291
+ ? 'MUTATION_OUTCOME_UNKNOWN'
292
+ : 'WORKER_INTEGRITY_FAILED'));
293
+ tailGate.resolve();
294
+ });
295
+ return publicResult.promise;
296
+ }
297
+ requireLegacyService() {
298
+ if (this.service !== smartSecretKernelLegacyService) {
299
+ throw createSmartSecretKernelStoreError('INVALID_ARGUMENT');
300
+ }
301
+ }
302
+ requireReceiptRecord(receiptArg) {
303
+ if (receiptArg === null || typeof receiptArg !== 'object') {
304
+ throw createSmartSecretKernelStoreError('RECEIPT_INVALID');
305
+ }
306
+ const record = this.receiptRecords.get(receiptArg);
307
+ if (!record || record.generation !== this.generation) {
308
+ throw createSmartSecretKernelStoreError('RECEIPT_INVALID');
309
+ }
310
+ return record;
311
+ }
312
+ remainingMilliseconds(contextArg) {
313
+ if (contextArg.signal?.aborted) {
314
+ throw createSmartSecretKernelStoreError('OPERATION_ABORTED');
315
+ }
316
+ const remaining = contextArg.deadline - performance.now();
317
+ if (remaining <= 0) {
318
+ throw createSmartSecretKernelStoreError('OPERATION_TIMEOUT');
319
+ }
320
+ return Math.max(1, Math.ceil(remaining));
321
+ }
322
+ createBridgeRequestOptions(contextArg) {
323
+ const timeoutMs = this.remainingMilliseconds(contextArg);
324
+ return {
325
+ timeoutMs,
326
+ ...(contextArg.signal === undefined ? {} : { signal: contextArg.signal }),
327
+ };
328
+ }
329
+ async acquireKernelLease(contextArg) {
330
+ const timeoutMs = this.remainingMilliseconds(contextArg);
331
+ try {
332
+ return await this.mutex.acquire({
333
+ timeoutMs,
334
+ ...(contextArg.signal === undefined ? {} : { signal: contextArg.signal }),
335
+ });
336
+ }
337
+ catch (errorArg) {
338
+ if (errorArg instanceof plugins.smartipc.NamedMutexError) {
339
+ if (errorArg.code === 'ABORTED') {
340
+ throw createSmartSecretKernelStoreError('OPERATION_ABORTED');
341
+ }
342
+ if (errorArg.code === 'TIMEOUT') {
343
+ throw createSmartSecretKernelStoreError('OPERATION_TIMEOUT');
344
+ }
345
+ }
346
+ throw createSmartSecretKernelStoreError('MUTEX_FAILED');
347
+ }
348
+ }
349
+ async withKernelLease(contextArg, operationArg) {
350
+ const lease = await this.acquireKernelLease(contextArg);
351
+ let outcome;
352
+ try {
353
+ outcome = { succeeded: true, value: await operationArg() };
354
+ }
355
+ catch (errorArg) {
356
+ if (errorArg instanceof SmartSecretKernelStoreError) {
357
+ outcome = { succeeded: false, error: errorArg };
358
+ }
359
+ else {
360
+ await this.poisonAndTerminate();
361
+ outcome = {
362
+ succeeded: false,
363
+ error: createSmartSecretKernelStoreError(contextArg.mutation && contextArg.dispatched
364
+ ? 'MUTATION_OUTCOME_UNKNOWN'
365
+ : 'WORKER_INTEGRITY_FAILED'),
366
+ };
367
+ }
368
+ }
369
+ try {
370
+ await lease.release();
371
+ }
372
+ catch {
373
+ await this.poisonAndTerminate();
374
+ throw createSmartSecretKernelStoreError(contextArg.mutation ? 'MUTATION_OUTCOME_UNKNOWN' : 'MUTEX_FAILED');
375
+ }
376
+ if (!outcome.succeeded)
377
+ throw outcome.error;
378
+ return outcome.value;
379
+ }
380
+ async dispatchRead(contextArg, dispatchArg) {
381
+ const requestOptions = this.createBridgeRequestOptions(contextArg);
382
+ contextArg.dispatched = true;
383
+ try {
384
+ return await dispatchArg(requestOptions);
385
+ }
386
+ catch {
387
+ await this.poisonAndTerminate();
388
+ throw createSmartSecretKernelStoreError('WORKER_INTEGRITY_FAILED');
389
+ }
390
+ }
391
+ async dispatchMutation(contextArg, dispatchArg) {
392
+ const requestOptions = this.createBridgeRequestOptions(contextArg);
393
+ contextArg.dispatched = true;
394
+ try {
395
+ return await dispatchArg(requestOptions);
396
+ }
397
+ catch {
398
+ await this.poisonAndTerminate();
399
+ throw createSmartSecretKernelStoreError('MUTATION_OUTCOME_UNKNOWN');
400
+ }
401
+ }
402
+ async throwDomainError(domainErrorArg, contextArg) {
403
+ if (domainErrorArg.code === 'KERNEL_UNAVAILABLE') {
404
+ throw createSmartSecretKernelStoreError('KERNEL_UNAVAILABLE');
405
+ }
406
+ if (domainErrorArg.code === 'ROOT_CONFLICT') {
407
+ throw createSmartSecretKernelStoreError('ROOT_CONFLICT');
408
+ }
409
+ if (domainErrorArg.code === 'ENTRY_CORRUPT') {
410
+ throw createSmartSecretKernelStoreError('ENTRY_CORRUPT');
411
+ }
412
+ if (domainErrorArg.code === 'SOURCE_CHANGED') {
413
+ throw createSmartSecretKernelStoreError('SOURCE_CHANGED');
414
+ }
415
+ if (domainErrorArg.code === 'MUTATION_OUTCOME_UNKNOWN'
416
+ && contextArg.mutation) {
417
+ await this.poisonAndTerminate();
418
+ throw createSmartSecretKernelStoreError('MUTATION_OUTCOME_UNKNOWN');
419
+ }
420
+ await this.poisonAndTerminate();
421
+ throw createSmartSecretKernelStoreError('WORKER_INTEGRITY_FAILED');
422
+ }
423
+ terminateBridgeConfirmed() {
424
+ if (this.terminationPromise)
425
+ return this.terminationPromise;
426
+ let termination;
427
+ try {
428
+ termination = this.bridge.terminate({ gracePeriodMs: 0 });
429
+ }
430
+ catch {
431
+ this.terminationPromise = Promise.resolve(false);
432
+ return this.terminationPromise;
433
+ }
434
+ this.terminationPromise = termination.then(() => true, () => false);
435
+ return this.terminationPromise;
436
+ }
437
+ async poisonAndTerminate() {
438
+ this.poisoned = true;
439
+ await this.terminateBridgeConfirmed();
440
+ }
441
+ }
442
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzZWNyZXQua2VybmVsc3RvcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydHNlY3JldC5rZXJuZWxzdG9yZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLDBCQUEwQixDQUFDO0FBQ3BELE9BQU8sRUFDTCwyQkFBMkIsRUFDM0IsaUNBQWlDLEdBQ2xDLE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUNMLHVDQUF1QyxFQUN2QyxxQ0FBcUMsRUFDckMseUNBQXlDLEVBQ3pDLHdCQUF3QixFQUN4Qiw4QkFBOEIsRUFDOUIsaUNBQWlDLEVBQ2pDLDBDQUEwQyxFQUMxQyxzQ0FBc0MsRUFDdEMsK0JBQStCLEVBQy9CLGtDQUFrQyxFQUNsQywrQkFBK0IsRUFDL0Isd0NBQXdDLEVBQ3hDLHNDQUFzQyxFQUN0QywrQkFBK0IsRUFDL0IsaUNBQWlDLEVBQ2pDLDhCQUE4QixFQUM5QixvQ0FBb0MsR0FPckMsTUFBTSxrQ0FBa0MsQ0FBQztBQU8xQyxNQUFNLGtCQUFrQixHQUFHLE1BQU0sQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFDO0FBQ3RFLE1BQU0sNEJBQTRCLEdBQUcsTUFBTSxDQUFDLG9DQUFvQyxDQUFDLENBQUM7QUEyQ2xGLE1BQU0sY0FBYyxHQUFHLEdBQW9CLEVBQUU7SUFDM0MsSUFBSSxPQUFPLEdBQTJDLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQztJQUMvRCxJQUFJLE1BQU0sR0FBa0MsR0FBRyxFQUFFLEdBQUUsQ0FBQyxDQUFDO0lBQ3JELE1BQU0sT0FBTyxHQUFHLElBQUksT0FBTyxDQUFJLENBQUMsVUFBVSxFQUFFLFNBQVMsRUFBRSxFQUFFO1FBQ3ZELE9BQU8sR0FBRyxVQUFVLENBQUM7UUFDckIsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUNyQixDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxDQUFD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
@@ -0,0 +1,81 @@
1
+ import { type ISmartSecretEnvelopeV1 } from './smartsecret.keyring.protocol.js';
2
+ export type TSmartSecretKekStatus = 'active' | 'retired' | 'revoked';
3
+ export interface ISmartSecretKekDescriptor {
4
+ version: number;
5
+ status: TSmartSecretKekStatus;
6
+ credentialPath?: string;
7
+ expectedFingerprint?: `sha256:${string}`;
8
+ createdAt: number;
9
+ activatedAt: number;
10
+ retiredAt?: number;
11
+ revokedAt?: number;
12
+ escrowReference?: string;
13
+ escrowedAt?: number;
14
+ recoveryTestedAt?: number;
15
+ }
16
+ export interface ISmartSecretKeyringConfig {
17
+ keyringId: string;
18
+ keys: readonly ISmartSecretKekDescriptor[];
19
+ }
20
+ export interface ISmartSecretKekInspection {
21
+ version: number;
22
+ status: TSmartSecretKekStatus;
23
+ expectedFingerprint?: `sha256:${string}`;
24
+ createdAt: number;
25
+ activatedAt: number;
26
+ retiredAt?: number;
27
+ revokedAt?: number;
28
+ escrowReference?: string;
29
+ escrowedAt?: number;
30
+ recoveryTestedAt?: number;
31
+ }
32
+ export interface ISmartSecretKeyringInspection {
33
+ keyringId: string;
34
+ activeVersion: number;
35
+ keys: ISmartSecretKekInspection[];
36
+ }
37
+ export interface IEncryptSmartSecretEnvelopeOptions {
38
+ envelopeId: string;
39
+ plaintext: Uint8Array;
40
+ context: Uint8Array;
41
+ createdAt?: number;
42
+ }
43
+ export interface IDecryptSmartSecretEnvelopeOptions {
44
+ envelope: unknown;
45
+ expectedEnvelopeId: string;
46
+ context: Uint8Array;
47
+ }
48
+ export interface IRewrapSmartSecretEnvelopeOptions {
49
+ envelope: unknown;
50
+ expectedEnvelopeId: string;
51
+ context: Uint8Array;
52
+ targetVersion?: number;
53
+ }
54
+ export interface ISmartSecretRecoverySelfTestResult {
55
+ keyringId: string;
56
+ version: number;
57
+ status: 'active' | 'retired';
58
+ fingerprint: `sha256:${string}`;
59
+ testedAt: number;
60
+ }
61
+ /**
62
+ * A Linux-only, immutable KEK snapshot for strict DEK/KEK envelopes.
63
+ * Envelope persistence and compare-and-swap coordination remain consumer responsibilities.
64
+ */
65
+ export declare class SmartSecretKeyring {
66
+ private readonly keyringId;
67
+ private readonly descriptors;
68
+ private readonly activeVersion;
69
+ private readonly loadedKeys;
70
+ private destroyed;
71
+ private constructor();
72
+ static create(configArg: ISmartSecretKeyringConfig): Promise<SmartSecretKeyring>;
73
+ private requireAlive;
74
+ private requireEnvelopeKey;
75
+ inspect(): ISmartSecretKeyringInspection;
76
+ destroy(): void;
77
+ encryptEnvelope(optionsArg: IEncryptSmartSecretEnvelopeOptions): Promise<ISmartSecretEnvelopeV1>;
78
+ decryptEnvelope(optionsArg: IDecryptSmartSecretEnvelopeOptions): Promise<Uint8Array>;
79
+ rewrapEnvelope(optionsArg: IRewrapSmartSecretEnvelopeOptions): Promise<ISmartSecretEnvelopeV1>;
80
+ recoverySelfTest(versionArg: number): Promise<ISmartSecretRecoverySelfTestResult>;
81
+ }
@@ -0,0 +1,17 @@
1
+ export type TSmartSecretKeyringErrorCode = 'AUTHENTICATION_FAILED' | 'CONFIG_INVALID' | 'CONTEXT_MISMATCH' | 'CRYPTO_OPERATION_FAILED' | 'CREDENTIAL_FILE_INVALID' | 'DESTROYED' | 'ENVELOPE_ID_MISMATCH' | 'ENVELOPE_INVALID' | 'KEK_FINGERPRINT_MISMATCH' | 'KEK_UNAVAILABLE' | 'INVALID_ARGUMENT' | 'PLATFORM_UNSUPPORTED' | 'SIZE_LIMIT_EXCEEDED' | 'TARGET_VERSION_MISMATCH';
2
+ export interface ISmartSecretKeyringErrorJson {
3
+ name: 'SmartSecretKeyringError';
4
+ code: TSmartSecretKeyringErrorCode;
5
+ message: string;
6
+ }
7
+ declare const inspectSymbol: unique symbol;
8
+ /** A code-only error that intentionally retains no operation values or causes. */
9
+ export declare class SmartSecretKeyringError extends Error {
10
+ readonly code: TSmartSecretKeyringErrorCode;
11
+ readonly cause: undefined;
12
+ constructor(codeArg: TSmartSecretKeyringErrorCode);
13
+ toJSON(): ISmartSecretKeyringErrorJson;
14
+ [inspectSymbol](): ISmartSecretKeyringErrorJson;
15
+ }
16
+ export declare const createSmartSecretKeyringError: (codeArg: TSmartSecretKeyringErrorCode) => SmartSecretKeyringError;
17
+ export {};
@@ -0,0 +1,46 @@
1
+ const inspectSymbol = Symbol.for('nodejs.util.inspect.custom');
2
+ const errorCodes = new Set([
3
+ 'AUTHENTICATION_FAILED',
4
+ 'CONFIG_INVALID',
5
+ 'CONTEXT_MISMATCH',
6
+ 'CRYPTO_OPERATION_FAILED',
7
+ 'CREDENTIAL_FILE_INVALID',
8
+ 'DESTROYED',
9
+ 'ENVELOPE_ID_MISMATCH',
10
+ 'ENVELOPE_INVALID',
11
+ 'KEK_FINGERPRINT_MISMATCH',
12
+ 'KEK_UNAVAILABLE',
13
+ 'INVALID_ARGUMENT',
14
+ 'PLATFORM_UNSUPPORTED',
15
+ 'SIZE_LIMIT_EXCEEDED',
16
+ 'TARGET_VERSION_MISMATCH',
17
+ ]);
18
+ /** A code-only error that intentionally retains no operation values or causes. */
19
+ export class SmartSecretKeyringError extends Error {
20
+ constructor(codeArg) {
21
+ const code = errorCodes.has(codeArg) ? codeArg : 'INVALID_ARGUMENT';
22
+ const message = `SmartSecret keyring operation failed (${code}).`;
23
+ super(message);
24
+ this.name = 'SmartSecretKeyringError';
25
+ this.code = code;
26
+ this.stack = `${this.name}: ${message}`;
27
+ Object.defineProperty(this, 'cause', {
28
+ configurable: false,
29
+ enumerable: false,
30
+ value: undefined,
31
+ writable: false,
32
+ });
33
+ }
34
+ toJSON() {
35
+ return {
36
+ name: 'SmartSecretKeyringError',
37
+ code: this.code,
38
+ message: this.message,
39
+ };
40
+ }
41
+ [inspectSymbol]() {
42
+ return this.toJSON();
43
+ }
44
+ }
45
+ export const createSmartSecretKeyringError = (codeArg) => new SmartSecretKeyringError(codeArg);
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzZWNyZXQua2V5cmluZy5lcnJvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c2VjcmV0LmtleXJpbmcuZXJyb3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBc0JBLE1BQU0sYUFBYSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLENBQUMsQ0FBQztBQUMvRCxNQUFNLFVBQVUsR0FBRyxJQUFJLEdBQUcsQ0FBK0I7SUFDdkQsdUJBQXVCO0lBQ3ZCLGdCQUFnQjtJQUNoQixrQkFBa0I7SUFDbEIseUJBQXlCO0lBQ3pCLHlCQUF5QjtJQUN6QixXQUFXO0lBQ1gsc0JBQXNCO0lBQ3RCLGtCQUFrQjtJQUNsQiwwQkFBMEI7SUFDMUIsaUJBQWlCO0lBQ2pCLGtCQUFrQjtJQUNsQixzQkFBc0I7SUFDdEIscUJBQXFCO0lBQ3JCLHlCQUF5QjtDQUMxQixDQUFDLENBQUM7QUFFSCxrRkFBa0Y7QUFDbEYsTUFBTSxPQUFPLHVCQUF3QixTQUFRLEtBQUs7SUFJaEQsWUFBWSxPQUFxQztRQUMvQyxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLGtCQUFrQixDQUFDO1FBQ3BFLE1BQU0sT0FBTyxHQUFHLHlDQUF5QyxJQUFJLElBQUksQ0FBQztRQUNsRSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDZixJQUFJLENBQUMsSUFBSSxHQUFHLHlCQUF5QixDQUFDO1FBQ3RDLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLElBQUksQ0FBQyxLQUFLLEdBQUcsR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO1FBQ3hDLE1BQU0sQ0FBQyxjQUFjLENBQUMsSUFBSSxFQUFFLE9BQU8sRUFBRTtZQUNuQyxZQUFZLEVBQUUsS0FBSztZQUNuQixVQUFVLEVBQUUsS0FBSztZQUNqQixLQUFLLEVBQUUsU0FBUztZQUNoQixRQUFRLEVBQUUsS0FBSztTQUNoQixDQUFDLENBQUM7SUFDTCxDQUFDO0lBRU0sTUFBTTtRQUNYLE9BQU87WUFDTCxJQUFJLEVBQUUseUJBQXlCO1lBQy9CLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtZQUNmLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTztTQUN0QixDQUFDO0lBQ0osQ0FBQztJQUVNLENBQUMsYUFBYSxDQUFDO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ3ZCLENBQUM7Q0FDRjtBQUVELE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUFHLENBQzNDLE9BQXFDLEVBQ1osRUFBRSxDQUFDLElBQUksdUJBQXVCLENBQUMsT0FBTyxDQUFDLENBQUMifQ==