@push.rocks/smartsecret 1.1.0 → 1.2.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.
- package/.smartconfig.json +8 -1
- package/dist_rust/smartsecret-kernel_linux_amd64 +0 -0
- package/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +3 -1
- package/dist_ts/smartsecret.kernel.error.d.ts +17 -0
- package/dist_ts/smartsecret.kernel.error.js +47 -0
- package/dist_ts/smartsecret.kernel.protocol.d.ts +159 -0
- package/dist_ts/smartsecret.kernel.protocol.js +424 -0
- package/dist_ts/smartsecret.kernelstore.d.ts +49 -0
- package/dist_ts/smartsecret.kernelstore.js +442 -0
- package/dist_ts/smartsecret.plugins.d.ts +4 -1
- package/dist_ts/smartsecret.plugins.js +5 -2
- package/package.json +11 -6
- package/readme.hints.md +11 -0
- package/readme.md +73 -1
- package/third-party-notices.md +177 -0
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/index.ts +6 -0
- package/ts/smartsecret.kernel.error.ts +78 -0
- package/ts/smartsecret.kernel.protocol.ts +657 -0
- package/ts/smartsecret.kernelstore.ts +664 -0
- package/ts/smartsecret.plugins.ts +4 -1
|
@@ -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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
|
|
@@ -3,5 +3,8 @@ import * as crypto from 'crypto';
|
|
|
3
3
|
import * as fs from 'fs';
|
|
4
4
|
import * as os from 'os';
|
|
5
5
|
import * as path from 'path';
|
|
6
|
+
import * as url from 'url';
|
|
6
7
|
import * as smartcrypto from '@push.rocks/smartcrypto';
|
|
7
|
-
|
|
8
|
+
import * as smartipc from '@push.rocks/smartipc';
|
|
9
|
+
import * as smartrust from '@push.rocks/smartrust';
|
|
10
|
+
export { childProcess, crypto, fs, os, path, url, smartcrypto, smartipc, smartrust };
|
|
@@ -4,7 +4,10 @@ import * as crypto from 'crypto';
|
|
|
4
4
|
import * as fs from 'fs';
|
|
5
5
|
import * as os from 'os';
|
|
6
6
|
import * as path from 'path';
|
|
7
|
+
import * as url from 'url';
|
|
7
8
|
// @push.rocks scope
|
|
8
9
|
import * as smartcrypto from '@push.rocks/smartcrypto';
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
import * as smartipc from '@push.rocks/smartipc';
|
|
11
|
+
import * as smartrust from '@push.rocks/smartrust';
|
|
12
|
+
export { childProcess, crypto, fs, os, path, url, smartcrypto, smartipc, smartrust };
|
|
13
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRzZWNyZXQucGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3NtYXJ0c2VjcmV0LnBsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxZQUFZLE1BQU0sZUFBZSxDQUFDO0FBQzlDLE9BQU8sS0FBSyxNQUFNLE1BQU0sUUFBUSxDQUFDO0FBQ2pDLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sS0FBSyxFQUFFLE1BQU0sSUFBSSxDQUFDO0FBQ3pCLE9BQU8sS0FBSyxJQUFJLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sS0FBSyxHQUFHLE1BQU0sS0FBSyxDQUFDO0FBRTNCLG9CQUFvQjtBQUNwQixPQUFPLEtBQUssV0FBVyxNQUFNLHlCQUF5QixDQUFDO0FBQ3ZELE9BQU8sS0FBSyxRQUFRLE1BQU0sc0JBQXNCLENBQUM7QUFDakQsT0FBTyxLQUFLLFNBQVMsTUFBTSx1QkFBdUIsQ0FBQztBQUVuRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsQ0FBQyJ9
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@push.rocks/smartsecret",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "OS
|
|
5
|
+
"description": "OS-backed secret storage plus strict Linux kernel-keyring and envelope APIs for Node.js.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
7
7
|
"typings": "dist_ts/index.d.ts",
|
|
8
8
|
"type": "module",
|
|
@@ -31,8 +31,9 @@
|
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@git.zone/tsbuild": "^4.4.2",
|
|
33
33
|
"@git.zone/tsrun": "^2.0.6",
|
|
34
|
+
"@git.zone/tsrust": "^1.7.0",
|
|
34
35
|
"@git.zone/tstest": "^3.6.7",
|
|
35
|
-
"@types/node": "^
|
|
36
|
+
"@types/node": "^25.9.5"
|
|
36
37
|
},
|
|
37
38
|
"files": [
|
|
38
39
|
"ts/**/*",
|
|
@@ -44,17 +45,21 @@
|
|
|
44
45
|
"assets/**/*",
|
|
45
46
|
"cli.js",
|
|
46
47
|
".smartconfig.json",
|
|
47
|
-
"readme.md"
|
|
48
|
+
"readme.md",
|
|
49
|
+
"third-party-notices.md"
|
|
48
50
|
],
|
|
49
51
|
"browserslist": [
|
|
50
52
|
"last 1 chrome versions"
|
|
51
53
|
],
|
|
52
54
|
"dependencies": {
|
|
53
|
-
"@push.rocks/smartcrypto": "^2.2.0"
|
|
55
|
+
"@push.rocks/smartcrypto": "^2.2.0",
|
|
56
|
+
"@push.rocks/smartipc": "^2.4.0",
|
|
57
|
+
"@push.rocks/smartrust": "^1.6.0"
|
|
54
58
|
},
|
|
55
59
|
"scripts": {
|
|
56
60
|
"test": "(tstest test/ --verbose)",
|
|
57
|
-
"
|
|
61
|
+
"test:before": "(tsrust) && (cargo test --manifest-path rust/Cargo.toml --target-dir .nogit/cargo-test-target)",
|
|
62
|
+
"build": "(tsbuild) && (tsrust)",
|
|
58
63
|
"buildDocs": "tsdoc"
|
|
59
64
|
}
|
|
60
65
|
}
|
package/readme.hints.md
CHANGED
|
@@ -17,3 +17,14 @@
|
|
|
17
17
|
- Loads exact 32-byte KEKs from validated absolute credential paths into immutable per-instance snapshots
|
|
18
18
|
- Consumers own envelope persistence and compare-and-swap coordination
|
|
19
19
|
- JavaScript key and plaintext zeroization is best effort
|
|
20
|
+
|
|
21
|
+
## SmartSecret Kernel Store
|
|
22
|
+
- Additive strict API; legacy SmartSecret backend selection remains unchanged
|
|
23
|
+
- Requires Node.js 25, Linux x64, Linux keyutils, and the exact package-owned static Rust worker
|
|
24
|
+
- No shell, PATH lookup, environment override, Secret Service, or filesystem secret fallback
|
|
25
|
+
- Generic values are framed and limited to 0..1024 bytes; service/account names are valid scalar UTF-8 strings of 1..1024 bytes
|
|
26
|
+
- Persistent-root service rings are revalidated on every operation; process keyring ownership is staging-only
|
|
27
|
+
- Service-wide SmartIPC NamedMutex plus a single monotonic 1..60000 ms deadline bounds cooperating cross-process access
|
|
28
|
+
- Any post-dispatch mutation ambiguity or worker integrity failure terminates and poisons the store
|
|
29
|
+
- DevIdP v1 migration is opaque, receipt-bound, keyutils-only, and requires a quiescent legacy writer
|
|
30
|
+
- Same-UID readability and kernel expiry/reboot behavior are part of the security model
|