@clef-sh/core 0.1.28 → 0.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.
- package/README.md +1 -2
- package/dist/artifact/packer.d.ts +4 -3
- package/dist/artifact/packer.d.ts.map +1 -1
- package/dist/artifact/resolve.d.ts +3 -2
- package/dist/artifact/resolve.d.ts.map +1 -1
- package/dist/compliance/run.d.ts.map +1 -1
- package/dist/diff/engine.d.ts +18 -8
- package/dist/diff/engine.d.ts.map +1 -1
- package/dist/import/index.d.ts +5 -5
- package/dist/import/index.d.ts.map +1 -1
- package/dist/index.d.mts +12 -10
- package/dist/index.d.ts +12 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1080 -838
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +1049 -794
- package/dist/index.mjs.map +4 -4
- package/dist/lint/runner.d.ts +7 -7
- package/dist/lint/runner.d.ts.map +1 -1
- package/dist/matrix/manager.d.ts +4 -16
- package/dist/matrix/manager.d.ts.map +1 -1
- package/dist/merge/driver.d.ts +2 -2
- package/dist/merge/driver.d.ts.map +1 -1
- package/dist/merge/metadata-driver.d.ts +5 -4
- package/dist/merge/metadata-driver.d.ts.map +1 -1
- package/dist/migration/backend.d.ts +10 -7
- package/dist/migration/backend.d.ts.map +1 -1
- package/dist/pack/backends/json-envelope.d.ts.map +1 -1
- package/dist/pack/types.d.ts +9 -3
- package/dist/pack/types.d.ts.map +1 -1
- package/dist/pending/metadata.d.ts +1 -3
- package/dist/pending/metadata.d.ts.map +1 -1
- package/dist/recipients/index.d.ts +4 -3
- package/dist/recipients/index.d.ts.map +1 -1
- package/dist/report/generator.d.ts +4 -3
- package/dist/report/generator.d.ts.map +1 -1
- package/dist/reset/manager.d.ts +21 -3
- package/dist/reset/manager.d.ts.map +1 -1
- package/dist/service-identity/manager.d.ts +6 -3
- package/dist/service-identity/manager.d.ts.map +1 -1
- package/dist/sops/client.d.ts +80 -55
- package/dist/sops/client.d.ts.map +1 -1
- package/dist/sops/linux-stdin-fifo.d.ts +31 -0
- package/dist/sops/linux-stdin-fifo.d.ts.map +1 -0
- package/dist/source/compose.d.ts +10 -0
- package/dist/source/compose.d.ts.map +1 -0
- package/dist/source/default-bulk.d.ts +12 -0
- package/dist/source/default-bulk.d.ts.map +1 -0
- package/dist/source/encryption-backend.d.ts +85 -0
- package/dist/source/encryption-backend.d.ts.map +1 -0
- package/dist/source/errors.d.ts +19 -0
- package/dist/source/errors.d.ts.map +1 -0
- package/dist/source/filesystem-storage-backend.d.ts +26 -0
- package/dist/source/filesystem-storage-backend.d.ts.map +1 -0
- package/dist/source/guards.d.ts +14 -0
- package/dist/source/guards.d.ts.map +1 -0
- package/dist/source/index.d.ts +10 -0
- package/dist/source/index.d.ts.map +1 -0
- package/dist/source/mock-source.d.ts +89 -0
- package/dist/source/mock-source.d.ts.map +1 -0
- package/dist/source/storage-backend.d.ts +61 -0
- package/dist/source/storage-backend.d.ts.map +1 -0
- package/dist/source/types.d.ts +212 -0
- package/dist/source/types.d.ts.map +1 -0
- package/dist/structure/manager.d.ts +17 -3
- package/dist/structure/manager.d.ts.map +1 -1
- package/dist/sync/manager.d.ts +7 -6
- package/dist/sync/manager.d.ts.map +1 -1
- package/dist/types/index.d.ts +10 -23
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/bulk/ops.d.ts +0 -57
- package/dist/bulk/ops.d.ts.map +0 -1
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SubprocessRunner } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* On Linux, libuv creates pipes for child stdio. SOPS (Go) translates
|
|
4
|
+
* `/dev/stdin` through `/proc/self/fd/0` and tries to re-open it by path,
|
|
5
|
+
* which fails with ENXIO ("no such device or address") because pipes
|
|
6
|
+
* cannot be re-opened by path.
|
|
7
|
+
*
|
|
8
|
+
* Workaround: when SopsClient asks the runner to spawn `sops` with
|
|
9
|
+
* `/dev/stdin` in the args AND content piped via the runner's stdin,
|
|
10
|
+
* substitute a Linux FIFO (named pipe). FIFOs are openable by path —
|
|
11
|
+
* the bytes still live in an in-memory kernel buffer (not on disk), so
|
|
12
|
+
* the no-plaintext-to-disk invariant is preserved.
|
|
13
|
+
*
|
|
14
|
+
* Gated on `process.platform === "linux"` and the absence of
|
|
15
|
+
* `JEST_WORKER_ID` — unit tests mock `SubprocessRunner` and never
|
|
16
|
+
* spawn a real SOPS binary, so the FIFO machinery would only add
|
|
17
|
+
* subprocess overhead with no benefit. Callers that genuinely need the
|
|
18
|
+
* workaround inside a Jest-spawned child (e.g. the CDK pack-helper
|
|
19
|
+
* subprocess) must scrub `JEST_WORKER_ID` from the child's env so this
|
|
20
|
+
* gate fires correctly.
|
|
21
|
+
*/
|
|
22
|
+
export declare function shouldUseLinuxStdinFifo(): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Wrap a `SubprocessRunner` so that any call carrying both `/dev/stdin`
|
|
25
|
+
* in `args` and a non-empty `opts.stdin` payload is rewritten to use a
|
|
26
|
+
* Linux FIFO. On platforms where the workaround isn't needed (or in
|
|
27
|
+
* unit tests), returns the input runner unchanged so the wrapper costs
|
|
28
|
+
* nothing.
|
|
29
|
+
*/
|
|
30
|
+
export declare function wrapWithLinuxStdinFifo(runner: SubprocessRunner): SubprocessRunner;
|
|
31
|
+
//# sourceMappingURL=linux-stdin-fifo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linux-stdin-fifo.d.ts","sourceRoot":"","sources":["../../src/sops/linux-stdin-fifo.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,uBAAuB,IAAI,OAAO,CAEjD;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CA4CjF"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ClefManifest } from "../types";
|
|
2
|
+
import type { Bulk, Lintable, Rotatable, SecretSource } from "./types";
|
|
3
|
+
import type { StorageBackend } from "./storage-backend";
|
|
4
|
+
import type { EncryptionBackend } from "./encryption-backend";
|
|
5
|
+
/**
|
|
6
|
+
* Build a `SecretSource & Lintable & Rotatable & Bulk` from the two
|
|
7
|
+
* orthogonal backends and the manifest.
|
|
8
|
+
*/
|
|
9
|
+
export declare function composeSecretSource(storage: StorageBackend, encryption: EncryptionBackend, manifest: ClefManifest): SecretSource & Lintable & Rotatable & Bulk;
|
|
10
|
+
//# sourceMappingURL=compose.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../../src/source/compose.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,UAAU,CAAC;AAC3D,OAAO,KAAK,EACV,IAAI,EAIJ,QAAQ,EAER,SAAS,EAET,YAAY,EACb,MAAM,SAAS,CAAC;AACjB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAqB,MAAM,sBAAsB,CAAC;AAGjF;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,cAAc,EACvB,UAAU,EAAE,iBAAiB,EAC7B,QAAQ,EAAE,YAAY,GACrB,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,IAAI,CAE5C"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Bulk, SecretSource } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* Wrap a `SecretSource` in a `Bulk` implementation that loops over
|
|
4
|
+
* `readCell` / `writeCell` / `deleteCell`. Sources whose substrate
|
|
5
|
+
* cannot batch — or that simply haven't bothered — get correct
|
|
6
|
+
* behavior for free at the cost of one round-trip per cell.
|
|
7
|
+
*
|
|
8
|
+
* Returned object satisfies `Bulk` only; combine via spread when a
|
|
9
|
+
* caller needs both the source surface and bulk methods.
|
|
10
|
+
*/
|
|
11
|
+
export declare function defaultBulk(source: SecretSource): Bulk;
|
|
12
|
+
//# sourceMappingURL=default-bulk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"default-bulk.d.ts","sourceRoot":"","sources":["../../src/source/default-bulk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAW,YAAY,EAAE,MAAM,SAAS,CAAC;AAG3D;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,IAAI,CA6CtD"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `EncryptionBackend` is the substrate-agnostic encryption contract — a
|
|
3
|
+
* peer abstraction to `StorageBackend`. It takes plaintext values and
|
|
4
|
+
* produces opaque ciphertext bytes (and the reverse), without ever
|
|
5
|
+
* touching files, paths, or storage substrate.
|
|
6
|
+
*
|
|
7
|
+
* Implementations:
|
|
8
|
+
* - `createSopsEncryptionBackend(sopsClient)` — SOPS via the bundled
|
|
9
|
+
* `sops` binary. The default and only first-party implementation.
|
|
10
|
+
* - Future: any byte-shaped encryption scheme (age-direct, libsodium,
|
|
11
|
+
* BYO). Plugin authors can ship one as `@clef-sh/encryption-<id>`.
|
|
12
|
+
*
|
|
13
|
+
* The pairing with `StorageBackend` is intentionally orthogonal:
|
|
14
|
+
*
|
|
15
|
+
* composeSecretSource(storage: StorageBackend,
|
|
16
|
+
* encryption: EncryptionBackend,
|
|
17
|
+
* manifest: ClefManifest): SecretSource
|
|
18
|
+
*
|
|
19
|
+
* Any combination of (storage, encryption) yields a working source.
|
|
20
|
+
*
|
|
21
|
+
* Plaintext discipline:
|
|
22
|
+
* - `encrypt` and `decrypt` may hold plaintext briefly in process memory
|
|
23
|
+
* while they shell out to the encryption tool. Implementations MUST
|
|
24
|
+
* NOT write plaintext to disk, log it, or transmit it over an
|
|
25
|
+
* untrusted channel.
|
|
26
|
+
* - `rotate` is plaintext-free: it transforms ciphertext to ciphertext
|
|
27
|
+
* (re-wrapping the data encryption key against an updated recipient
|
|
28
|
+
* set) without exposing values to the calling process.
|
|
29
|
+
*/
|
|
30
|
+
import type { ClefManifest, DecryptedFile, SopsMetadata } from "../types";
|
|
31
|
+
/**
|
|
32
|
+
* Per-call context. Carries the manifest (for recipients/backend
|
|
33
|
+
* resolution), the target environment (for per-env overrides), and the
|
|
34
|
+
* format hint forwarded from the `StorageBackend`.
|
|
35
|
+
*/
|
|
36
|
+
export interface EncryptionContext {
|
|
37
|
+
manifest: ClefManifest;
|
|
38
|
+
environment?: string;
|
|
39
|
+
/** Format of the ciphertext bytes — typically passed through verbatim. */
|
|
40
|
+
format: "yaml" | "json";
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Recipient changes applied during a rotation. All fields are optional;
|
|
44
|
+
* a backend may interpret only the keys it understands (e.g. a custom
|
|
45
|
+
* non-SOPS backend that ignores `addAge` if it has no concept of age).
|
|
46
|
+
*/
|
|
47
|
+
export interface RotateOptions {
|
|
48
|
+
addAge?: string;
|
|
49
|
+
rmAge?: string;
|
|
50
|
+
addKms?: string;
|
|
51
|
+
rmKms?: string;
|
|
52
|
+
addGcpKms?: string;
|
|
53
|
+
rmGcpKms?: string;
|
|
54
|
+
addAzureKv?: string;
|
|
55
|
+
rmAzureKv?: string;
|
|
56
|
+
addPgp?: string;
|
|
57
|
+
rmPgp?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface EncryptionBackend {
|
|
60
|
+
/** Stable identifier (e.g. `"sops"`). */
|
|
61
|
+
readonly id: string;
|
|
62
|
+
/** Short human-readable description, used in `clef doctor`. */
|
|
63
|
+
readonly description: string;
|
|
64
|
+
/**
|
|
65
|
+
* Encrypt a plaintext value-map into ciphertext bytes. The recipient
|
|
66
|
+
* set is derived from the manifest (and optional per-env override).
|
|
67
|
+
*/
|
|
68
|
+
encrypt(values: Record<string, string>, ctx: EncryptionContext): Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Decrypt ciphertext bytes back into a plaintext value-map plus
|
|
71
|
+
* encryption metadata (backend, recipients, last-modified, ...).
|
|
72
|
+
*/
|
|
73
|
+
decrypt(blob: string, ctx: EncryptionContext): Promise<DecryptedFile>;
|
|
74
|
+
/**
|
|
75
|
+
* Rotate the data encryption key and/or update the recipient set on
|
|
76
|
+
* an already-encrypted blob. Returns the new ciphertext. Plaintext is
|
|
77
|
+
* not exposed to the calling process.
|
|
78
|
+
*/
|
|
79
|
+
rotate(blob: string, opts: RotateOptions, ctx: EncryptionContext): Promise<string>;
|
|
80
|
+
/** Inspect ciphertext metadata without decrypting. Pure parser. */
|
|
81
|
+
getMetadata(blob: string): SopsMetadata;
|
|
82
|
+
/** Whether `blob` is well-formed encrypted output. Never throws. */
|
|
83
|
+
validateEncryption(blob: string): boolean;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=encryption-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"encryption-backend.d.ts","sourceRoot":"","sources":["../../src/source/encryption-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE1E;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0EAA0E;IAC1E,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,iBAAiB;IAChC,yCAAyC;IACzC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEjF;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;IAEtE;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnF,mEAAmE;IACnE,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;IAExC,oEAAoE;IACpE,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;CAC3C"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { ClefError } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Thrown when a CLI command or UI route requires a capability the
|
|
4
|
+
* configured `SecretSource` does not implement (e.g. running
|
|
5
|
+
* `clef rotate` against a `postgres` source that does not implement
|
|
6
|
+
* `Rotatable`).
|
|
7
|
+
*
|
|
8
|
+
* Surfaces at the command-entry boundary so users see a clean message
|
|
9
|
+
* rather than a deep stack trace from a missing method call. The
|
|
10
|
+
* `capability` field is the trait name in lower-case kebab form
|
|
11
|
+
* (`"rotate"`, `"recipients"`, `"merge"`, etc.) — matching the keys of
|
|
12
|
+
* `SourceCapabilities`.
|
|
13
|
+
*/
|
|
14
|
+
export declare class SourceCapabilityUnsupportedError extends ClefError {
|
|
15
|
+
readonly capability: string;
|
|
16
|
+
readonly sourceId: string;
|
|
17
|
+
constructor(capability: string, sourceId: string);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/source/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC;;;;;;;;;;;GAWG;AACH,qBAAa,gCAAiC,SAAQ,SAAS;aAE3C,UAAU,EAAE,MAAM;aAClB,QAAQ,EAAE,MAAM;gBADhB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM;CAQnC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ClefManifest } from "../types";
|
|
2
|
+
import type { StorageBackend } from "./storage-backend";
|
|
3
|
+
import type { CellRef, CellPendingMetadata } from "./types";
|
|
4
|
+
export declare class FilesystemStorageBackend implements StorageBackend {
|
|
5
|
+
private readonly manifest;
|
|
6
|
+
private readonly repoRoot;
|
|
7
|
+
readonly id = "filesystem";
|
|
8
|
+
readonly description = "Filesystem-backed cell storage (default substrate)";
|
|
9
|
+
constructor(manifest: ClefManifest, repoRoot: string);
|
|
10
|
+
/**
|
|
11
|
+
* Resolve a cell reference to its absolute filesystem path. Public —
|
|
12
|
+
* used by substrate-specific trait implementations.
|
|
13
|
+
*/
|
|
14
|
+
cellPath(cell: CellRef): string;
|
|
15
|
+
/** The repo root, exposed for filesystem-shaped trait implementations. */
|
|
16
|
+
getRepoRoot(): string;
|
|
17
|
+
blobFormat(cell: CellRef): "yaml" | "json";
|
|
18
|
+
readBlob(cell: CellRef): Promise<string>;
|
|
19
|
+
writeBlob(cell: CellRef, blob: string): Promise<void>;
|
|
20
|
+
deleteBlob(cell: CellRef): Promise<void>;
|
|
21
|
+
blobExists(cell: CellRef): Promise<boolean>;
|
|
22
|
+
readPendingMetadata(cell: CellRef): Promise<CellPendingMetadata>;
|
|
23
|
+
writePendingMetadata(cell: CellRef, meta: CellPendingMetadata): Promise<void>;
|
|
24
|
+
private sidecarPath;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=filesystem-storage-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filesystem-storage-backend.d.ts","sourceRoot":"","sources":["../../src/source/filesystem-storage-backend.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAG5D,qBAAa,wBAAyB,YAAW,cAAc;IAK3D,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAL3B,QAAQ,CAAC,EAAE,gBAAgB;IAC3B,QAAQ,CAAC,WAAW,wDAAwD;gBAGzD,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM;IAGnC;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM;IAO/B,0EAA0E;IAC1E,WAAW,IAAI,MAAM;IAIrB,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM;IAIpC,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAKxC,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAuBrD,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAcxC,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAI3C,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIhE,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IAInF,OAAO,CAAC,WAAW;CAKpB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Bulk, Lintable, MergeAware, Migratable, RecipientManaged, Rotatable, SecretSource, SourceCapabilities, Structural } from "./types";
|
|
2
|
+
export declare function isLintable(s: SecretSource): s is SecretSource & Lintable;
|
|
3
|
+
export declare function isRotatable(s: SecretSource): s is SecretSource & Rotatable;
|
|
4
|
+
export declare function isRecipientManaged(s: SecretSource): s is SecretSource & RecipientManaged;
|
|
5
|
+
export declare function isMergeAware(s: SecretSource): s is SecretSource & MergeAware;
|
|
6
|
+
export declare function isMigratable(s: SecretSource): s is SecretSource & Migratable;
|
|
7
|
+
export declare function isBulk(s: SecretSource): s is SecretSource & Bulk;
|
|
8
|
+
export declare function isStructural(s: SecretSource): s is SecretSource & Structural;
|
|
9
|
+
/**
|
|
10
|
+
* Build a boolean capability descriptor for the source. Used by the UI
|
|
11
|
+
* server's `GET /api/capabilities` endpoint and by `clef doctor` output.
|
|
12
|
+
*/
|
|
13
|
+
export declare function describeCapabilities(s: SecretSource): SourceCapabilities;
|
|
14
|
+
//# sourceMappingURL=guards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../../src/source/guards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EACJ,QAAQ,EACR,UAAU,EACV,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,UAAU,EACX,MAAM,SAAS,CAAC;AAqBjB,wBAAgB,UAAU,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,QAAQ,CAExE;AAED,wBAAgB,WAAW,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,SAAS,CAE1E;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,gBAAgB,CAExF;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,UAAU,CAE5E;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,UAAU,CAE5E;AAED,wBAAgB,MAAM,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,IAAI,CAEhE;AAED,wBAAgB,YAAY,CAAC,CAAC,EAAE,YAAY,GAAG,CAAC,IAAI,YAAY,GAAG,UAAU,CAO5E;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,YAAY,GAAG,kBAAkB,CAUxE"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { AddRecipientRequest, Bulk, CellData, CellPendingMetadata, CellRef, Lintable, MergeAware, Migratable, RecipientDriftResult, RecipientManaged, RemoveRecipientRequest, Rotatable, SecretSource, SourceCapabilities, Structural, } from "./types";
|
|
2
|
+
export { describeCapabilities, isBulk, isLintable, isMergeAware, isMigratable, isRecipientManaged, isRotatable, isStructural, } from "./guards";
|
|
3
|
+
export { defaultBulk } from "./default-bulk";
|
|
4
|
+
export { SourceCapabilityUnsupportedError } from "./errors";
|
|
5
|
+
export { MockSecretSource } from "./mock-source";
|
|
6
|
+
export type { StorageBackend } from "./storage-backend";
|
|
7
|
+
export { FilesystemStorageBackend } from "./filesystem-storage-backend";
|
|
8
|
+
export type { EncryptionBackend, EncryptionContext, RotateOptions } from "./encryption-backend";
|
|
9
|
+
export { composeSecretSource } from "./compose";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/source/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,mBAAmB,EACnB,IAAI,EACJ,QAAQ,EACR,mBAAmB,EACnB,OAAO,EACP,QAAQ,EACR,UAAU,EACV,UAAU,EACV,oBAAoB,EACpB,gBAAgB,EAChB,sBAAsB,EACtB,SAAS,EACT,YAAY,EACZ,kBAAkB,EAClB,UAAU,GACX,MAAM,SAAS,CAAC;AAEjB,OAAO,EACL,oBAAoB,EACpB,MAAM,EACN,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,YAAY,GACb,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,gCAAgC,EAAE,MAAM,UAAU,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAChG,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory test fixture used by CLI command tests and any future
|
|
3
|
+
* consumer that needs to exercise source-shaped code paths without a
|
|
4
|
+
* real git+SOPS substrate. Production code must NOT depend on this
|
|
5
|
+
* file — it is exported under `@clef-sh/core` solely so workspace
|
|
6
|
+
* tests can import it.
|
|
7
|
+
*
|
|
8
|
+
* Capability dialing: pass `capabilities: { lint: false, ... }` to
|
|
9
|
+
* construct a source missing specific traits, so tests can assert
|
|
10
|
+
* `SourceCapabilityUnsupportedError` paths (Phase 5+).
|
|
11
|
+
*/
|
|
12
|
+
import type { AddNamespaceOptions, AddEnvironmentOptions, AddRecipientRequest, CellPendingMetadata, CellRef, CellData, RecipientDriftResult, RemoveRecipientRequest, RotateOptions, SecretSource } from "./types";
|
|
13
|
+
import type { ClefManifest, SopsMetadata } from "../types";
|
|
14
|
+
import type { Recipient, RecipientsResult } from "../recipients";
|
|
15
|
+
import type { MigrationOptions, MigrationResult, MigrationTarget } from "../migration/backend";
|
|
16
|
+
import type { MergeResult } from "../merge/driver";
|
|
17
|
+
interface MockCapabilityToggles {
|
|
18
|
+
lint?: boolean;
|
|
19
|
+
rotate?: boolean;
|
|
20
|
+
recipients?: boolean;
|
|
21
|
+
merge?: boolean;
|
|
22
|
+
migrate?: boolean;
|
|
23
|
+
bulk?: boolean;
|
|
24
|
+
structural?: boolean;
|
|
25
|
+
}
|
|
26
|
+
interface MockSecretSourceOptions {
|
|
27
|
+
id?: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
/** Pre-populated cell values keyed by `${namespace}/${environment}`. */
|
|
30
|
+
cells?: Record<string, Record<string, string>>;
|
|
31
|
+
/** Default recipients populated into every read cell's metadata. */
|
|
32
|
+
recipients?: string[];
|
|
33
|
+
/** Capability toggles (default: all true). */
|
|
34
|
+
capabilities?: MockCapabilityToggles;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* In-memory `SecretSource` implementing every trait by default. Toggle
|
|
38
|
+
* capabilities off via the `capabilities` constructor option to
|
|
39
|
+
* simulate a source that does not support a given feature.
|
|
40
|
+
*
|
|
41
|
+
* The `_disabled*` private fields exist because TypeScript type guards
|
|
42
|
+
* detect trait support by method presence. To "disable" a capability
|
|
43
|
+
* the corresponding methods are simply not defined on the instance —
|
|
44
|
+
* the public class definition declares them, but the constructor
|
|
45
|
+
* deletes them when toggled off.
|
|
46
|
+
*/
|
|
47
|
+
export declare class MockSecretSource implements SecretSource {
|
|
48
|
+
readonly id: string;
|
|
49
|
+
readonly description: string;
|
|
50
|
+
private readonly cells;
|
|
51
|
+
private readonly pending;
|
|
52
|
+
private readonly recipients;
|
|
53
|
+
constructor(options?: MockSecretSourceOptions);
|
|
54
|
+
readCell(cell: CellRef): Promise<CellData>;
|
|
55
|
+
writeCell(cell: CellRef, values: Record<string, string>): Promise<void>;
|
|
56
|
+
deleteCell(cell: CellRef): Promise<void>;
|
|
57
|
+
cellExists(cell: CellRef): Promise<boolean>;
|
|
58
|
+
listKeys(cell: CellRef): Promise<string[]>;
|
|
59
|
+
getCellMetadata(_cell: CellRef): Promise<SopsMetadata>;
|
|
60
|
+
scaffoldCell(cell: CellRef, _manifest: ClefManifest): Promise<void>;
|
|
61
|
+
getPendingMetadata(cell: CellRef): Promise<CellPendingMetadata>;
|
|
62
|
+
markPending(cell: CellRef, keys: string[], setBy: string): Promise<void>;
|
|
63
|
+
markResolved(cell: CellRef, keys: string[]): Promise<void>;
|
|
64
|
+
recordRotation(cell: CellRef, keys: string[], rotatedBy: string): Promise<void>;
|
|
65
|
+
removeRotation(cell: CellRef, keys: string[]): Promise<void>;
|
|
66
|
+
validateEncryption(cell: CellRef): Promise<boolean>;
|
|
67
|
+
checkRecipientDrift(_cell: CellRef, expected: string[]): Promise<RecipientDriftResult>;
|
|
68
|
+
rotate(_cell: CellRef, _opts: RotateOptions): Promise<void>;
|
|
69
|
+
listRecipients(_manifest: ClefManifest, _environment?: string): Promise<Recipient[]>;
|
|
70
|
+
addRecipient(req: AddRecipientRequest): Promise<RecipientsResult>;
|
|
71
|
+
removeRecipient(req: RemoveRecipientRequest): Promise<RecipientsResult>;
|
|
72
|
+
mergeCells(_base: CellRef, _ours: CellRef, _theirs: CellRef): Promise<MergeResult>;
|
|
73
|
+
installMergeDriver(_repoRoot: string): Promise<void>;
|
|
74
|
+
uninstallMergeDriver(_repoRoot: string): Promise<void>;
|
|
75
|
+
installHooks(_repoRoot: string): Promise<void>;
|
|
76
|
+
uninstallHooks(_repoRoot: string): Promise<void>;
|
|
77
|
+
migrateBackend(_target: MigrationTarget, _opts: MigrationOptions): Promise<MigrationResult>;
|
|
78
|
+
bulkSet(namespace: string, key: string, valuesByEnv: Record<string, string>, manifest: ClefManifest): Promise<void>;
|
|
79
|
+
bulkDelete(namespace: string, key: string, manifest: ClefManifest): Promise<void>;
|
|
80
|
+
copyValue(key: string, from: CellRef, to: CellRef, manifest: ClefManifest): Promise<void>;
|
|
81
|
+
addNamespace(_name: string, _opts: AddNamespaceOptions, _manifest: ClefManifest): Promise<void>;
|
|
82
|
+
removeNamespace(name: string, _manifest: ClefManifest): Promise<void>;
|
|
83
|
+
renameNamespace(from: string, to: string, _manifest: ClefManifest): Promise<void>;
|
|
84
|
+
addEnvironment(_name: string, _opts: AddEnvironmentOptions, _manifest: ClefManifest): Promise<void>;
|
|
85
|
+
removeEnvironment(name: string, _manifest: ClefManifest): Promise<void>;
|
|
86
|
+
renameEnvironment(from: string, to: string, _manifest: ClefManifest): Promise<void>;
|
|
87
|
+
}
|
|
88
|
+
export {};
|
|
89
|
+
//# sourceMappingURL=mock-source.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mock-source.d.ts","sourceRoot":"","sources":["../../src/source/mock-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `StorageBackend` is the substrate-level plugin-author surface for *where*
|
|
3
|
+
* ciphertext bytes live. It is one of two orthogonal abstractions composed
|
|
4
|
+
* into a `SecretSource`:
|
|
5
|
+
*
|
|
6
|
+
* - `StorageBackend` — substrate (filesystem, postgres, S3, ...)
|
|
7
|
+
* - `EncryptionBackend` — encryption (SOPS, age-direct, custom, ...)
|
|
8
|
+
*
|
|
9
|
+
* Both vary independently. Any combination — `(filesystem, sops)`,
|
|
10
|
+
* `(postgres, sops)`, `(filesystem, custom)`, `(postgres, custom)` —
|
|
11
|
+
* produces a working `SecretSource` via `composeSecretSource(storage,
|
|
12
|
+
* encryption, manifest)`.
|
|
13
|
+
*
|
|
14
|
+
* Implementations have **zero** knowledge of encryption, recipients, KMS,
|
|
15
|
+
* or age. They store and retrieve opaque bytes by `CellRef` and a small
|
|
16
|
+
* metadata sidecar; plugin authors never re-implement encryption.
|
|
17
|
+
*
|
|
18
|
+
* Format of the bytes:
|
|
19
|
+
* - Whatever the paired `EncryptionBackend` produces and consumes
|
|
20
|
+
* (SOPS YAML/JSON for `sops`; could be anything for a custom backend).
|
|
21
|
+
* - The `StorageBackend` does not parse the bytes; it stores and
|
|
22
|
+
* retrieves them verbatim.
|
|
23
|
+
*
|
|
24
|
+
* Atomicity:
|
|
25
|
+
* - `writeBlob` MUST be atomic from the caller's perspective. A torn
|
|
26
|
+
* write would leave the cell in an undecryptable state. Filesystem
|
|
27
|
+
* impls use temp-file + rename; database impls use a transaction.
|
|
28
|
+
*/
|
|
29
|
+
import type { CellRef, CellPendingMetadata } from "./types";
|
|
30
|
+
export interface StorageBackend {
|
|
31
|
+
/** Stable identifier for diagnostic output (e.g. `"filesystem"`, `"postgres"`). */
|
|
32
|
+
readonly id: string;
|
|
33
|
+
/** Short human-readable description, used in `clef doctor`. */
|
|
34
|
+
readonly description: string;
|
|
35
|
+
/**
|
|
36
|
+
* Read the cell's ciphertext bytes. Throws if the cell does not exist —
|
|
37
|
+
* callers should use `blobExists` first when absence is a valid state.
|
|
38
|
+
*/
|
|
39
|
+
readBlob(cell: CellRef): Promise<string>;
|
|
40
|
+
/** Atomically replace the cell's ciphertext bytes. Idempotent. */
|
|
41
|
+
writeBlob(cell: CellRef, blob: string): Promise<void>;
|
|
42
|
+
/** Remove the cell's blob. No-op if it does not exist. */
|
|
43
|
+
deleteBlob(cell: CellRef): Promise<void>;
|
|
44
|
+
/** Whether the cell currently has stored ciphertext. */
|
|
45
|
+
blobExists(cell: CellRef): Promise<boolean>;
|
|
46
|
+
/**
|
|
47
|
+
* Format hint for the cell's bytes. Forwarded to the paired
|
|
48
|
+
* `EncryptionBackend` so it can pick the right input/output type. The
|
|
49
|
+
* filesystem substrate derives this from the file extension; other
|
|
50
|
+
* substrates pick a fixed format.
|
|
51
|
+
*/
|
|
52
|
+
blobFormat(cell: CellRef): "yaml" | "json";
|
|
53
|
+
/**
|
|
54
|
+
* Read pending + rotation metadata for the cell. Returns an empty
|
|
55
|
+
* record when no metadata exists. Never throws on missing.
|
|
56
|
+
*/
|
|
57
|
+
readPendingMetadata(cell: CellRef): Promise<CellPendingMetadata>;
|
|
58
|
+
/** Atomically replace the cell's pending + rotation metadata. */
|
|
59
|
+
writePendingMetadata(cell: CellRef, meta: CellPendingMetadata): Promise<void>;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=storage-backend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-backend.d.ts","sourceRoot":"","sources":["../../src/source/storage-backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE5D,MAAM,WAAW,cAAc;IAC7B,mFAAmF;IACnF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,+DAA+D;IAC/D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzC,kEAAkE;IAClE,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtD,0DAA0D;IAC1D,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzC,wDAAwD;IACxD,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAE5C;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IAE3C;;;OAGG;IACH,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAC;IAEjE,iEAAiE;IACjE,oBAAoB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/E"}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `SecretSource` is the high-level cell-storage seam consumed by every
|
|
3
|
+
* non-source-specific consumer (CLI commands, UI server, pack backends).
|
|
4
|
+
* Methods take and return plaintext at this boundary; encryption is a
|
|
5
|
+
* lower-layer concern that does not appear in this contract.
|
|
6
|
+
*
|
|
7
|
+
* Architecture (introduced in Phase 2):
|
|
8
|
+
*
|
|
9
|
+
* ┌─────────────────────────────────────────────────────┐
|
|
10
|
+
* │ SecretSource plaintext cells, what consumers see │
|
|
11
|
+
* ├─────────────────────────────────────────────────────┤
|
|
12
|
+
* │ SopsClient uniform encryption (KMS/age via │
|
|
13
|
+
* │ the SOPS subprocess) │
|
|
14
|
+
* ├─────────────────────────────────────────────────────┤
|
|
15
|
+
* │ BlobStore opaque ciphertext bytes by CellRef │
|
|
16
|
+
* └─────────────────────────────────────────────────────┘
|
|
17
|
+
*
|
|
18
|
+
* The bundled `GitSopsSource` is composed from `FilesystemBlobStore +
|
|
19
|
+
* SopsClient + manifest`. A future third-party source plugs in by
|
|
20
|
+
* implementing `BlobStore` (a small, encryption-free interface) — the
|
|
21
|
+
* encryption layer is provided uniformly by clef. Plugin authors do
|
|
22
|
+
* not implement encryption primitives.
|
|
23
|
+
*
|
|
24
|
+
* The optional capability traits (`Lintable`, `Rotatable`, etc.)
|
|
25
|
+
* declare functionality some sources can offer and others cannot.
|
|
26
|
+
* SOPS-backed traits (lint/rotate/recipients/migrate) are uniform
|
|
27
|
+
* across every source because they live at the SopsClient layer.
|
|
28
|
+
* Substrate-shaped traits (`MergeAware`, `Structural`) are decided by
|
|
29
|
+
* the BlobStore. Consumers use the type guards in `./guards` for
|
|
30
|
+
* runtime detection; CLI commands and UI routes that require an
|
|
31
|
+
* unsupported capability fail fast with
|
|
32
|
+
* `SourceCapabilityUnsupportedError` (see `./errors`).
|
|
33
|
+
*/
|
|
34
|
+
import type { ClefManifest, SopsMetadata } from "../types";
|
|
35
|
+
import type { Recipient, RecipientsResult } from "../recipients";
|
|
36
|
+
import type { MigrationOptions, MigrationResult, MigrationTarget } from "../migration/backend";
|
|
37
|
+
import type { MergeResult } from "../merge/driver";
|
|
38
|
+
import type { CellMetadata as PendingCellMetadata } from "../pending/metadata";
|
|
39
|
+
import type { AddNamespaceOptions, AddEnvironmentOptions } from "../structure/manager";
|
|
40
|
+
import type { RotateOptions } from "./encryption-backend";
|
|
41
|
+
export type { RotateOptions };
|
|
42
|
+
/** Identifies a cell in the namespace × environment matrix. */
|
|
43
|
+
export interface CellRef {
|
|
44
|
+
namespace: string;
|
|
45
|
+
environment: string;
|
|
46
|
+
}
|
|
47
|
+
/** Result of decrypting / loading a cell's contents. */
|
|
48
|
+
export interface CellData {
|
|
49
|
+
values: Record<string, string>;
|
|
50
|
+
/**
|
|
51
|
+
* Source-reported metadata. For `git-sops` this carries the SOPS
|
|
52
|
+
* envelope fields (recipients, lastModified, backend, version).
|
|
53
|
+
* Sources with no native equivalent populate sensible defaults.
|
|
54
|
+
*/
|
|
55
|
+
metadata: SopsMetadata;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Pending and rotation metadata for a cell. Mirrors the existing
|
|
59
|
+
* `.clef-meta.yaml` data model so the only thing that changes is *where*
|
|
60
|
+
* the metadata lives — file sidecar (git-sops) vs. database row
|
|
61
|
+
* (postgres) etc.
|
|
62
|
+
*/
|
|
63
|
+
export type CellPendingMetadata = PendingCellMetadata;
|
|
64
|
+
/**
|
|
65
|
+
* Boolean capability descriptor returned by `describeCapabilities` and
|
|
66
|
+
* surfaced to UI clients via `GET /api/capabilities`. Field names match
|
|
67
|
+
* the trait identifier so adding a new trait means adding one boolean.
|
|
68
|
+
*/
|
|
69
|
+
export interface SourceCapabilities {
|
|
70
|
+
lint: boolean;
|
|
71
|
+
rotate: boolean;
|
|
72
|
+
recipients: boolean;
|
|
73
|
+
merge: boolean;
|
|
74
|
+
migrate: boolean;
|
|
75
|
+
bulk: boolean;
|
|
76
|
+
structural: boolean;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Core contract every source must implement. Operations are cell-level
|
|
80
|
+
* — callers never need to know about file paths, table names, or any
|
|
81
|
+
* other substrate detail.
|
|
82
|
+
*
|
|
83
|
+
* Methods throw `ClefError` (or one of its subclasses such as
|
|
84
|
+
* `SopsDecryptionError` / `SopsKeyNotFoundError`) on failure. Sources
|
|
85
|
+
* are expected to translate substrate-specific errors into the Clef
|
|
86
|
+
* hierarchy so CLI/UI consumers can render uniform error messages.
|
|
87
|
+
*/
|
|
88
|
+
export interface SecretSource {
|
|
89
|
+
/** Stable source identifier (e.g. `"git-sops"`, `"postgres"`). */
|
|
90
|
+
readonly id: string;
|
|
91
|
+
/** Short human-readable description, used in `clef doctor` output. */
|
|
92
|
+
readonly description: string;
|
|
93
|
+
/** Decrypt / load the cell's values and metadata. */
|
|
94
|
+
readCell(cell: CellRef): Promise<CellData>;
|
|
95
|
+
/**
|
|
96
|
+
* Replace the cell's values atomically. Implementations must ensure
|
|
97
|
+
* a failure mid-write does not leave partial values visible.
|
|
98
|
+
*/
|
|
99
|
+
writeCell(cell: CellRef, values: Record<string, string>): Promise<void>;
|
|
100
|
+
/** Remove the cell entirely (or its scaffolded equivalent). */
|
|
101
|
+
deleteCell(cell: CellRef): Promise<void>;
|
|
102
|
+
/** Whether the cell currently has stored data. */
|
|
103
|
+
cellExists(cell: CellRef): Promise<boolean>;
|
|
104
|
+
/**
|
|
105
|
+
* List the keys present in the cell. Sources that can answer this
|
|
106
|
+
* without decrypting (git-sops reads `data.*` keys from the SOPS
|
|
107
|
+
* file) should do so for performance; otherwise a default
|
|
108
|
+
* implementation can decrypt and return `Object.keys`.
|
|
109
|
+
*/
|
|
110
|
+
listKeys(cell: CellRef): Promise<string[]>;
|
|
111
|
+
/** Read source-reported metadata without loading values. */
|
|
112
|
+
getCellMetadata(cell: CellRef): Promise<SopsMetadata>;
|
|
113
|
+
/**
|
|
114
|
+
* Create a new (or empty) cell consistent with the manifest's
|
|
115
|
+
* declared recipients/backend for this environment. Idempotent.
|
|
116
|
+
*/
|
|
117
|
+
scaffoldCell(cell: CellRef, manifest: ClefManifest): Promise<void>;
|
|
118
|
+
/** Pending + rotation metadata. */
|
|
119
|
+
getPendingMetadata(cell: CellRef): Promise<CellPendingMetadata>;
|
|
120
|
+
markPending(cell: CellRef, keys: string[], setBy: string): Promise<void>;
|
|
121
|
+
markResolved(cell: CellRef, keys: string[]): Promise<void>;
|
|
122
|
+
recordRotation(cell: CellRef, keys: string[], rotatedBy: string): Promise<void>;
|
|
123
|
+
removeRotation(cell: CellRef, keys: string[]): Promise<void>;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Source-specific lint checks. Portable matrix-completeness lint runs
|
|
127
|
+
* over every source via the core interface and is *not* part of this
|
|
128
|
+
* trait — only checks that depend on the substrate (e.g. SOPS envelope
|
|
129
|
+
* integrity, recipient drift) live here.
|
|
130
|
+
*/
|
|
131
|
+
export interface Lintable {
|
|
132
|
+
/** Whether the cell has valid encryption envelope metadata. */
|
|
133
|
+
validateEncryption(cell: CellRef): Promise<boolean>;
|
|
134
|
+
/** Compare the cell's actual recipients against the expected set. */
|
|
135
|
+
checkRecipientDrift(cell: CellRef, expected: string[]): Promise<RecipientDriftResult>;
|
|
136
|
+
}
|
|
137
|
+
/** Result of `Lintable.checkRecipientDrift`. */
|
|
138
|
+
export interface RecipientDriftResult {
|
|
139
|
+
/** Recipients expected by the manifest but absent from the cell. */
|
|
140
|
+
missing: string[];
|
|
141
|
+
/** Recipients present on the cell but not in the manifest. */
|
|
142
|
+
unexpected: string[];
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Re-key a cell: rotate the data encryption key and/or update the
|
|
146
|
+
* recipient set without exposing plaintext to the calling process. The
|
|
147
|
+
* `RotateOptions` shape mirrors the substrate-level `EncryptionBackend`
|
|
148
|
+
* — at the SOPS layer that means add/remove for any of age, AWS KMS,
|
|
149
|
+
* GCP KMS, Azure KV, PGP. Backends interpret only the keys they
|
|
150
|
+
* understand.
|
|
151
|
+
*/
|
|
152
|
+
export interface Rotatable {
|
|
153
|
+
rotate(cell: CellRef, opts: RotateOptions): Promise<void>;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Manifest-level recipient management. `add` and `remove` mutate both
|
|
157
|
+
* the manifest declaration and re-encrypt every affected cell — the
|
|
158
|
+
* trait bundles these because list/add/remove are useless apart.
|
|
159
|
+
*/
|
|
160
|
+
export interface RecipientManaged {
|
|
161
|
+
listRecipients(manifest: ClefManifest, environment?: string): Promise<Recipient[]>;
|
|
162
|
+
addRecipient(req: AddRecipientRequest): Promise<RecipientsResult>;
|
|
163
|
+
removeRecipient(req: RemoveRecipientRequest): Promise<RecipientsResult>;
|
|
164
|
+
}
|
|
165
|
+
export interface AddRecipientRequest {
|
|
166
|
+
key: string;
|
|
167
|
+
label?: string;
|
|
168
|
+
environment?: string;
|
|
169
|
+
manifest: ClefManifest;
|
|
170
|
+
}
|
|
171
|
+
export interface RemoveRecipientRequest {
|
|
172
|
+
key: string;
|
|
173
|
+
environment?: string;
|
|
174
|
+
manifest: ClefManifest;
|
|
175
|
+
}
|
|
176
|
+
/** Three-way merge + git driver/hook installation. */
|
|
177
|
+
export interface MergeAware {
|
|
178
|
+
mergeCells(base: CellRef, ours: CellRef, theirs: CellRef): Promise<MergeResult>;
|
|
179
|
+
installMergeDriver(repoRoot: string): Promise<void>;
|
|
180
|
+
uninstallMergeDriver(repoRoot: string): Promise<void>;
|
|
181
|
+
installHooks(repoRoot: string): Promise<void>;
|
|
182
|
+
uninstallHooks(repoRoot: string): Promise<void>;
|
|
183
|
+
}
|
|
184
|
+
/** Re-encrypt every cell to a new SOPS backend (e.g. age → awskms). */
|
|
185
|
+
export interface Migratable {
|
|
186
|
+
migrateBackend(target: MigrationTarget, opts: MigrationOptions): Promise<MigrationResult>;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Batch operations across the matrix. Sources that can do these in a
|
|
190
|
+
* single round-trip (e.g. one SQL transaction) should implement the
|
|
191
|
+
* trait directly; otherwise consumers wrap a `SecretSource` in
|
|
192
|
+
* `defaultBulk` for a correct-but-slow looped fallback.
|
|
193
|
+
*/
|
|
194
|
+
export interface Bulk {
|
|
195
|
+
bulkSet(namespace: string, key: string, valuesByEnv: Record<string, string>, manifest: ClefManifest): Promise<void>;
|
|
196
|
+
bulkDelete(namespace: string, key: string, manifest: ClefManifest): Promise<void>;
|
|
197
|
+
copyValue(key: string, from: CellRef, to: CellRef, manifest: ClefManifest): Promise<void>;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Namespace + environment CRUD. On a file-based source this cascades
|
|
201
|
+
* to file/folder renames; on a DB source it's a metadata table update.
|
|
202
|
+
*/
|
|
203
|
+
export interface Structural {
|
|
204
|
+
addNamespace(name: string, opts: AddNamespaceOptions, manifest: ClefManifest): Promise<void>;
|
|
205
|
+
removeNamespace(name: string, manifest: ClefManifest): Promise<void>;
|
|
206
|
+
renameNamespace(from: string, to: string, manifest: ClefManifest): Promise<void>;
|
|
207
|
+
addEnvironment(name: string, opts: AddEnvironmentOptions, manifest: ClefManifest): Promise<void>;
|
|
208
|
+
removeEnvironment(name: string, manifest: ClefManifest): Promise<void>;
|
|
209
|
+
renameEnvironment(from: string, to: string, manifest: ClefManifest): Promise<void>;
|
|
210
|
+
}
|
|
211
|
+
export type { AddNamespaceOptions, AddEnvironmentOptions };
|
|
212
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/source/types.ts"],"names":[],"mappings":"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"}
|