@dsh-enhanced/credentials-keychain 0.1.3

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,126 @@
1
+ import { spawn } from 'node:child_process';
2
+ export class CredentialProviderError extends Error {
3
+ code;
4
+ constructor(code, message) {
5
+ super(message);
6
+ this.code = code;
7
+ this.name = 'CredentialProviderError';
8
+ }
9
+ }
10
+ function minimalLinuxEnv(env) {
11
+ return {
12
+ PATH: '/usr/bin:/bin',
13
+ ...(env.DBUS_SESSION_BUS_ADDRESS === undefined ? {} : { DBUS_SESSION_BUS_ADDRESS: env.DBUS_SESSION_BUS_ADDRESS }),
14
+ ...(env.XDG_RUNTIME_DIR === undefined ? {} : { XDG_RUNTIME_DIR: env.XDG_RUNTIME_DIR }),
15
+ };
16
+ }
17
+ function normalizeSecret(value, maxSecretBytes) {
18
+ const bytes = Buffer.isBuffer(value) ? value : Buffer.from(value);
19
+ if (bytes.byteLength > maxSecretBytes)
20
+ throw new CredentialProviderError('oversize', 'credential provider output is too large');
21
+ const text = bytes.toString('utf8').replace(/[\r\n]+$/u, '');
22
+ if (text.length === 0)
23
+ throw new CredentialProviderError('not-found', 'credential value is missing');
24
+ if (text.includes('\0'))
25
+ throw new CredentialProviderError('invalid-value', 'credential value contains an invalid byte');
26
+ return text;
27
+ }
28
+ const windowsPowerShell = 'C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe';
29
+ const windowsReadCommand = '$credential = Import-Clixml -LiteralPath $args[0]; [Console]::Out.Write($credential.GetNetworkCredential().Password)';
30
+ export async function readCredential(handle, options) {
31
+ if (handle.provider === 'environment') {
32
+ const value = options.env[handle.environmentName];
33
+ if (value === undefined)
34
+ throw new CredentialProviderError('not-found', 'credential value is missing');
35
+ return normalizeSecret(value, options.maxSecretBytes);
36
+ }
37
+ let command;
38
+ if (handle.provider === 'macos-keychain') {
39
+ command = {
40
+ executable: '/usr/bin/security',
41
+ args: ['find-generic-password', '-w', '-s', handle.service, '-a', handle.account],
42
+ env: { PATH: '/usr/bin:/bin' },
43
+ timeoutMs: options.timeoutMs,
44
+ maxOutputBytes: options.maxSecretBytes + 1,
45
+ };
46
+ }
47
+ else if (handle.provider === 'linux-secret-service') {
48
+ command = {
49
+ executable: '/usr/bin/secret-tool',
50
+ args: ['lookup', 'service', handle.service, 'account', handle.account],
51
+ env: minimalLinuxEnv(options.env),
52
+ timeoutMs: options.timeoutMs,
53
+ maxOutputBytes: options.maxSecretBytes + 1,
54
+ };
55
+ }
56
+ else if (handle.provider === 'windows-dpapi') {
57
+ command = {
58
+ executable: windowsPowerShell,
59
+ args: ['-NoLogo', '-NoProfile', '-NonInteractive', '-Command', windowsReadCommand, handle.path],
60
+ env: { PATH: 'C:\\Windows\\System32;C:\\Windows', SystemRoot: 'C:\\Windows' },
61
+ timeoutMs: options.timeoutMs,
62
+ maxOutputBytes: options.maxSecretBytes + 1,
63
+ };
64
+ }
65
+ else {
66
+ throw new CredentialProviderError('provider-failed', 'credential provider is unsupported');
67
+ }
68
+ let result;
69
+ try {
70
+ result = await options.run(command);
71
+ }
72
+ catch (error) {
73
+ if (error instanceof CredentialProviderError)
74
+ throw error;
75
+ throw new CredentialProviderError('provider-failed', 'credential provider execution failed');
76
+ }
77
+ if (result.stdout.byteLength > options.maxSecretBytes) {
78
+ throw new CredentialProviderError('oversize', 'credential provider output is too large');
79
+ }
80
+ if (result.code !== 0)
81
+ throw new CredentialProviderError('provider-failed', 'credential provider returned an error');
82
+ return normalizeSecret(result.stdout, options.maxSecretBytes);
83
+ }
84
+ export const runCredentialCommand = input => new Promise((resolve, reject) => {
85
+ const child = spawn(input.executable, [...input.args], {
86
+ env: { ...input.env },
87
+ shell: false,
88
+ stdio: ['ignore', 'pipe', 'pipe'],
89
+ });
90
+ const stdout = [];
91
+ const stderr = [];
92
+ let total = 0;
93
+ let settled = false;
94
+ let timer;
95
+ const finish = (callback) => {
96
+ if (settled)
97
+ return;
98
+ settled = true;
99
+ if (timer !== undefined)
100
+ clearTimeout(timer);
101
+ callback();
102
+ };
103
+ const append = (target, chunk) => {
104
+ total += chunk.byteLength;
105
+ if (total > input.maxOutputBytes) {
106
+ child.kill('SIGKILL');
107
+ finish(() => reject(new CredentialProviderError('oversize', 'credential provider output is too large')));
108
+ return;
109
+ }
110
+ target.push(Buffer.from(chunk));
111
+ };
112
+ child.stdout.on('data', (chunk) => append(stdout, chunk));
113
+ child.stderr.on('data', (chunk) => append(stderr, chunk));
114
+ child.once('error', () => finish(() => reject(new CredentialProviderError('provider-failed', 'credential provider execution failed'))));
115
+ child.once('close', code => finish(() => resolve({
116
+ code: code ?? -1,
117
+ stdout: Buffer.concat(stdout),
118
+ stderr: Buffer.concat(stderr),
119
+ })));
120
+ timer = setTimeout(() => {
121
+ child.kill('SIGKILL');
122
+ finish(() => reject(new CredentialProviderError('timeout', 'credential provider timed out')));
123
+ }, input.timeoutMs);
124
+ timer.unref?.();
125
+ });
126
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAS1C,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAC3B;IAArB,YAAqB,IAAiC,EAAE,OAAe;QACrE,KAAK,CAAC,OAAO,CAAC,CAAA;QADK,SAAI,GAAJ,IAAI,CAA6B;QAEpD,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;IACvC,CAAC;CACF;AASD,SAAS,eAAe,CAAC,GAAiD;IACxE,OAAO;QACL,IAAI,EAAE,eAAe;QACrB,GAAG,CAAC,GAAG,CAAC,wBAAwB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,wBAAwB,EAAE,GAAG,CAAC,wBAAwB,EAAE,CAAC;QACjH,GAAG,CAAC,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC;KACvF,CAAA;AACH,CAAC;AAED,SAAS,eAAe,CAAC,KAAsB,EAAE,cAAsB;IACrE,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACjE,IAAI,KAAK,CAAC,UAAU,GAAG,cAAc;QAAE,MAAM,IAAI,uBAAuB,CAAC,UAAU,EAAE,yCAAyC,CAAC,CAAA;IAC/H,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;IAC5D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,uBAAuB,CAAC,WAAW,EAAE,6BAA6B,CAAC,CAAA;IACpG,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,uBAAuB,CAAC,eAAe,EAAE,2CAA2C,CAAC,CAAA;IACxH,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,iBAAiB,GAAG,gEAAgE,CAAA;AAC1F,MAAM,kBAAkB,GAAG,sHAAsH,CAAA;AAEjJ,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAwB,EAAE,OAA8B;IAC3F,IAAI,MAAM,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAA;QACjD,IAAI,KAAK,KAAK,SAAS;YAAE,MAAM,IAAI,uBAAuB,CAAC,WAAW,EAAE,6BAA6B,CAAC,CAAA;QACtG,OAAO,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IACvD,CAAC;IACD,IAAI,OAA+B,CAAA;IACnC,IAAI,MAAM,CAAC,QAAQ,KAAK,gBAAgB,EAAE,CAAC;QACzC,OAAO,GAAG;YACN,UAAU,EAAE,mBAAmB;YAC/B,IAAI,EAAE,CAAC,uBAAuB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC;YACjF,GAAG,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE;YAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,cAAc,EAAE,OAAO,CAAC,cAAc,GAAG,CAAC;SAC3C,CAAA;IACL,CAAC;SAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,sBAAsB,EAAE,CAAC;QACtD,OAAO,GAAG;YACN,UAAU,EAAE,sBAAsB;YAClC,IAAI,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC;YACtE,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC;YACjC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,cAAc,EAAE,OAAO,CAAC,cAAc,GAAG,CAAC;SAC3C,CAAA;IACL,CAAC;SAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,eAAe,EAAE,CAAC;QAC/C,OAAO,GAAG;YACR,UAAU,EAAE,iBAAiB;YAC7B,IAAI,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,CAAC,IAAI,CAAC;YAC/F,GAAG,EAAE,EAAE,IAAI,EAAE,mCAAmC,EAAE,UAAU,EAAE,aAAa,EAAE;YAC7E,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,cAAc,EAAE,OAAO,CAAC,cAAc,GAAG,CAAC;SAC3C,CAAA;IACH,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,EAAE,oCAAoC,CAAC,CAAA;IAC5F,CAAC;IACD,IAAI,MAA+B,CAAA;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,uBAAuB;YAAE,MAAM,KAAK,CAAA;QACzD,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,EAAE,sCAAsC,CAAC,CAAA;IAC9F,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;QACtD,MAAM,IAAI,uBAAuB,CAAC,UAAU,EAAE,yCAAyC,CAAC,CAAA;IAC1F,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC;QAAE,MAAM,IAAI,uBAAuB,CAAC,iBAAiB,EAAE,uCAAuC,CAAC,CAAA;IACpH,OAAO,eAAe,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;AAC/D,CAAC;AAED,MAAM,CAAC,MAAM,oBAAoB,GAA4B,KAAK,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;IACpG,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE;QACrD,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE;QACrB,KAAK,EAAE,KAAK;QACZ,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;KAClC,CAAC,CAAA;IACF,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,MAAM,MAAM,GAAa,EAAE,CAAA;IAC3B,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,IAAI,KAAgD,CAAA;IACpD,MAAM,MAAM,GAAG,CAAC,QAAoB,EAAE,EAAE;QACtC,IAAI,OAAO;YAAE,OAAM;QACnB,OAAO,GAAG,IAAI,CAAA;QACd,IAAI,KAAK,KAAK,SAAS;YAAE,YAAY,CAAC,KAAK,CAAC,CAAA;QAC5C,QAAQ,EAAE,CAAA;IACZ,CAAC,CAAA;IACD,MAAM,MAAM,GAAG,CAAC,MAAgB,EAAE,KAAa,EAAE,EAAE;QACjD,KAAK,IAAI,KAAK,CAAC,UAAU,CAAA;QACzB,IAAI,KAAK,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC;YACjC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;YACrB,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,uBAAuB,CAAC,UAAU,EAAE,yCAAyC,CAAC,CAAC,CAAC,CAAA;YACxG,OAAM;QACR,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAA;IACjC,CAAC,CAAA;IACD,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IACjE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAA;IACjE,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAC3C,IAAI,uBAAuB,CAAC,iBAAiB,EAAE,sCAAsC,CAAC,CACvF,CAAC,CAAC,CAAA;IACH,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC;QAC/C,IAAI,EAAE,IAAI,IAAI,CAAC,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;QAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;KAC9B,CAAC,CAAC,CAAC,CAAA;IACJ,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QACtB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAA;QACrB,MAAM,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,uBAAuB,CAAC,SAAS,EAAE,+BAA+B,CAAC,CAAC,CAAC,CAAA;IAC/F,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IACnB,KAAK,CAAC,KAAK,EAAE,EAAE,CAAA;AACjB,CAAC,CAAC,CAAA"}
@@ -0,0 +1,65 @@
1
+ import { Context, Service } from '@deepseek-ai/cordis';
2
+ import { Config } from './config.js';
3
+ import type { CredentialCommandRunner, CredentialHandle, CredentialLeaseMetadata, CredentialLeaseRequest, CredentialLeaseStatus } from './types.js';
4
+ export type CredentialsKeychainErrorCode = 'consumer-denied' | 'disposed' | 'handle-not-found' | 'invalid-ttl' | 'lease-replayed' | 'policy-denied' | 'purpose-denied';
5
+ export declare class CredentialsKeychainError extends Error {
6
+ readonly code: CredentialsKeychainErrorCode;
7
+ constructor(code: CredentialsKeychainErrorCode, message: string);
8
+ }
9
+ export type CredentialLeaseAbortCode = 'disposed' | 'expired' | 'revoked';
10
+ export declare class CredentialLeaseAbortError extends Error {
11
+ readonly code: CredentialLeaseAbortCode;
12
+ constructor(code: CredentialLeaseAbortCode, message: string);
13
+ }
14
+ export interface CredentialsKeychainServiceOptions {
15
+ env?: Readonly<Record<string, string | undefined>>;
16
+ run?: CredentialCommandRunner;
17
+ now?: () => number;
18
+ }
19
+ export interface CredentialCallbackLease {
20
+ readonly id: string;
21
+ readonly handleId: string;
22
+ readonly consumer: string;
23
+ readonly purpose: string;
24
+ readonly expiresAt: number;
25
+ }
26
+ declare module '@deepseek-ai/cordis' {
27
+ interface Context {
28
+ credentialsKeychain: CredentialsKeychainService;
29
+ }
30
+ }
31
+ export declare class CredentialsKeychainService extends Service {
32
+ static Config: import("@deepseek-ai/schemastery").default<Config>;
33
+ private readonly ledger;
34
+ private readonly policy;
35
+ private readonly handles;
36
+ private readonly env;
37
+ private readonly run;
38
+ private readonly defaultLeaseMs;
39
+ private readonly maxSecretBytes;
40
+ private readonly providerTimeoutMs;
41
+ private readonly controllers;
42
+ private readonly operations;
43
+ private active;
44
+ constructor(ctx: Context, input: import('./config.js').Config, options?: CredentialsKeychainServiceOptions);
45
+ withSecret<T>(caller: Context, request: CredentialLeaseRequest, callback: (value: string, signal: AbortSignal, lease: CredentialCallbackLease) => Promise<T>): Promise<T>;
46
+ revoke(input: {
47
+ operatorId: string;
48
+ leaseId: string;
49
+ expectedVersion: number;
50
+ reason: string;
51
+ }): CredentialLeaseMetadata;
52
+ listLeases(input?: {
53
+ status?: CredentialLeaseStatus;
54
+ limit?: number;
55
+ }): CredentialLeaseMetadata[];
56
+ listHandles(): Array<Pick<CredentialHandle, 'consumers' | 'id' | 'maxLeaseMs' | 'provider' | 'purposes'>>;
57
+ health(): {
58
+ handles: number;
59
+ activeLeases: number;
60
+ failedLeases: number;
61
+ };
62
+ private execute;
63
+ private assertActive;
64
+ }
65
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
package/lib/service.js ADDED
@@ -0,0 +1,199 @@
1
+ import { isAbsolute } from 'node:path';
2
+ import { Context, Service } from '@deepseek-ai/cordis';
3
+ import { Config } from './config.js';
4
+ import { CredentialLedger } from './ledger.js';
5
+ import { CredentialProviderError, readCredential, runCredentialCommand } from './providers.js';
6
+ export class CredentialsKeychainError extends Error {
7
+ code;
8
+ constructor(code, message) {
9
+ super(message);
10
+ this.code = code;
11
+ this.name = 'CredentialsKeychainError';
12
+ }
13
+ }
14
+ export class CredentialLeaseAbortError extends Error {
15
+ code;
16
+ constructor(code, message) {
17
+ super(message);
18
+ this.code = code;
19
+ this.name = 'CredentialLeaseAbortError';
20
+ }
21
+ }
22
+ function leaseMetadata(record) {
23
+ return {
24
+ id: record.id,
25
+ handleId: record.handleId,
26
+ consumer: record.consumer,
27
+ purpose: record.purpose,
28
+ status: record.status,
29
+ issuedAt: record.issuedAt,
30
+ expiresAt: record.expiresAt,
31
+ ...(record.settledAt === undefined ? {} : { settledAt: record.settledAt }),
32
+ ...(record.failureCode === undefined ? {} : { failureCode: record.failureCode }),
33
+ version: record.version,
34
+ };
35
+ }
36
+ export class CredentialsKeychainService extends Service {
37
+ static Config = Config;
38
+ ledger;
39
+ policy;
40
+ handles;
41
+ env;
42
+ run;
43
+ defaultLeaseMs;
44
+ maxSecretBytes;
45
+ providerTimeoutMs;
46
+ controllers = new Map();
47
+ operations = new Set();
48
+ active = true;
49
+ constructor(ctx, input, options = {}) {
50
+ super(ctx, 'credentialsKeychain');
51
+ const policy = ctx.get('assistantPolicy');
52
+ if (policy === undefined)
53
+ throw new Error('credentials-keychain: assistantPolicy service is required');
54
+ const config = Config(input);
55
+ if (!isAbsolute(config.databasePath))
56
+ throw new Error('credentials-keychain: databasePath must be absolute');
57
+ this.policy = policy;
58
+ this.handles = new Map(config.handles.map(handle => [handle.id, Object.freeze(handle)]));
59
+ this.env = options.env ?? process.env;
60
+ this.run = options.run ?? runCredentialCommand;
61
+ this.defaultLeaseMs = config.defaultLeaseMs;
62
+ this.maxSecretBytes = config.maxSecretBytes;
63
+ this.providerTimeoutMs = config.providerTimeoutMs;
64
+ this.ledger = new CredentialLedger({ path: config.databasePath, ...(options.now === undefined ? {} : { now: options.now }) });
65
+ ctx.effect(() => async () => {
66
+ this.active = false;
67
+ for (const [leaseId, controller] of this.controllers) {
68
+ const current = this.ledger.get(leaseId);
69
+ if (current?.status === 'active') {
70
+ this.ledger.settle({ leaseId, expectedVersion: current.version, status: 'failed', failureCode: 'service-disposed' });
71
+ }
72
+ controller.abort(new CredentialLeaseAbortError('disposed', 'credentials-keychain disposed'));
73
+ }
74
+ await Promise.allSettled(this.operations);
75
+ this.ledger.close();
76
+ }, 'credentials-keychain.ledger');
77
+ }
78
+ withSecret(caller, request, callback) {
79
+ this.assertActive();
80
+ const operation = this.execute(caller, request, callback);
81
+ this.operations.add(operation);
82
+ void operation.finally(() => this.operations.delete(operation)).catch(() => { });
83
+ return operation;
84
+ }
85
+ revoke(input) {
86
+ this.assertActive();
87
+ const current = this.ledger.get(input.leaseId);
88
+ if (current === undefined)
89
+ throw new Error('credentials-keychain: lease does not exist');
90
+ const decision = this.policy.authorize({
91
+ subject: { kind: 'external', id: `local:${input.operatorId}` },
92
+ action: 'credential.revoke',
93
+ resource: { kind: 'credential', id: current.handleId },
94
+ context: { initiator: 'foreground' },
95
+ }, { idempotencyKey: `credential-revoke:${input.leaseId}:${input.expectedVersion}` });
96
+ if (decision.effect !== 'allow')
97
+ throw new CredentialsKeychainError('policy-denied', `credentials-keychain: policy denied revocation: ${decision.reasonCode}`);
98
+ const revoked = this.ledger.revoke({ leaseId: input.leaseId, expectedVersion: input.expectedVersion,
99
+ actor: `local:${input.operatorId}`, reason: input.reason });
100
+ this.controllers.get(input.leaseId)?.abort(new CredentialLeaseAbortError('revoked', 'credential lease revoked'));
101
+ return leaseMetadata(revoked);
102
+ }
103
+ listLeases(input = {}) {
104
+ this.assertActive();
105
+ return this.ledger.list(input).map(leaseMetadata);
106
+ }
107
+ listHandles() {
108
+ this.assertActive();
109
+ return [...this.handles.values()].map(handle => ({
110
+ id: handle.id,
111
+ provider: handle.provider,
112
+ consumers: [...handle.consumers],
113
+ purposes: [...handle.purposes],
114
+ maxLeaseMs: handle.maxLeaseMs,
115
+ }));
116
+ }
117
+ health() {
118
+ this.assertActive();
119
+ return {
120
+ handles: this.handles.size,
121
+ activeLeases: this.ledger.list({ status: 'active', limit: 1_000 }).length,
122
+ failedLeases: this.ledger.list({ status: 'failed', limit: 1_000 }).length,
123
+ };
124
+ }
125
+ async execute(caller, request, callback) {
126
+ const consumer = caller.fiber.name;
127
+ const handle = this.handles.get(request.handleId);
128
+ if (handle === undefined)
129
+ throw new CredentialsKeychainError('handle-not-found', 'credential handle does not exist');
130
+ if (!handle.consumers.includes(consumer)) {
131
+ throw new CredentialsKeychainError('consumer-denied', 'caller is not allowlisted for this credential handle');
132
+ }
133
+ if (!handle.purposes.includes(request.purpose)) {
134
+ throw new CredentialsKeychainError('purpose-denied', 'purpose is not allowlisted for this credential handle');
135
+ }
136
+ const ttlMs = request.ttlMs ?? Math.min(this.defaultLeaseMs, handle.maxLeaseMs);
137
+ if (!Number.isSafeInteger(ttlMs) || ttlMs < 1_000 || ttlMs > handle.maxLeaseMs) {
138
+ throw new CredentialsKeychainError('invalid-ttl', 'credential lease TTL exceeds the handle limit');
139
+ }
140
+ const decision = this.policy.authorize({
141
+ subject: { kind: 'background', id: consumer },
142
+ action: 'credential.use',
143
+ resource: { kind: 'credential', id: handle.id },
144
+ context: { initiator: 'background' },
145
+ }, { idempotencyKey: `credential-use:${request.idempotencyKey}` });
146
+ if (decision.effect !== 'allow')
147
+ throw new CredentialsKeychainError('policy-denied', `credentials-keychain: policy denied use: ${decision.reasonCode}`);
148
+ const begun = this.ledger.begin({ handleId: handle.id, consumer, purpose: request.purpose,
149
+ idempotencyKey: request.idempotencyKey, ttlMs });
150
+ if (begun.replayed)
151
+ throw new CredentialsKeychainError('lease-replayed', `credential lease request was already ${begun.record.status}`);
152
+ const controller = new AbortController();
153
+ this.controllers.set(begun.record.id, controller);
154
+ const timer = setTimeout(() => {
155
+ const current = this.ledger.get(begun.record.id);
156
+ if (current?.status === 'active') {
157
+ this.ledger.settle({ leaseId: current.id, expectedVersion: current.version,
158
+ status: 'expired', failureCode: 'lease-expired' });
159
+ }
160
+ controller.abort(new CredentialLeaseAbortError('expired', 'credential lease expired'));
161
+ }, ttlMs);
162
+ timer.unref?.();
163
+ try {
164
+ const value = await readCredential(handle, { env: this.env, run: this.run,
165
+ timeoutMs: this.providerTimeoutMs, maxSecretBytes: this.maxSecretBytes });
166
+ const result = await callback(value, controller.signal, {
167
+ id: begun.record.id, handleId: handle.id, consumer, purpose: request.purpose,
168
+ expiresAt: begun.record.expiresAt,
169
+ });
170
+ const current = this.ledger.get(begun.record.id);
171
+ if (current?.status === 'active') {
172
+ this.ledger.settle({ leaseId: current.id, expectedVersion: current.version,
173
+ status: controller.signal.aborted ? 'expired' : 'completed',
174
+ ...(controller.signal.aborted ? { failureCode: 'lease-expired' } : {}) });
175
+ }
176
+ return result;
177
+ }
178
+ catch (error) {
179
+ const current = this.ledger.get(begun.record.id);
180
+ if (current?.status === 'active') {
181
+ this.ledger.settle({ leaseId: current.id, expectedVersion: current.version,
182
+ status: controller.signal.aborted ? 'expired' : 'failed',
183
+ failureCode: controller.signal.aborted
184
+ ? 'lease-expired'
185
+ : error instanceof CredentialProviderError ? error.code : 'callback-failed' });
186
+ }
187
+ throw error;
188
+ }
189
+ finally {
190
+ clearTimeout(timer);
191
+ this.controllers.delete(begun.record.id);
192
+ }
193
+ }
194
+ assertActive() {
195
+ if (!this.active)
196
+ throw new CredentialsKeychainError('disposed', 'credentials-keychain service is disposed');
197
+ }
198
+ }
199
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import { DatabaseSync } from 'node:sqlite';
2
+ export declare const credentialSchemaVersion = 1;
3
+ export declare class CredentialDatabaseError extends Error {
4
+ readonly code: 'invalid-path' | 'schema-too-new';
5
+ constructor(code: 'invalid-path' | 'schema-too-new', message: string);
6
+ }
7
+ export declare function openCredentialDatabase(path: string): DatabaseSync;
8
+ //# sourceMappingURL=sqlite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC,qBAAa,uBAAwB,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,cAAc,GAAG,gBAAgB;gBAAvC,IAAI,EAAE,cAAc,GAAG,gBAAgB,EAAE,OAAO,EAAE,MAAM;CAI9E;AA2CD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAkBjE"}
package/lib/sqlite.js ADDED
@@ -0,0 +1,76 @@
1
+ import { chmodSync, mkdirSync } from 'node:fs';
2
+ import { dirname, isAbsolute } from 'node:path';
3
+ import { DatabaseSync } from 'node:sqlite';
4
+ export const credentialSchemaVersion = 1;
5
+ export class CredentialDatabaseError extends Error {
6
+ code;
7
+ constructor(code, message) {
8
+ super(message);
9
+ this.code = code;
10
+ this.name = 'CredentialDatabaseError';
11
+ }
12
+ }
13
+ function migrate(database) {
14
+ const current = database.prepare('PRAGMA user_version').get();
15
+ if (current.user_version > credentialSchemaVersion) {
16
+ throw new CredentialDatabaseError('schema-too-new', `credential schema ${current.user_version} is newer than supported schema ${credentialSchemaVersion}`);
17
+ }
18
+ if (current.user_version === credentialSchemaVersion)
19
+ return;
20
+ database.exec(`
21
+ BEGIN IMMEDIATE;
22
+ CREATE TABLE credential_leases (
23
+ id TEXT PRIMARY KEY,
24
+ idempotency_key TEXT NOT NULL UNIQUE,
25
+ handle_id TEXT NOT NULL,
26
+ consumer TEXT NOT NULL,
27
+ purpose TEXT NOT NULL,
28
+ status TEXT NOT NULL CHECK (status IN ('active', 'completed', 'expired', 'failed', 'revoked')),
29
+ issued_at INTEGER NOT NULL,
30
+ expires_at INTEGER NOT NULL,
31
+ settled_at INTEGER,
32
+ failure_code TEXT,
33
+ version INTEGER NOT NULL DEFAULT 1
34
+ ) STRICT;
35
+ CREATE INDEX credential_leases_status_expiry ON credential_leases(status, expires_at);
36
+ CREATE TABLE credential_audit (
37
+ sequence INTEGER PRIMARY KEY AUTOINCREMENT,
38
+ occurred_at INTEGER NOT NULL,
39
+ action TEXT NOT NULL,
40
+ lease_id TEXT NOT NULL,
41
+ handle_id TEXT NOT NULL,
42
+ consumer TEXT NOT NULL,
43
+ purpose TEXT NOT NULL,
44
+ outcome TEXT NOT NULL,
45
+ failure_code TEXT,
46
+ actor TEXT,
47
+ reason TEXT
48
+ ) STRICT;
49
+ PRAGMA user_version = 1;
50
+ COMMIT;
51
+ `);
52
+ }
53
+ export function openCredentialDatabase(path) {
54
+ if (path !== ':memory:' && !isAbsolute(path)) {
55
+ throw new CredentialDatabaseError('invalid-path', 'credential database path must be absolute');
56
+ }
57
+ if (path !== ':memory:')
58
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
59
+ const database = new DatabaseSync(path);
60
+ try {
61
+ database.exec('PRAGMA foreign_keys = ON');
62
+ database.exec('PRAGMA busy_timeout = 5000');
63
+ database.exec('PRAGMA synchronous = FULL');
64
+ if (path !== ':memory:')
65
+ database.exec('PRAGMA journal_mode = WAL');
66
+ migrate(database);
67
+ if (path !== ':memory:')
68
+ chmodSync(path, 0o600);
69
+ return database;
70
+ }
71
+ catch (error) {
72
+ database.close();
73
+ throw error;
74
+ }
75
+ }
76
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAC9C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAA;AAExC,MAAM,OAAO,uBAAwB,SAAQ,KAAK;IAC3B;IAArB,YAAqB,IAAuC,EAAE,OAAe;QAC3E,KAAK,CAAC,OAAO,CAAC,CAAA;QADK,SAAI,GAAJ,IAAI,CAAmC;QAE1D,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAA;IACvC,CAAC;CACF;AAED,SAAS,OAAO,CAAC,QAAsB;IACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,GAAG,EAA8B,CAAA;IACzF,IAAI,OAAO,CAAC,YAAY,GAAG,uBAAuB,EAAE,CAAC;QACnD,MAAM,IAAI,uBAAuB,CAAC,gBAAgB,EAChD,qBAAqB,OAAO,CAAC,YAAY,mCAAmC,uBAAuB,EAAE,CAAC,CAAA;IAC1G,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,KAAK,uBAAuB;QAAE,OAAM;IAC5D,QAAQ,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+Bb,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,MAAM,IAAI,uBAAuB,CAAC,cAAc,EAAE,2CAA2C,CAAC,CAAA;IAChG,CAAC;IACD,IAAI,IAAI,KAAK,UAAU;QAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;IACnF,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,CAAA;IACvC,IAAI,CAAC;QACH,QAAQ,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;QACzC,QAAQ,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAA;QAC3C,QAAQ,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;QAC1C,IAAI,IAAI,KAAK,UAAU;YAAE,QAAQ,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAA;QACnE,OAAO,CAAC,QAAQ,CAAC,CAAA;QACjB,IAAI,IAAI,KAAK,UAAU;YAAE,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;QAC/C,OAAO,QAAQ,CAAA;IACjB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,QAAQ,CAAC,KAAK,EAAE,CAAA;QAChB,MAAM,KAAK,CAAA;IACb,CAAC;AACH,CAAC"}
package/lib/types.d.ts ADDED
@@ -0,0 +1,57 @@
1
+ export interface CredentialHandleBase {
2
+ id: string;
3
+ consumers: readonly string[];
4
+ purposes: readonly string[];
5
+ maxLeaseMs: number;
6
+ }
7
+ export interface EnvironmentCredentialHandle extends CredentialHandleBase {
8
+ provider: 'environment';
9
+ environmentName: string;
10
+ }
11
+ export interface KeychainCredentialHandle extends CredentialHandleBase {
12
+ provider: 'linux-secret-service' | 'macos-keychain';
13
+ service: string;
14
+ account: string;
15
+ }
16
+ export interface WindowsDpapiCredentialHandle extends CredentialHandleBase {
17
+ provider: 'windows-dpapi';
18
+ /** Absolute path to a per-user DPAPI-encrypted PSCredential export. */
19
+ path: string;
20
+ }
21
+ export type CredentialHandle = EnvironmentCredentialHandle | KeychainCredentialHandle | WindowsDpapiCredentialHandle;
22
+ export interface CredentialCommandInput {
23
+ executable: string;
24
+ args: readonly string[];
25
+ env: Readonly<Record<string, string>>;
26
+ timeoutMs: number;
27
+ maxOutputBytes: number;
28
+ }
29
+ export interface CredentialCommandResult {
30
+ code: number;
31
+ stdout: Buffer;
32
+ stderr: Buffer;
33
+ }
34
+ export type CredentialCommandRunner = (input: CredentialCommandInput) => Promise<CredentialCommandResult>;
35
+ export type CredentialProviderErrorCode = 'invalid-value' | 'not-found' | 'oversize' | 'provider-failed' | 'timeout';
36
+ export interface CredentialLeaseRequest {
37
+ handleId: string;
38
+ purpose: string;
39
+ ttlMs?: number;
40
+ idempotencyKey: string;
41
+ }
42
+ export type CredentialLeaseStatus = 'active' | 'completed' | 'expired' | 'failed' | 'revoked';
43
+ export interface CredentialLeaseRecord {
44
+ id: string;
45
+ handleId: string;
46
+ consumer: string;
47
+ purpose: string;
48
+ idempotencyKey: string;
49
+ status: CredentialLeaseStatus;
50
+ issuedAt: number;
51
+ expiresAt: number;
52
+ settledAt?: number;
53
+ failureCode?: string;
54
+ version: number;
55
+ }
56
+ export type CredentialLeaseMetadata = Omit<CredentialLeaseRecord, 'idempotencyKey'>;
57
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,SAAS,MAAM,EAAE,CAAA;IAC5B,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACvE,QAAQ,EAAE,aAAa,CAAA;IACvB,eAAe,EAAE,MAAM,CAAA;CACxB;AAED,MAAM,WAAW,wBAAyB,SAAQ,oBAAoB;IACpE,QAAQ,EAAE,sBAAsB,GAAG,gBAAgB,CAAA;IACnD,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACxE,QAAQ,EAAE,eAAe,CAAA;IACzB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,MAAM,gBAAgB,GAAG,2BAA2B,GAAG,wBAAwB,GAAG,4BAA4B,CAAA;AAEpH,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;IACvB,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,MAAM,uBAAuB,GAAG,CAAC,KAAK,EAAE,sBAAsB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAA;AAEzG,MAAM,MAAM,2BAA2B,GAAG,eAAe,GAAG,WAAW,GAAG,UAAU,GAAG,iBAAiB,GAAG,SAAS,CAAA;AAEpH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAA;AAE7F,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,cAAc,EAAE,MAAM,CAAA;IACtB,MAAM,EAAE,qBAAqB,CAAA;IAC7B,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,MAAM,uBAAuB,GAAG,IAAI,CAAC,qBAAqB,EAAE,gBAAgB,CAAC,CAAA"}
package/lib/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,2 @@
1
+ export declare const version = "0.1.3";
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,UAAU,CAAA"}
package/lib/version.js ADDED
@@ -0,0 +1,2 @@
1
+ export const version = '0.1.3';
2
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAA"}