proofscan 0.6.9 → 0.7.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.
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +16 -8
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/connectors.d.ts.map +1 -1
- package/dist/commands/connectors.js +9 -4
- package/dist/commands/connectors.js.map +1 -1
- package/dist/secrets/detection.d.ts +71 -0
- package/dist/secrets/detection.d.ts.map +1 -0
- package/dist/secrets/detection.js +179 -0
- package/dist/secrets/detection.js.map +1 -0
- package/dist/secrets/index.d.ts +11 -0
- package/dist/secrets/index.d.ts.map +1 -0
- package/dist/secrets/index.js +16 -0
- package/dist/secrets/index.js.map +1 -0
- package/dist/secrets/providers/dpapi.d.ts +22 -0
- package/dist/secrets/providers/dpapi.d.ts.map +1 -0
- package/dist/secrets/providers/dpapi.js +95 -0
- package/dist/secrets/providers/dpapi.js.map +1 -0
- package/dist/secrets/providers/index.d.ts +20 -0
- package/dist/secrets/providers/index.d.ts.map +1 -0
- package/dist/secrets/providers/index.js +47 -0
- package/dist/secrets/providers/index.js.map +1 -0
- package/dist/secrets/providers/plain.d.ts +21 -0
- package/dist/secrets/providers/plain.d.ts.map +1 -0
- package/dist/secrets/providers/plain.js +29 -0
- package/dist/secrets/providers/plain.js.map +1 -0
- package/dist/secrets/redaction.d.ts +76 -0
- package/dist/secrets/redaction.d.ts.map +1 -0
- package/dist/secrets/redaction.js +136 -0
- package/dist/secrets/redaction.js.map +1 -0
- package/dist/secrets/store.d.ts +42 -0
- package/dist/secrets/store.d.ts.map +1 -0
- package/dist/secrets/store.js +174 -0
- package/dist/secrets/store.js.map +1 -0
- package/dist/secrets/types.d.ts +133 -0
- package/dist/secrets/types.d.ts.map +1 -0
- package/dist/secrets/types.js +39 -0
- package/dist/secrets/types.js.map +1 -0
- package/dist/shell/completer.d.ts.map +1 -1
- package/dist/shell/completer.js +91 -14
- package/dist/shell/completer.js.map +1 -1
- package/dist/shell/repl.d.ts +0 -5
- package/dist/shell/repl.d.ts.map +1 -1
- package/dist/shell/repl.js +11 -10
- package/dist/shell/repl.js.map +1 -1
- package/dist/shell/types.d.ts +24 -0
- package/dist/shell/types.d.ts.map +1 -1
- package/dist/shell/types.js +26 -0
- package/dist/shell/types.js.map +1 -1
- package/dist/utils/output.d.ts +14 -0
- package/dist/utils/output.d.ts.map +1 -1
- package/dist/utils/output.js +16 -0
- package/dist/utils/output.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dpapi.js","sourceRoot":"","sources":["../../../src/secrets/providers/dpapi.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encryption providers index
|
|
3
|
+
*/
|
|
4
|
+
export { PlainProvider } from './plain.js';
|
|
5
|
+
export { DpapiProvider } from './dpapi.js';
|
|
6
|
+
import type { IEncryptionProvider, ProviderType } from '../types.js';
|
|
7
|
+
/**
|
|
8
|
+
* Get the best available encryption provider for the current platform
|
|
9
|
+
*
|
|
10
|
+
* Priority:
|
|
11
|
+
* 1. DPAPI on Windows
|
|
12
|
+
* 2. Keychain on macOS (future)
|
|
13
|
+
* 3. Plain fallback (no encryption, with warning)
|
|
14
|
+
*/
|
|
15
|
+
export declare function getBestProvider(): IEncryptionProvider;
|
|
16
|
+
/**
|
|
17
|
+
* Get a specific provider by type
|
|
18
|
+
*/
|
|
19
|
+
export declare function getProvider(type: ProviderType): IEncryptionProvider;
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/secrets/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAIrE;;;;;;;GAOG;AACH,wBAAgB,eAAe,IAAI,mBAAmB,CAgBrD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,mBAAmB,CAYnE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encryption providers index
|
|
3
|
+
*/
|
|
4
|
+
export { PlainProvider } from './plain.js';
|
|
5
|
+
export { DpapiProvider } from './dpapi.js';
|
|
6
|
+
import { PlainProvider } from './plain.js';
|
|
7
|
+
import { DpapiProvider } from './dpapi.js';
|
|
8
|
+
/**
|
|
9
|
+
* Get the best available encryption provider for the current platform
|
|
10
|
+
*
|
|
11
|
+
* Priority:
|
|
12
|
+
* 1. DPAPI on Windows
|
|
13
|
+
* 2. Keychain on macOS (future)
|
|
14
|
+
* 3. Plain fallback (no encryption, with warning)
|
|
15
|
+
*/
|
|
16
|
+
export function getBestProvider() {
|
|
17
|
+
// Try DPAPI first (Windows)
|
|
18
|
+
const dpapi = new DpapiProvider();
|
|
19
|
+
if (dpapi.isAvailable()) {
|
|
20
|
+
return dpapi;
|
|
21
|
+
}
|
|
22
|
+
// TODO: Add macOS Keychain support
|
|
23
|
+
// const keychain = new KeychainProvider();
|
|
24
|
+
// if (keychain.isAvailable()) {
|
|
25
|
+
// return keychain;
|
|
26
|
+
// }
|
|
27
|
+
// Fallback to plain (no encryption)
|
|
28
|
+
console.warn('Warning: No secure encryption provider available. Secrets will be stored without encryption.');
|
|
29
|
+
return new PlainProvider();
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Get a specific provider by type
|
|
33
|
+
*/
|
|
34
|
+
export function getProvider(type) {
|
|
35
|
+
switch (type) {
|
|
36
|
+
case 'dpapi':
|
|
37
|
+
return new DpapiProvider();
|
|
38
|
+
case 'plain':
|
|
39
|
+
return new PlainProvider();
|
|
40
|
+
case 'keychain':
|
|
41
|
+
// Not yet implemented
|
|
42
|
+
throw new Error('Keychain provider not yet implemented');
|
|
43
|
+
default:
|
|
44
|
+
throw new Error(`Unknown provider type: ${type}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/secrets/providers/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAG3C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;GAOG;AACH,MAAM,UAAU,eAAe;IAC7B,4BAA4B;IAC5B,MAAM,KAAK,GAAG,IAAI,aAAa,EAAE,CAAC;IAClC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,mCAAmC;IACnC,2CAA2C;IAC3C,gCAAgC;IAChC,qBAAqB;IACrB,IAAI;IAEJ,oCAAoC;IACpC,OAAO,CAAC,IAAI,CAAC,8FAA8F,CAAC,CAAC;IAC7G,OAAO,IAAI,aAAa,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,IAAkB;IAC5C,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,OAAO;YACV,OAAO,IAAI,aAAa,EAAE,CAAC;QAC7B,KAAK,OAAO;YACV,OAAO,IAAI,aAAa,EAAE,CAAC;QAC7B,KAAK,UAAU;YACb,sBAAsB;YACtB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D;YACE,MAAM,IAAI,KAAK,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;IACtD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plain encryption provider (no encryption)
|
|
3
|
+
*
|
|
4
|
+
* This is a fallback provider for testing and platforms without
|
|
5
|
+
* native encryption support. It provides NO security and should
|
|
6
|
+
* only be used for development/testing purposes.
|
|
7
|
+
*/
|
|
8
|
+
import type { IEncryptionProvider, ProviderType } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Plain provider - stores secrets as base64 without encryption
|
|
11
|
+
*
|
|
12
|
+
* WARNING: This provider offers NO security. Secrets are only
|
|
13
|
+
* base64 encoded, not encrypted. Use only for testing.
|
|
14
|
+
*/
|
|
15
|
+
export declare class PlainProvider implements IEncryptionProvider {
|
|
16
|
+
readonly type: ProviderType;
|
|
17
|
+
isAvailable(): boolean;
|
|
18
|
+
encrypt(plaintext: string): Promise<string>;
|
|
19
|
+
decrypt(ciphertext: string): Promise<string>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=plain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain.d.ts","sourceRoot":"","sources":["../../../src/secrets/providers/plain.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAErE;;;;;GAKG;AACH,qBAAa,aAAc,YAAW,mBAAmB;IACvD,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAW;IAEtC,WAAW,IAAI,OAAO;IAKhB,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAK3C,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAInD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plain encryption provider (no encryption)
|
|
3
|
+
*
|
|
4
|
+
* This is a fallback provider for testing and platforms without
|
|
5
|
+
* native encryption support. It provides NO security and should
|
|
6
|
+
* only be used for development/testing purposes.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Plain provider - stores secrets as base64 without encryption
|
|
10
|
+
*
|
|
11
|
+
* WARNING: This provider offers NO security. Secrets are only
|
|
12
|
+
* base64 encoded, not encrypted. Use only for testing.
|
|
13
|
+
*/
|
|
14
|
+
export class PlainProvider {
|
|
15
|
+
type = 'plain';
|
|
16
|
+
isAvailable() {
|
|
17
|
+
// Always available as fallback
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
async encrypt(plaintext) {
|
|
21
|
+
// Just base64 encode - NO ENCRYPTION
|
|
22
|
+
return Buffer.from(plaintext, 'utf-8').toString('base64');
|
|
23
|
+
}
|
|
24
|
+
async decrypt(ciphertext) {
|
|
25
|
+
// Just base64 decode
|
|
26
|
+
return Buffer.from(ciphertext, 'base64').toString('utf-8');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=plain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain.js","sourceRoot":"","sources":["../../../src/secrets/providers/plain.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH;;;;;GAKG;AACH,MAAM,OAAO,aAAa;IACf,IAAI,GAAiB,OAAO,CAAC;IAEtC,WAAW;QACT,+BAA+B;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,SAAiB;QAC7B,qCAAqC;QACrC,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,UAAkB;QAC9B,qBAAqB;QACrB,OAAO,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAC7D,CAAC;CACF"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret redaction utilities (Phase 3.5)
|
|
3
|
+
*
|
|
4
|
+
* Provides deep redaction of secrets in config output.
|
|
5
|
+
* Used by config show, export, and snapshot commands.
|
|
6
|
+
*/
|
|
7
|
+
/** Redacted placeholder for secrets */
|
|
8
|
+
export declare const REDACTED = "***REDACTED***";
|
|
9
|
+
/** Redacted placeholder for secret references */
|
|
10
|
+
export declare const REDACTED_REF = "***SECRET_REF***";
|
|
11
|
+
/**
|
|
12
|
+
* Result of redaction
|
|
13
|
+
*/
|
|
14
|
+
export interface RedactionResult {
|
|
15
|
+
/** Redacted value */
|
|
16
|
+
value: unknown;
|
|
17
|
+
/** Number of values redacted */
|
|
18
|
+
count: number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Options for redaction
|
|
22
|
+
*/
|
|
23
|
+
export interface RedactionOptions {
|
|
24
|
+
/** Redact values for secret keys (default: true) */
|
|
25
|
+
redactSecretKeys?: boolean;
|
|
26
|
+
/** Redact secret references like "dpapi:xxx" (default: true) */
|
|
27
|
+
redactSecretRefs?: boolean;
|
|
28
|
+
/** Custom redaction string for values */
|
|
29
|
+
redactedValue?: string;
|
|
30
|
+
/** Custom redaction string for references */
|
|
31
|
+
redactedRef?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Recursively redact secrets in a value
|
|
35
|
+
*
|
|
36
|
+
* Handles:
|
|
37
|
+
* - Secret references (dpapi:xxx, keychain:xxx)
|
|
38
|
+
* - Values for keys that match secret patterns
|
|
39
|
+
*
|
|
40
|
+
* @param value - Any JSON-serializable value
|
|
41
|
+
* @param options - Redaction options
|
|
42
|
+
* @returns Redacted value and count
|
|
43
|
+
*/
|
|
44
|
+
export declare function redactDeep(value: unknown, options?: RedactionOptions): RedactionResult;
|
|
45
|
+
/**
|
|
46
|
+
* Redact a single value based on key and options
|
|
47
|
+
*
|
|
48
|
+
* @param key - The key name
|
|
49
|
+
* @param value - The value to potentially redact
|
|
50
|
+
* @param options - Redaction options
|
|
51
|
+
* @returns Redacted value if applicable, original otherwise
|
|
52
|
+
*/
|
|
53
|
+
export declare function redactValue(key: string, value: string, options?: RedactionOptions): string;
|
|
54
|
+
/**
|
|
55
|
+
* Redact env variables object
|
|
56
|
+
*
|
|
57
|
+
* @param env - Environment variables
|
|
58
|
+
* @param options - Redaction options
|
|
59
|
+
* @returns Redacted env and count
|
|
60
|
+
*/
|
|
61
|
+
export declare function redactEnv(env: Record<string, string>, options?: RedactionOptions): {
|
|
62
|
+
env: Record<string, string>;
|
|
63
|
+
count: number;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Create a summary of redacted values
|
|
67
|
+
*
|
|
68
|
+
* @param count - Number of values redacted
|
|
69
|
+
* @returns Human-readable summary
|
|
70
|
+
*/
|
|
71
|
+
export declare function redactionSummary(count: number): string;
|
|
72
|
+
/**
|
|
73
|
+
* Check if a value has been redacted
|
|
74
|
+
*/
|
|
75
|
+
export declare function isRedacted(value: string): boolean;
|
|
76
|
+
//# sourceMappingURL=redaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.d.ts","sourceRoot":"","sources":["../../src/secrets/redaction.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,uCAAuC;AACvC,eAAO,MAAM,QAAQ,mBAAmB,CAAC;AAEzC,iDAAiD;AACjD,eAAO,MAAM,YAAY,qBAAqB,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,gCAAgC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,oDAAoD;IACpD,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,yCAAyC;IACzC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AASD;;;;;;;;;;GAUG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,OAAO,EACd,OAAO,GAAE,gBAAqB,GAC7B,eAAe,CAkDjB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,gBAAqB,GAC7B,MAAM,CAgBR;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC3B,OAAO,GAAE,gBAAqB,GAC7B;IAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAchD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQtD;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAEjD"}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Secret redaction utilities (Phase 3.5)
|
|
3
|
+
*
|
|
4
|
+
* Provides deep redaction of secrets in config output.
|
|
5
|
+
* Used by config show, export, and snapshot commands.
|
|
6
|
+
*/
|
|
7
|
+
import { isSecretRef } from './types.js';
|
|
8
|
+
import { isSecretKey } from './detection.js';
|
|
9
|
+
/** Redacted placeholder for secrets */
|
|
10
|
+
export const REDACTED = '***REDACTED***';
|
|
11
|
+
/** Redacted placeholder for secret references */
|
|
12
|
+
export const REDACTED_REF = '***SECRET_REF***';
|
|
13
|
+
const DEFAULT_OPTIONS = {
|
|
14
|
+
redactSecretKeys: true,
|
|
15
|
+
redactSecretRefs: true,
|
|
16
|
+
redactedValue: REDACTED,
|
|
17
|
+
redactedRef: REDACTED_REF,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Recursively redact secrets in a value
|
|
21
|
+
*
|
|
22
|
+
* Handles:
|
|
23
|
+
* - Secret references (dpapi:xxx, keychain:xxx)
|
|
24
|
+
* - Values for keys that match secret patterns
|
|
25
|
+
*
|
|
26
|
+
* @param value - Any JSON-serializable value
|
|
27
|
+
* @param options - Redaction options
|
|
28
|
+
* @returns Redacted value and count
|
|
29
|
+
*/
|
|
30
|
+
export function redactDeep(value, options = {}) {
|
|
31
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
32
|
+
let count = 0;
|
|
33
|
+
function processValue(val, parentKey) {
|
|
34
|
+
// Handle null/undefined
|
|
35
|
+
if (val === null || val === undefined) {
|
|
36
|
+
return val;
|
|
37
|
+
}
|
|
38
|
+
// Handle strings
|
|
39
|
+
if (typeof val === 'string') {
|
|
40
|
+
// Check if it's a secret reference
|
|
41
|
+
if (opts.redactSecretRefs && isSecretRef(val)) {
|
|
42
|
+
count++;
|
|
43
|
+
return opts.redactedRef;
|
|
44
|
+
}
|
|
45
|
+
// Check if parent key indicates a secret
|
|
46
|
+
if (opts.redactSecretKeys && parentKey && isSecretKey(parentKey)) {
|
|
47
|
+
// Don't redact empty strings or already-redacted values
|
|
48
|
+
if (val.length > 0 && val !== opts.redactedValue && val !== opts.redactedRef) {
|
|
49
|
+
count++;
|
|
50
|
+
return opts.redactedValue;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return val;
|
|
54
|
+
}
|
|
55
|
+
// Handle arrays
|
|
56
|
+
if (Array.isArray(val)) {
|
|
57
|
+
return val.map(item => processValue(item, parentKey));
|
|
58
|
+
}
|
|
59
|
+
// Handle objects
|
|
60
|
+
if (typeof val === 'object') {
|
|
61
|
+
const result = {};
|
|
62
|
+
for (const [key, v] of Object.entries(val)) {
|
|
63
|
+
result[key] = processValue(v, key);
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
// Primitives (number, boolean, etc.)
|
|
68
|
+
return val;
|
|
69
|
+
}
|
|
70
|
+
const redacted = processValue(value);
|
|
71
|
+
return { value: redacted, count };
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Redact a single value based on key and options
|
|
75
|
+
*
|
|
76
|
+
* @param key - The key name
|
|
77
|
+
* @param value - The value to potentially redact
|
|
78
|
+
* @param options - Redaction options
|
|
79
|
+
* @returns Redacted value if applicable, original otherwise
|
|
80
|
+
*/
|
|
81
|
+
export function redactValue(key, value, options = {}) {
|
|
82
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
83
|
+
// Check if it's a secret reference
|
|
84
|
+
if (opts.redactSecretRefs && isSecretRef(value)) {
|
|
85
|
+
return opts.redactedRef;
|
|
86
|
+
}
|
|
87
|
+
// Check if key indicates a secret
|
|
88
|
+
if (opts.redactSecretKeys && isSecretKey(key)) {
|
|
89
|
+
if (value.length > 0 && value !== opts.redactedValue && value !== opts.redactedRef) {
|
|
90
|
+
return opts.redactedValue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return value;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Redact env variables object
|
|
97
|
+
*
|
|
98
|
+
* @param env - Environment variables
|
|
99
|
+
* @param options - Redaction options
|
|
100
|
+
* @returns Redacted env and count
|
|
101
|
+
*/
|
|
102
|
+
export function redactEnv(env, options = {}) {
|
|
103
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
104
|
+
let count = 0;
|
|
105
|
+
const result = {};
|
|
106
|
+
for (const [key, value] of Object.entries(env)) {
|
|
107
|
+
const redacted = redactValue(key, value, opts);
|
|
108
|
+
if (redacted !== value) {
|
|
109
|
+
count++;
|
|
110
|
+
}
|
|
111
|
+
result[key] = redacted;
|
|
112
|
+
}
|
|
113
|
+
return { env: result, count };
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Create a summary of redacted values
|
|
117
|
+
*
|
|
118
|
+
* @param count - Number of values redacted
|
|
119
|
+
* @returns Human-readable summary
|
|
120
|
+
*/
|
|
121
|
+
export function redactionSummary(count) {
|
|
122
|
+
if (count === 0) {
|
|
123
|
+
return '';
|
|
124
|
+
}
|
|
125
|
+
if (count === 1) {
|
|
126
|
+
return '(1 secret redacted)';
|
|
127
|
+
}
|
|
128
|
+
return `(${count} secrets redacted)`;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Check if a value has been redacted
|
|
132
|
+
*/
|
|
133
|
+
export function isRedacted(value) {
|
|
134
|
+
return value === REDACTED || value === REDACTED_REF;
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=redaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redaction.js","sourceRoot":"","sources":["../../src/secrets/redaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed secret store (Phase 3.5)
|
|
3
|
+
*
|
|
4
|
+
* Stores encrypted secrets in ~/.proofscan/secrets.db
|
|
5
|
+
* Uses platform-specific encryption providers (DPAPI on Windows).
|
|
6
|
+
*/
|
|
7
|
+
import type { ISecretStore, IEncryptionProvider, SecretMeta, StoreSecretResult, ProviderType } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* SQLite-backed secret store
|
|
10
|
+
*/
|
|
11
|
+
export declare class SqliteSecretStore implements ISecretStore {
|
|
12
|
+
private db;
|
|
13
|
+
private provider;
|
|
14
|
+
private closed;
|
|
15
|
+
constructor(configDir?: string, provider?: IEncryptionProvider);
|
|
16
|
+
private initSchema;
|
|
17
|
+
private ensureOpen;
|
|
18
|
+
store(plaintext: string, meta?: SecretMeta): Promise<StoreSecretResult>;
|
|
19
|
+
retrieve(id: string): Promise<string | null>;
|
|
20
|
+
exists(id: string): Promise<boolean>;
|
|
21
|
+
delete(id: string): Promise<boolean>;
|
|
22
|
+
list(): Promise<string[]>;
|
|
23
|
+
getMeta(id: string): Promise<SecretMeta | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Get the provider type in use
|
|
26
|
+
*/
|
|
27
|
+
getProviderType(): ProviderType;
|
|
28
|
+
/**
|
|
29
|
+
* Get count of stored secrets
|
|
30
|
+
*/
|
|
31
|
+
count(): number;
|
|
32
|
+
close(): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Get or create the global secret store
|
|
36
|
+
*/
|
|
37
|
+
export declare function getSecretStore(configDir?: string): SqliteSecretStore;
|
|
38
|
+
/**
|
|
39
|
+
* Close the global secret store
|
|
40
|
+
*/
|
|
41
|
+
export declare function closeSecretStore(): void;
|
|
42
|
+
//# sourceMappingURL=store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/secrets/store.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EACV,YAAY,EACZ,mBAAmB,EACnB,UAAU,EAEV,iBAAiB,EACjB,YAAY,EACb,MAAM,YAAY,CAAC;AAsBpB;;GAEG;AACH,qBAAa,iBAAkB,YAAW,YAAY;IACpD,OAAO,CAAC,EAAE,CAAoB;IAC9B,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,MAAM,CAAS;gBAEX,SAAS,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,mBAAmB;IAiB9D,OAAO,CAAC,UAAU;IAUlB,OAAO,CAAC,UAAU;IAMZ,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA0BvE,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA8B5C,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAOpC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAQpC,IAAI,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAQzB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAiBrD;;OAEG;IACH,eAAe,IAAI,YAAY;IAI/B;;OAEG;IACH,KAAK,IAAI,MAAM;IAQf,KAAK,IAAI,IAAI;CAMd;AAKD;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,iBAAiB,CAKpE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAKvC"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite-backed secret store (Phase 3.5)
|
|
3
|
+
*
|
|
4
|
+
* Stores encrypted secrets in ~/.proofscan/secrets.db
|
|
5
|
+
* Uses platform-specific encryption providers (DPAPI on Windows).
|
|
6
|
+
*/
|
|
7
|
+
import Database from 'better-sqlite3';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import { mkdirSync } from 'fs';
|
|
10
|
+
import { v4 as uuidv4 } from 'uuid';
|
|
11
|
+
import { makeSecretRef } from './types.js';
|
|
12
|
+
import { getBestProvider, getProvider } from './providers/index.js';
|
|
13
|
+
import { getDefaultConfigDir } from '../utils/config-path.js';
|
|
14
|
+
/** Database schema version */
|
|
15
|
+
const SECRETS_DB_VERSION = 1;
|
|
16
|
+
/** Database schema */
|
|
17
|
+
const SECRETS_DB_SCHEMA = `
|
|
18
|
+
CREATE TABLE IF NOT EXISTS secrets (
|
|
19
|
+
id TEXT PRIMARY KEY,
|
|
20
|
+
provider TEXT NOT NULL,
|
|
21
|
+
ciphertext TEXT NOT NULL,
|
|
22
|
+
created_at TEXT NOT NULL,
|
|
23
|
+
meta_json TEXT
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
CREATE INDEX IF NOT EXISTS idx_secrets_provider ON secrets(provider);
|
|
27
|
+
CREATE INDEX IF NOT EXISTS idx_secrets_created ON secrets(created_at);
|
|
28
|
+
`;
|
|
29
|
+
/**
|
|
30
|
+
* SQLite-backed secret store
|
|
31
|
+
*/
|
|
32
|
+
export class SqliteSecretStore {
|
|
33
|
+
db;
|
|
34
|
+
provider;
|
|
35
|
+
closed = false;
|
|
36
|
+
constructor(configDir, provider) {
|
|
37
|
+
const dir = configDir || getDefaultConfigDir();
|
|
38
|
+
// Ensure directory exists
|
|
39
|
+
mkdirSync(dir, { recursive: true });
|
|
40
|
+
// Open database
|
|
41
|
+
const dbPath = join(dir, 'secrets.db');
|
|
42
|
+
this.db = new Database(dbPath);
|
|
43
|
+
// Initialize schema
|
|
44
|
+
this.initSchema();
|
|
45
|
+
// Use provided provider or get best available
|
|
46
|
+
this.provider = provider || getBestProvider();
|
|
47
|
+
}
|
|
48
|
+
initSchema() {
|
|
49
|
+
// Check version
|
|
50
|
+
const currentVersion = this.db.pragma('user_version', { simple: true });
|
|
51
|
+
if (currentVersion < SECRETS_DB_VERSION) {
|
|
52
|
+
this.db.exec(SECRETS_DB_SCHEMA);
|
|
53
|
+
this.db.pragma(`user_version = ${SECRETS_DB_VERSION}`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
ensureOpen() {
|
|
57
|
+
if (this.closed) {
|
|
58
|
+
throw new Error('SecretStore has been closed');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async store(plaintext, meta) {
|
|
62
|
+
this.ensureOpen();
|
|
63
|
+
// Generate unique ID
|
|
64
|
+
const id = uuidv4();
|
|
65
|
+
// Encrypt the plaintext
|
|
66
|
+
const ciphertext = await this.provider.encrypt(plaintext);
|
|
67
|
+
// Serialize metadata
|
|
68
|
+
const metaJson = meta ? JSON.stringify(meta) : null;
|
|
69
|
+
// Insert into database
|
|
70
|
+
const stmt = this.db.prepare(`
|
|
71
|
+
INSERT INTO secrets (id, provider, ciphertext, created_at, meta_json)
|
|
72
|
+
VALUES (?, ?, ?, ?, ?)
|
|
73
|
+
`);
|
|
74
|
+
stmt.run(id, this.provider.type, ciphertext, new Date().toISOString(), metaJson);
|
|
75
|
+
return {
|
|
76
|
+
id,
|
|
77
|
+
reference: makeSecretRef(this.provider.type, id),
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
async retrieve(id) {
|
|
81
|
+
this.ensureOpen();
|
|
82
|
+
const stmt = this.db.prepare(`
|
|
83
|
+
SELECT provider, ciphertext FROM secrets WHERE id = ?
|
|
84
|
+
`);
|
|
85
|
+
const row = stmt.get(id);
|
|
86
|
+
if (!row) {
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
// Get the appropriate provider
|
|
90
|
+
const provider = row.provider === this.provider.type
|
|
91
|
+
? this.provider
|
|
92
|
+
: getProvider(row.provider);
|
|
93
|
+
// Security: Check if provider is available on this platform
|
|
94
|
+
if (!provider.isAvailable()) {
|
|
95
|
+
throw new Error(`Secret was encrypted with '${row.provider}' which is not available on this platform. ` +
|
|
96
|
+
`This secret can only be decrypted on a system where ${row.provider} is supported.`);
|
|
97
|
+
}
|
|
98
|
+
// Decrypt and return
|
|
99
|
+
return provider.decrypt(row.ciphertext);
|
|
100
|
+
}
|
|
101
|
+
async exists(id) {
|
|
102
|
+
this.ensureOpen();
|
|
103
|
+
const stmt = this.db.prepare(`SELECT 1 FROM secrets WHERE id = ?`);
|
|
104
|
+
return stmt.get(id) !== undefined;
|
|
105
|
+
}
|
|
106
|
+
async delete(id) {
|
|
107
|
+
this.ensureOpen();
|
|
108
|
+
const stmt = this.db.prepare(`DELETE FROM secrets WHERE id = ?`);
|
|
109
|
+
const result = stmt.run(id);
|
|
110
|
+
return result.changes > 0;
|
|
111
|
+
}
|
|
112
|
+
async list() {
|
|
113
|
+
this.ensureOpen();
|
|
114
|
+
const stmt = this.db.prepare(`SELECT id FROM secrets ORDER BY created_at DESC`);
|
|
115
|
+
const rows = stmt.all();
|
|
116
|
+
return rows.map(r => r.id);
|
|
117
|
+
}
|
|
118
|
+
async getMeta(id) {
|
|
119
|
+
this.ensureOpen();
|
|
120
|
+
const stmt = this.db.prepare(`SELECT meta_json FROM secrets WHERE id = ?`);
|
|
121
|
+
const row = stmt.get(id);
|
|
122
|
+
if (!row || !row.meta_json) {
|
|
123
|
+
return null;
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
return JSON.parse(row.meta_json);
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
return null;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Get the provider type in use
|
|
134
|
+
*/
|
|
135
|
+
getProviderType() {
|
|
136
|
+
return this.provider.type;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Get count of stored secrets
|
|
140
|
+
*/
|
|
141
|
+
count() {
|
|
142
|
+
this.ensureOpen();
|
|
143
|
+
const stmt = this.db.prepare(`SELECT COUNT(*) as count FROM secrets`);
|
|
144
|
+
const row = stmt.get();
|
|
145
|
+
return row.count;
|
|
146
|
+
}
|
|
147
|
+
close() {
|
|
148
|
+
if (!this.closed) {
|
|
149
|
+
this.db.close();
|
|
150
|
+
this.closed = true;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Singleton instance
|
|
155
|
+
let secretStore = null;
|
|
156
|
+
/**
|
|
157
|
+
* Get or create the global secret store
|
|
158
|
+
*/
|
|
159
|
+
export function getSecretStore(configDir) {
|
|
160
|
+
if (!secretStore) {
|
|
161
|
+
secretStore = new SqliteSecretStore(configDir);
|
|
162
|
+
}
|
|
163
|
+
return secretStore;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Close the global secret store
|
|
167
|
+
*/
|
|
168
|
+
export function closeSecretStore() {
|
|
169
|
+
if (secretStore) {
|
|
170
|
+
secretStore.close();
|
|
171
|
+
secretStore = null;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/secrets/store.ts"],"names":[],"mappings":"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"}
|