@shipfox/api-secrets 2.0.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/.turbo/turbo-build.log +2 -0
- package/.turbo/turbo-type$colon$emit.log +1 -0
- package/.turbo/turbo-type.log +1 -0
- package/CHANGELOG.md +116 -0
- package/LICENSE +21 -0
- package/README.md +207 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +38 -0
- package/dist/config.js.map +1 -0
- package/dist/core/crypto.d.ts +25 -0
- package/dist/core/crypto.d.ts.map +1 -0
- package/dist/core/crypto.js +85 -0
- package/dist/core/crypto.js.map +1 -0
- package/dist/core/dek-manager.d.ts +16 -0
- package/dist/core/dek-manager.d.ts.map +1 -0
- package/dist/core/dek-manager.js +85 -0
- package/dist/core/dek-manager.js.map +1 -0
- package/dist/core/errors.d.ts +53 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +86 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/fingerprint.d.ts +2 -0
- package/dist/core/fingerprint.d.ts.map +1 -0
- package/dist/core/fingerprint.js +9 -0
- package/dist/core/fingerprint.js.map +1 -0
- package/dist/core/index.d.ts +30 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +97 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/key-provider.d.ts +17 -0
- package/dist/core/key-provider.d.ts.map +1 -0
- package/dist/core/key-provider.js +45 -0
- package/dist/core/key-provider.js.map +1 -0
- package/dist/core/local-secret-store.d.ts +19 -0
- package/dist/core/local-secret-store.d.ts.map +1 -0
- package/dist/core/local-secret-store.js +40 -0
- package/dist/core/local-secret-store.js.map +1 -0
- package/dist/core/management.d.ts +37 -0
- package/dist/core/management.d.ts.map +1 -0
- package/dist/core/management.js +403 -0
- package/dist/core/management.js.map +1 -0
- package/dist/core/rotate-kek.d.ts +10 -0
- package/dist/core/rotate-kek.d.ts.map +1 -0
- package/dist/core/rotate-kek.js +94 -0
- package/dist/core/rotate-kek.js.map +1 -0
- package/dist/core/secret-store.d.ts +33 -0
- package/dist/core/secret-store.d.ts.map +1 -0
- package/dist/core/secret-store.js +209 -0
- package/dist/core/secret-store.js.map +1 -0
- package/dist/core/store-resolver.d.ts +18 -0
- package/dist/core/store-resolver.d.ts.map +1 -0
- package/dist/core/store-resolver.js +10 -0
- package/dist/core/store-resolver.js.map +1 -0
- package/dist/core/store-validation.d.ts +11 -0
- package/dist/core/store-validation.d.ts.map +1 -0
- package/dist/core/store-validation.js +30 -0
- package/dist/core/store-validation.js.map +1 -0
- package/dist/core/value-cipher.d.ts +10 -0
- package/dist/core/value-cipher.d.ts.map +1 -0
- package/dist/core/value-cipher.js +22 -0
- package/dist/core/value-cipher.js.map +1 -0
- package/dist/core/variable-store.d.ts +24 -0
- package/dist/core/variable-store.d.ts.map +1 -0
- package/dist/core/variable-store.js +194 -0
- package/dist/core/variable-store.js.map +1 -0
- package/dist/db/cap.d.ts +8 -0
- package/dist/db/cap.d.ts.map +1 -0
- package/dist/db/cap.js +39 -0
- package/dist/db/cap.js.map +1 -0
- package/dist/db/data-keys.d.ts +24 -0
- package/dist/db/data-keys.d.ts.map +1 -0
- package/dist/db/data-keys.js +61 -0
- package/dist/db/data-keys.js.map +1 -0
- package/dist/db/db.d.ts +1254 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +24 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/index.d.ts +13 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +15 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/management.d.ts +50 -0
- package/dist/db/management.d.ts.map +1 -0
- package/dist/db/management.js +127 -0
- package/dist/db/management.js.map +1 -0
- package/dist/db/schema/common.d.ts +3 -0
- package/dist/db/schema/common.d.ts.map +1 -0
- package/dist/db/schema/common.js +8 -0
- package/dist/db/schema/common.js.map +1 -0
- package/dist/db/schema/data-keys.d.ts +103 -0
- package/dist/db/schema/data-keys.d.ts.map +1 -0
- package/dist/db/schema/data-keys.js +24 -0
- package/dist/db/schema/data-keys.js.map +1 -0
- package/dist/db/schema/outbox.d.ts +195 -0
- package/dist/db/schema/outbox.d.ts.map +1 -0
- package/dist/db/schema/outbox.js +5 -0
- package/dist/db/schema/outbox.js.map +1 -0
- package/dist/db/schema/values.d.ts +193 -0
- package/dist/db/schema/values.d.ts.map +1 -0
- package/dist/db/schema/values.js +43 -0
- package/dist/db/schema/values.js.map +1 -0
- package/dist/db/schema/variables.d.ts +175 -0
- package/dist/db/schema/variables.d.ts.map +1 -0
- package/dist/db/schema/variables.js +41 -0
- package/dist/db/schema/variables.js.map +1 -0
- package/dist/db/scope.d.ts +20 -0
- package/dist/db/scope.d.ts.map +1 -0
- package/dist/db/scope.js +19 -0
- package/dist/db/scope.js.map +1 -0
- package/dist/db/values.d.ts +33 -0
- package/dist/db/values.d.ts.map +1 -0
- package/dist/db/values.js +119 -0
- package/dist/db/values.js.map +1 -0
- package/dist/db/variables.d.ts +32 -0
- package/dist/db/variables.d.ts.map +1 -0
- package/dist/db/variables.js +117 -0
- package/dist/db/variables.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +28 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics/index.d.ts +3 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +4 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/instance.d.ts +39 -0
- package/dist/metrics/instance.d.ts.map +1 -0
- package/dist/metrics/instance.js +151 -0
- package/dist/metrics/instance.js.map +1 -0
- package/dist/metrics/service.d.ts +2 -0
- package/dist/metrics/service.d.ts.map +1 -0
- package/dist/metrics/service.js +21 -0
- package/dist/metrics/service.js.map +1 -0
- package/dist/presentation/dto/index.d.ts +2 -0
- package/dist/presentation/dto/index.d.ts.map +1 -0
- package/dist/presentation/dto/index.js +3 -0
- package/dist/presentation/dto/index.js.map +1 -0
- package/dist/presentation/dto/management.d.ts +7 -0
- package/dist/presentation/dto/management.d.ts.map +1 -0
- package/dist/presentation/dto/management.js +32 -0
- package/dist/presentation/dto/management.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-secret.d.ts +2 -0
- package/dist/presentation/e2eRoutes/create-secret.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-secret.js +34 -0
- package/dist/presentation/e2eRoutes/create-secret.js.map +1 -0
- package/dist/presentation/e2eRoutes/create-variable.d.ts +2 -0
- package/dist/presentation/e2eRoutes/create-variable.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/create-variable.js +34 -0
- package/dist/presentation/e2eRoutes/create-variable.js.map +1 -0
- package/dist/presentation/e2eRoutes/index.d.ts +3 -0
- package/dist/presentation/e2eRoutes/index.d.ts.map +1 -0
- package/dist/presentation/e2eRoutes/index.js +11 -0
- package/dist/presentation/e2eRoutes/index.js.map +1 -0
- package/dist/presentation/routes/auth.d.ts +16 -0
- package/dist/presentation/routes/auth.d.ts.map +1 -0
- package/dist/presentation/routes/auth.js +42 -0
- package/dist/presentation/routes/auth.js.map +1 -0
- package/dist/presentation/routes/batch-secrets.d.ts +2 -0
- package/dist/presentation/routes/batch-secrets.d.ts.map +1 -0
- package/dist/presentation/routes/batch-secrets.js +44 -0
- package/dist/presentation/routes/batch-secrets.js.map +1 -0
- package/dist/presentation/routes/batch-variables.d.ts +2 -0
- package/dist/presentation/routes/batch-variables.d.ts.map +1 -0
- package/dist/presentation/routes/batch-variables.js +44 -0
- package/dist/presentation/routes/batch-variables.js.map +1 -0
- package/dist/presentation/routes/cursor.d.ts +3 -0
- package/dist/presentation/routes/cursor.d.ts.map +1 -0
- package/dist/presentation/routes/cursor.js +19 -0
- package/dist/presentation/routes/cursor.js.map +1 -0
- package/dist/presentation/routes/delete-secret.d.ts +2 -0
- package/dist/presentation/routes/delete-secret.d.ts.map +1 -0
- package/dist/presentation/routes/delete-secret.js +40 -0
- package/dist/presentation/routes/delete-secret.js.map +1 -0
- package/dist/presentation/routes/delete-variable.d.ts +2 -0
- package/dist/presentation/routes/delete-variable.d.ts.map +1 -0
- package/dist/presentation/routes/delete-variable.js +40 -0
- package/dist/presentation/routes/delete-variable.js.map +1 -0
- package/dist/presentation/routes/errors.d.ts +2 -0
- package/dist/presentation/routes/errors.d.ts.map +1 -0
- package/dist/presentation/routes/errors.js +73 -0
- package/dist/presentation/routes/errors.js.map +1 -0
- package/dist/presentation/routes/get-variable.d.ts +2 -0
- package/dist/presentation/routes/get-variable.d.ts.map +1 -0
- package/dist/presentation/routes/get-variable.js +42 -0
- package/dist/presentation/routes/get-variable.js.map +1 -0
- package/dist/presentation/routes/index.d.ts +3 -0
- package/dist/presentation/routes/index.d.ts.map +1 -0
- package/dist/presentation/routes/index.js +29 -0
- package/dist/presentation/routes/index.js.map +1 -0
- package/dist/presentation/routes/list-secrets.d.ts +2 -0
- package/dist/presentation/routes/list-secrets.d.ts.map +1 -0
- package/dist/presentation/routes/list-secrets.js +50 -0
- package/dist/presentation/routes/list-secrets.js.map +1 -0
- package/dist/presentation/routes/list-variables.d.ts +2 -0
- package/dist/presentation/routes/list-variables.d.ts.map +1 -0
- package/dist/presentation/routes/list-variables.js +50 -0
- package/dist/presentation/routes/list-variables.js.map +1 -0
- package/dist/presentation/routes/put-secret.d.ts +2 -0
- package/dist/presentation/routes/put-secret.d.ts.map +1 -0
- package/dist/presentation/routes/put-secret.js +52 -0
- package/dist/presentation/routes/put-secret.js.map +1 -0
- package/dist/presentation/routes/put-variable.d.ts +2 -0
- package/dist/presentation/routes/put-variable.d.ts.map +1 -0
- package/dist/presentation/routes/put-variable.js +52 -0
- package/dist/presentation/routes/put-variable.js.map +1 -0
- package/dist/presentation/routes/warnings.d.ts +5 -0
- package/dist/presentation/routes/warnings.d.ts.map +1 -0
- package/dist/presentation/routes/warnings.js +16 -0
- package/dist/presentation/routes/warnings.js.map +1 -0
- package/dist/tsconfig.test.tsbuildinfo +1 -0
- package/drizzle/0000_lowly_ogun.sql +59 -0
- package/drizzle/meta/0000_snapshot.json +547 -0
- package/drizzle/meta/_journal.json +13 -0
- package/drizzle.config.ts +7 -0
- package/package.json +77 -0
- package/src/config.test.ts +41 -0
- package/src/config.ts +41 -0
- package/src/core/crypto.test.ts +115 -0
- package/src/core/crypto.ts +105 -0
- package/src/core/dek-manager.test.ts +120 -0
- package/src/core/dek-manager.ts +98 -0
- package/src/core/errors.ts +100 -0
- package/src/core/fingerprint.test.ts +27 -0
- package/src/core/fingerprint.ts +14 -0
- package/src/core/index.ts +153 -0
- package/src/core/key-provider.test.ts +44 -0
- package/src/core/key-provider.ts +70 -0
- package/src/core/local-secret-store.ts +49 -0
- package/src/core/management.test.ts +37 -0
- package/src/core/management.ts +503 -0
- package/src/core/rotate-kek.test.ts +183 -0
- package/src/core/rotate-kek.ts +100 -0
- package/src/core/secret-store.test.ts +301 -0
- package/src/core/secret-store.ts +251 -0
- package/src/core/store-resolver.test.ts +20 -0
- package/src/core/store-resolver.ts +28 -0
- package/src/core/store-validation.ts +43 -0
- package/src/core/value-cipher.ts +26 -0
- package/src/core/variable-store.test.ts +106 -0
- package/src/core/variable-store.ts +232 -0
- package/src/db/cap.ts +58 -0
- package/src/db/data-keys.ts +99 -0
- package/src/db/db.ts +26 -0
- package/src/db/index.ts +45 -0
- package/src/db/management.ts +252 -0
- package/src/db/schema/common.ts +8 -0
- package/src/db/schema/data-keys.ts +31 -0
- package/src/db/schema/outbox.ts +4 -0
- package/src/db/schema/values.ts +74 -0
- package/src/db/schema/variables.ts +71 -0
- package/src/db/scope.ts +42 -0
- package/src/db/values.ts +191 -0
- package/src/db/variables.ts +187 -0
- package/src/index.test.ts +11 -0
- package/src/index.ts +50 -0
- package/src/metrics/index.ts +19 -0
- package/src/metrics/instance.ts +219 -0
- package/src/metrics/service.ts +19 -0
- package/src/presentation/dto/index.ts +1 -0
- package/src/presentation/dto/management.ts +36 -0
- package/src/presentation/e2eRoutes/create-secret.ts +31 -0
- package/src/presentation/e2eRoutes/create-variable.ts +34 -0
- package/src/presentation/e2eRoutes/index.test.ts +94 -0
- package/src/presentation/e2eRoutes/index.ts +8 -0
- package/src/presentation/routes/auth.ts +50 -0
- package/src/presentation/routes/batch-secrets.ts +33 -0
- package/src/presentation/routes/batch-variables.ts +33 -0
- package/src/presentation/routes/cursor.ts +23 -0
- package/src/presentation/routes/delete-secret.ts +26 -0
- package/src/presentation/routes/delete-variable.ts +26 -0
- package/src/presentation/routes/errors.ts +63 -0
- package/src/presentation/routes/get-variable.ts +32 -0
- package/src/presentation/routes/index.ts +29 -0
- package/src/presentation/routes/list-secrets.ts +41 -0
- package/src/presentation/routes/list-variables.ts +41 -0
- package/src/presentation/routes/management.test.ts +452 -0
- package/src/presentation/routes/put-secret.ts +39 -0
- package/src/presentation/routes/put-variable.ts +39 -0
- package/src/presentation/routes/warnings.ts +23 -0
- package/test/env.ts +8 -0
- package/test/globalSetup.ts +18 -0
- package/test/setup.ts +17 -0
- package/tsconfig.build.json +10 -0
- package/tsconfig.build.tsbuildinfo +1 -0
- package/tsconfig.json +7 -0
- package/tsconfig.test.json +8 -0
- package/vitest.config.ts +12 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/dek-manager.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport {getDataKey, insertDataKeyIfAbsent} from '#db/index.js';\nimport {classifyDekAccessError, recordSecretsDekAccess} from '#metrics/instance.js';\nimport type {KeyProvider} from './key-provider.js';\n\nconst DEK_BYTES = 32;\n\n/**\n * Plaintext DEKs live in memory by design so hot secret reads avoid unwrapping on\n * every access. Node cannot reliably zeroize Buffers, so residency is bounded by\n * LRU size and lazy TTL instead of pretending wipes are a complete mitigation.\n */\nexport class DekManager {\n readonly #cache = new Map<string, {dek: Buffer; expiresAt: number}>();\n readonly #keyProvider: KeyProvider;\n readonly #options: {maxEntries: number; ttlMs: number};\n\n constructor(keyProvider: KeyProvider, options: {maxEntries: number; ttlMs: number}) {\n this.#keyProvider = keyProvider;\n this.#options = options;\n }\n\n async getPlaintextDek(workspaceId: string): Promise<Buffer> {\n const startedAt = Date.now();\n try {\n const cached = this.#cache.get(workspaceId);\n if (cached && cached.expiresAt > Date.now()) {\n this.#cache.delete(workspaceId);\n this.#cache.set(workspaceId, cached);\n recordSecretsDekAccess({outcome: 'cache_hit', durationMs: Date.now() - startedAt});\n return Buffer.from(cached.dek);\n }\n const hadExpiredCache = Boolean(cached);\n if (cached) this.#cache.delete(workspaceId);\n\n const existing = await getDataKey(workspaceId);\n if (existing) {\n const dek = this.#keyProvider.unwrapDek(\n workspaceId,\n existing.wrappedDek,\n existing.kekVersion,\n );\n this.#set(workspaceId, dek);\n recordSecretsDekAccess({\n outcome: hadExpiredCache ? 'cache_expired' : 'db_unwrapped',\n durationMs: Date.now() - startedAt,\n });\n return Buffer.from(dek);\n }\n\n const generatedDek = crypto.randomBytes(DEK_BYTES);\n const wrapped = this.#keyProvider.wrapDek(workspaceId, generatedDek);\n const inserted = await insertDataKeyIfAbsent({\n workspaceId,\n wrappedDek: wrapped.wrappedDek,\n kekVersion: wrapped.kekVersion,\n });\n\n // The DEK row commits before value writes. If concurrent first-use inserts race,\n // the primary key decides the winner and every caller re-reads the persisted row.\n const persisted = await getDataKey(workspaceId);\n if (!persisted) throw new Error(`Data key was not persisted for workspace ${workspaceId}`);\n const dek = this.#keyProvider.unwrapDek(\n workspaceId,\n persisted.wrappedDek,\n persisted.kekVersion,\n );\n this.#set(workspaceId, dek);\n recordSecretsDekAccess({\n outcome: inserted ? 'generated' : 'db_unwrapped',\n durationMs: Date.now() - startedAt,\n });\n return Buffer.from(dek);\n } catch (error) {\n recordSecretsDekAccess({\n outcome: classifyDekAccessError(error),\n durationMs: Date.now() - startedAt,\n });\n throw error;\n }\n }\n\n invalidate(workspaceId: string): void {\n this.#cache.delete(workspaceId);\n }\n\n #set(workspaceId: string, dek: Buffer): void {\n this.#cache.set(workspaceId, {\n dek: Buffer.from(dek),\n expiresAt: Date.now() + this.#options.ttlMs,\n });\n while (this.#cache.size > this.#options.maxEntries) {\n const oldest = this.#cache.keys().next().value as string | undefined;\n if (!oldest) break;\n this.#cache.delete(oldest);\n }\n }\n}\n"],"names":["crypto","getDataKey","insertDataKeyIfAbsent","classifyDekAccessError","recordSecretsDekAccess","DEK_BYTES","DekManager","keyProvider","options","Map","getPlaintextDek","workspaceId","startedAt","Date","now","cached","get","expiresAt","delete","set","outcome","durationMs","Buffer","from","dek","hadExpiredCache","Boolean","existing","unwrapDek","wrappedDek","kekVersion","generatedDek","randomBytes","wrapped","wrapDek","inserted","persisted","Error","error","invalidate","ttlMs","size","maxEntries","oldest","keys","next","value"],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export declare class SecretDecryptionError extends Error {
|
|
2
|
+
constructor();
|
|
3
|
+
}
|
|
4
|
+
export declare class DekWrapError extends Error {
|
|
5
|
+
constructor();
|
|
6
|
+
}
|
|
7
|
+
export declare class DekUnwrapError extends Error {
|
|
8
|
+
constructor();
|
|
9
|
+
}
|
|
10
|
+
export declare class KekConfigurationError extends Error {
|
|
11
|
+
constructor(message: string);
|
|
12
|
+
}
|
|
13
|
+
export declare class SecretKeyValidationError extends Error {
|
|
14
|
+
readonly key: string;
|
|
15
|
+
constructor(key: string);
|
|
16
|
+
}
|
|
17
|
+
export declare class NamespaceValidationError extends Error {
|
|
18
|
+
readonly namespace: string;
|
|
19
|
+
constructor(namespace: string);
|
|
20
|
+
}
|
|
21
|
+
export declare class WorkspaceSecretCapExceededError extends Error {
|
|
22
|
+
readonly workspaceId: string;
|
|
23
|
+
readonly cap: number;
|
|
24
|
+
constructor(workspaceId: string, cap: number);
|
|
25
|
+
}
|
|
26
|
+
export declare class SecretValueTooLargeError extends Error {
|
|
27
|
+
readonly maxBytes: number;
|
|
28
|
+
constructor(maxBytes: number);
|
|
29
|
+
}
|
|
30
|
+
export declare class SecretBatchScopeMismatchError extends Error {
|
|
31
|
+
constructor();
|
|
32
|
+
}
|
|
33
|
+
export declare class SecretBatchDuplicateKeyError extends Error {
|
|
34
|
+
readonly key: string;
|
|
35
|
+
constructor(key: string);
|
|
36
|
+
}
|
|
37
|
+
export declare class SecretNotFoundError extends Error {
|
|
38
|
+
readonly key: string;
|
|
39
|
+
constructor(key: string);
|
|
40
|
+
}
|
|
41
|
+
export declare class VariableNotFoundError extends Error {
|
|
42
|
+
readonly key: string;
|
|
43
|
+
constructor(key: string);
|
|
44
|
+
}
|
|
45
|
+
export declare class UnknownSecretStoreError extends Error {
|
|
46
|
+
readonly store: string;
|
|
47
|
+
constructor(store: string);
|
|
48
|
+
}
|
|
49
|
+
export declare class KekVersionStrandedError extends Error {
|
|
50
|
+
readonly kekVersion: string;
|
|
51
|
+
constructor(kekVersion: string);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,qBAAsB,SAAQ,KAAK;;CAK/C;AAED,qBAAa,YAAa,SAAQ,KAAK;;CAKtC;AAED,qBAAa,cAAe,SAAQ,KAAK;;CAKxC;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,wBAAyB,SAAQ,KAAK;aACrB,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CAIxC;AAED,qBAAa,wBAAyB,SAAQ,KAAK;aACrB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAI9C;AAED,qBAAa,+BAAgC,SAAQ,KAAK;aAEtC,WAAW,EAAE,MAAM;aACnB,GAAG,EAAE,MAAM;gBADX,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM;CAK9B;AAED,qBAAa,wBAAyB,SAAQ,KAAK;aACrB,QAAQ,EAAE,MAAM;gBAAhB,QAAQ,EAAE,MAAM;CAI7C;AAED,qBAAa,6BAA8B,SAAQ,KAAK;;CAKvD;AAED,qBAAa,4BAA6B,SAAQ,KAAK;aACzB,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CAIxC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;aAChB,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CAIxC;AAED,qBAAa,qBAAsB,SAAQ,KAAK;aAClB,GAAG,EAAE,MAAM;gBAAX,GAAG,EAAE,MAAM;CAIxC;AAED,qBAAa,uBAAwB,SAAQ,KAAK;aACpB,KAAK,EAAE,MAAM;gBAAb,KAAK,EAAE,MAAM;CAI1C;AAED,qBAAa,uBAAwB,SAAQ,KAAK;aACpB,UAAU,EAAE,MAAM;gBAAlB,UAAU,EAAE,MAAM;CAI/C"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
export class SecretDecryptionError extends Error {
|
|
2
|
+
constructor(){
|
|
3
|
+
super('Secret value could not be decrypted.');
|
|
4
|
+
this.name = 'SecretDecryptionError';
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export class DekWrapError extends Error {
|
|
8
|
+
constructor(){
|
|
9
|
+
super('Data encryption key could not be wrapped.');
|
|
10
|
+
this.name = 'DekWrapError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export class DekUnwrapError extends Error {
|
|
14
|
+
constructor(){
|
|
15
|
+
super('Data encryption key could not be unwrapped.');
|
|
16
|
+
this.name = 'DekUnwrapError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
export class KekConfigurationError extends Error {
|
|
20
|
+
constructor(message){
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = 'KekConfigurationError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class SecretKeyValidationError extends Error {
|
|
26
|
+
constructor(key){
|
|
27
|
+
super(`Invalid secret key: ${key}`), this.key = key;
|
|
28
|
+
this.name = 'SecretKeyValidationError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class NamespaceValidationError extends Error {
|
|
32
|
+
constructor(namespace){
|
|
33
|
+
super(`Invalid secret namespace: ${namespace}`), this.namespace = namespace;
|
|
34
|
+
this.name = 'NamespaceValidationError';
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class WorkspaceSecretCapExceededError extends Error {
|
|
38
|
+
constructor(workspaceId, cap){
|
|
39
|
+
super(`Workspace ${workspaceId} exceeds the secret and variable cap of ${cap}.`), this.workspaceId = workspaceId, this.cap = cap;
|
|
40
|
+
this.name = 'WorkspaceSecretCapExceededError';
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
export class SecretValueTooLargeError extends Error {
|
|
44
|
+
constructor(maxBytes){
|
|
45
|
+
super(`Secret and variable values must not exceed ${maxBytes} bytes.`), this.maxBytes = maxBytes;
|
|
46
|
+
this.name = 'SecretValueTooLargeError';
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export class SecretBatchScopeMismatchError extends Error {
|
|
50
|
+
constructor(){
|
|
51
|
+
super('Secret and variable batches must target a single project scope.');
|
|
52
|
+
this.name = 'SecretBatchScopeMismatchError';
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export class SecretBatchDuplicateKeyError extends Error {
|
|
56
|
+
constructor(key){
|
|
57
|
+
super(`Duplicate secret or variable key in batch: ${key}`), this.key = key;
|
|
58
|
+
this.name = 'SecretBatchDuplicateKeyError';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export class SecretNotFoundError extends Error {
|
|
62
|
+
constructor(key){
|
|
63
|
+
super(`Secret not found: ${key}`), this.key = key;
|
|
64
|
+
this.name = 'SecretNotFoundError';
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export class VariableNotFoundError extends Error {
|
|
68
|
+
constructor(key){
|
|
69
|
+
super(`Variable not found: ${key}`), this.key = key;
|
|
70
|
+
this.name = 'VariableNotFoundError';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
export class UnknownSecretStoreError extends Error {
|
|
74
|
+
constructor(store){
|
|
75
|
+
super(`Unknown secret store: ${store.slice(0, 64)}`), this.store = store;
|
|
76
|
+
this.name = 'UnknownSecretStoreError';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export class KekVersionStrandedError extends Error {
|
|
80
|
+
constructor(kekVersion){
|
|
81
|
+
super(`Data key is stranded on unknown KEK version: ${kekVersion}`), this.kekVersion = kekVersion;
|
|
82
|
+
this.name = 'KekVersionStrandedError';
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/errors.ts"],"sourcesContent":["export class SecretDecryptionError extends Error {\n constructor() {\n super('Secret value could not be decrypted.');\n this.name = 'SecretDecryptionError';\n }\n}\n\nexport class DekWrapError extends Error {\n constructor() {\n super('Data encryption key could not be wrapped.');\n this.name = 'DekWrapError';\n }\n}\n\nexport class DekUnwrapError extends Error {\n constructor() {\n super('Data encryption key could not be unwrapped.');\n this.name = 'DekUnwrapError';\n }\n}\n\nexport class KekConfigurationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'KekConfigurationError';\n }\n}\n\nexport class SecretKeyValidationError extends Error {\n constructor(public readonly key: string) {\n super(`Invalid secret key: ${key}`);\n this.name = 'SecretKeyValidationError';\n }\n}\n\nexport class NamespaceValidationError extends Error {\n constructor(public readonly namespace: string) {\n super(`Invalid secret namespace: ${namespace}`);\n this.name = 'NamespaceValidationError';\n }\n}\n\nexport class WorkspaceSecretCapExceededError extends Error {\n constructor(\n public readonly workspaceId: string,\n public readonly cap: number,\n ) {\n super(`Workspace ${workspaceId} exceeds the secret and variable cap of ${cap}.`);\n this.name = 'WorkspaceSecretCapExceededError';\n }\n}\n\nexport class SecretValueTooLargeError extends Error {\n constructor(public readonly maxBytes: number) {\n super(`Secret and variable values must not exceed ${maxBytes} bytes.`);\n this.name = 'SecretValueTooLargeError';\n }\n}\n\nexport class SecretBatchScopeMismatchError extends Error {\n constructor() {\n super('Secret and variable batches must target a single project scope.');\n this.name = 'SecretBatchScopeMismatchError';\n }\n}\n\nexport class SecretBatchDuplicateKeyError extends Error {\n constructor(public readonly key: string) {\n super(`Duplicate secret or variable key in batch: ${key}`);\n this.name = 'SecretBatchDuplicateKeyError';\n }\n}\n\nexport class SecretNotFoundError extends Error {\n constructor(public readonly key: string) {\n super(`Secret not found: ${key}`);\n this.name = 'SecretNotFoundError';\n }\n}\n\nexport class VariableNotFoundError extends Error {\n constructor(public readonly key: string) {\n super(`Variable not found: ${key}`);\n this.name = 'VariableNotFoundError';\n }\n}\n\nexport class UnknownSecretStoreError extends Error {\n constructor(public readonly store: string) {\n super(`Unknown secret store: ${store.slice(0, 64)}`);\n this.name = 'UnknownSecretStoreError';\n }\n}\n\nexport class KekVersionStrandedError extends Error {\n constructor(public readonly kekVersion: string) {\n super(`Data key is stranded on unknown KEK version: ${kekVersion}`);\n this.name = 'KekVersionStrandedError';\n }\n}\n"],"names":["SecretDecryptionError","Error","name","DekWrapError","DekUnwrapError","KekConfigurationError","message","SecretKeyValidationError","key","NamespaceValidationError","namespace","WorkspaceSecretCapExceededError","workspaceId","cap","SecretValueTooLargeError","maxBytes","SecretBatchScopeMismatchError","SecretBatchDuplicateKeyError","SecretNotFoundError","VariableNotFoundError","UnknownSecretStoreError","store","slice","KekVersionStrandedError","kekVersion"],"mappings":"AAAA,OAAO,MAAMA,8BAA8BC;IACzC,aAAc;QACZ,KAAK,CAAC;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMC,qBAAqBF;IAChC,aAAc;QACZ,KAAK,CAAC;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAME,uBAAuBH;IAClC,aAAc;QACZ,KAAK,CAAC;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMG,8BAA8BJ;IACzC,YAAYK,OAAe,CAAE;QAC3B,KAAK,CAACA;QACN,IAAI,CAACJ,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMK,iCAAiCN;IAC5C,YAAY,AAAgBO,GAAW,CAAE;QACvC,KAAK,CAAC,CAAC,oBAAoB,EAAEA,KAAK,QADRA,MAAAA;QAE1B,IAAI,CAACN,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMO,iCAAiCR;IAC5C,YAAY,AAAgBS,SAAiB,CAAE;QAC7C,KAAK,CAAC,CAAC,0BAA0B,EAAEA,WAAW,QADpBA,YAAAA;QAE1B,IAAI,CAACR,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMS,wCAAwCV;IACnD,YACE,AAAgBW,WAAmB,EACnC,AAAgBC,GAAW,CAC3B;QACA,KAAK,CAAC,CAAC,UAAU,EAAED,YAAY,wCAAwC,EAAEC,IAAI,CAAC,CAAC,QAH/DD,cAAAA,kBACAC,MAAAA;QAGhB,IAAI,CAACX,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMY,iCAAiCb;IAC5C,YAAY,AAAgBc,QAAgB,CAAE;QAC5C,KAAK,CAAC,CAAC,2CAA2C,EAAEA,SAAS,OAAO,CAAC,QAD3CA,WAAAA;QAE1B,IAAI,CAACb,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMc,sCAAsCf;IACjD,aAAc;QACZ,KAAK,CAAC;QACN,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMe,qCAAqChB;IAChD,YAAY,AAAgBO,GAAW,CAAE;QACvC,KAAK,CAAC,CAAC,2CAA2C,EAAEA,KAAK,QAD/BA,MAAAA;QAE1B,IAAI,CAACN,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMgB,4BAA4BjB;IACvC,YAAY,AAAgBO,GAAW,CAAE;QACvC,KAAK,CAAC,CAAC,kBAAkB,EAAEA,KAAK,QADNA,MAAAA;QAE1B,IAAI,CAACN,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMiB,8BAA8BlB;IACzC,YAAY,AAAgBO,GAAW,CAAE;QACvC,KAAK,CAAC,CAAC,oBAAoB,EAAEA,KAAK,QADRA,MAAAA;QAE1B,IAAI,CAACN,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMkB,gCAAgCnB;IAC3C,YAAY,AAAgBoB,KAAa,CAAE;QACzC,KAAK,CAAC,CAAC,sBAAsB,EAAEA,MAAMC,KAAK,CAAC,GAAG,KAAK,QADzBD,QAAAA;QAE1B,IAAI,CAACnB,IAAI,GAAG;IACd;AACF;AAEA,OAAO,MAAMqB,gCAAgCtB;IAC3C,YAAY,AAAgBuB,UAAkB,CAAE;QAC9C,KAAK,CAAC,CAAC,6CAA6C,EAAEA,YAAY,QADxCA,aAAAA;QAE1B,IAAI,CAACtB,IAAI,GAAG;IACd;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/core/fingerprint.ts"],"names":[],"mappings":"AAKA,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAQzE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
const FINGERPRINT_PREFIX = 'hmac-sha256:';
|
|
3
|
+
const FINGERPRINT_DOMAIN = 'shipfox:secrets:value-fingerprint:v1';
|
|
4
|
+
export function fingerprintSecretValue(value, key) {
|
|
5
|
+
const digest = crypto.createHmac('sha256', key).update(FINGERPRINT_DOMAIN).update('\0').update(value).digest('base64url');
|
|
6
|
+
return `${FINGERPRINT_PREFIX}${digest}`;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
//# sourceMappingURL=fingerprint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/fingerprint.ts"],"sourcesContent":["import crypto from 'node:crypto';\n\nconst FINGERPRINT_PREFIX = 'hmac-sha256:';\nconst FINGERPRINT_DOMAIN = 'shipfox:secrets:value-fingerprint:v1';\n\nexport function fingerprintSecretValue(value: string, key: Buffer): string {\n const digest = crypto\n .createHmac('sha256', key)\n .update(FINGERPRINT_DOMAIN)\n .update('\\0')\n .update(value)\n .digest('base64url');\n return `${FINGERPRINT_PREFIX}${digest}`;\n}\n"],"names":["crypto","FINGERPRINT_PREFIX","FINGERPRINT_DOMAIN","fingerprintSecretValue","value","key","digest","createHmac","update"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AAEjC,MAAMC,qBAAqB;AAC3B,MAAMC,qBAAqB;AAE3B,OAAO,SAASC,uBAAuBC,KAAa,EAAEC,GAAW;IAC/D,MAAMC,SAASN,OACZO,UAAU,CAAC,UAAUF,KACrBG,MAAM,CAACN,oBACPM,MAAM,CAAC,MACPA,MAAM,CAACJ,OACPE,MAAM,CAAC;IACV,OAAO,GAAGL,qBAAqBK,QAAQ;AACzC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { DekManager } from './dek-manager.js';
|
|
2
|
+
import { type KeyProvider } from './key-provider.js';
|
|
3
|
+
import { createSecretsManagementApi } from './management.js';
|
|
4
|
+
import { rotateWorkspaceDataKeysWithProvider } from './rotate-kek.js';
|
|
5
|
+
import { createSecretStoreApi } from './secret-store.js';
|
|
6
|
+
import { BUILTIN_LOCAL_STORE, type SecretStoreProvider } from './store-resolver.js';
|
|
7
|
+
export * from './errors.js';
|
|
8
|
+
export type { ManagementEntry, ManagementKeyParams, ManagementListParams, ManagementWriteParams, } from './management.js';
|
|
9
|
+
export type { DeleteSecretsParams, SetSecretsParams } from './secret-store.js';
|
|
10
|
+
export type { DeleteVariablesParams, SetVariablesParams } from './variable-store.js';
|
|
11
|
+
export { deleteVariables, getVariable, getVariablesByNamespace, setVariables, } from './variable-store.js';
|
|
12
|
+
export { BUILTIN_LOCAL_STORE, type SecretStoreProvider };
|
|
13
|
+
export declare function keyProvider(): KeyProvider;
|
|
14
|
+
export declare function dekManager(): DekManager;
|
|
15
|
+
export declare function localSecretStore(): SecretStoreProvider;
|
|
16
|
+
export declare function resolveSecretStore(name?: string | undefined): SecretStoreProvider;
|
|
17
|
+
export declare function getSecret(...args: Parameters<ReturnType<typeof createSecretStoreApi>['getSecret']>): Promise<string | null>;
|
|
18
|
+
export declare function getSecretsByNamespace(...args: Parameters<ReturnType<typeof createSecretStoreApi>['getSecretsByNamespace']>): Promise<Record<string, string>>;
|
|
19
|
+
export declare function setSecrets(...args: Parameters<ReturnType<typeof createSecretStoreApi>['setSecrets']>): Promise<void>;
|
|
20
|
+
export declare function deleteSecrets(...args: Parameters<ReturnType<typeof createSecretStoreApi>['deleteSecrets']>): Promise<number>;
|
|
21
|
+
export declare function listManagedSecrets(...args: Parameters<ReturnType<typeof createSecretsManagementApi>['listSecrets']>): Promise<import("../db/management.js").SecretManagementListResult>;
|
|
22
|
+
export declare function listManagedVariables(...args: Parameters<ReturnType<typeof createSecretsManagementApi>['listVariables']>): Promise<import("../db/management.js").VariableManagementListResult>;
|
|
23
|
+
export declare function getManagedVariable(...args: Parameters<ReturnType<typeof createSecretsManagementApi>['getVariable']>): Promise<import("../db/schema/variables.js").SecretVariable>;
|
|
24
|
+
export declare function setManagedSecrets(...args: Parameters<ReturnType<typeof createSecretsManagementApi>['setSecrets']>): Promise<import("../db/management.js").SecretManagementRow[]>;
|
|
25
|
+
export declare function setManagedVariables(...args: Parameters<ReturnType<typeof createSecretsManagementApi>['setVariables']>): Promise<import("../db/schema/variables.js").SecretVariable[]>;
|
|
26
|
+
export declare function deleteManagedSecret(...args: Parameters<ReturnType<typeof createSecretsManagementApi>['deleteSecret']>): Promise<void>;
|
|
27
|
+
export declare function deleteManagedVariable(...args: Parameters<ReturnType<typeof createSecretsManagementApi>['deleteVariable']>): Promise<void>;
|
|
28
|
+
export declare function rotateWorkspaceDataKeys(): Promise<import("./rotate-kek.js").RotateWorkspaceDataKeysResult>;
|
|
29
|
+
export { rotateWorkspaceDataKeysWithProvider };
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { config } from '#config.js';
|
|
2
|
+
import { decodeBase64Key } from './crypto.js';
|
|
3
|
+
import { DekManager } from './dek-manager.js';
|
|
4
|
+
import { createLocalKeyProvider } from './key-provider.js';
|
|
5
|
+
import { createLocalSecretStore } from './local-secret-store.js';
|
|
6
|
+
import { createSecretsManagementApi } from './management.js';
|
|
7
|
+
import { rotateWorkspaceDataKeysWithProvider } from './rotate-kek.js';
|
|
8
|
+
import { createSecretStoreApi } from './secret-store.js';
|
|
9
|
+
import { BUILTIN_LOCAL_STORE, createSecretStoreResolver } from './store-resolver.js';
|
|
10
|
+
export * from './errors.js';
|
|
11
|
+
export { deleteVariables, getVariable, getVariablesByNamespace, setVariables } from './variable-store.js';
|
|
12
|
+
export { BUILTIN_LOCAL_STORE };
|
|
13
|
+
let memoizedKeyProvider;
|
|
14
|
+
let memoizedDekManager;
|
|
15
|
+
let memoizedLocalStore;
|
|
16
|
+
let memoizedSecretApi;
|
|
17
|
+
let memoizedManagementApi;
|
|
18
|
+
export function keyProvider() {
|
|
19
|
+
if (memoizedKeyProvider) return memoizedKeyProvider;
|
|
20
|
+
memoizedKeyProvider = createLocalKeyProvider({
|
|
21
|
+
currentKek: decodeBase64Key(config.SECRETS_ENCRYPTION_KEK, 'SECRETS_ENCRYPTION_KEK'),
|
|
22
|
+
previousKek: config.SECRETS_ENCRYPTION_KEK_PREVIOUS ? decodeBase64Key(config.SECRETS_ENCRYPTION_KEK_PREVIOUS, 'SECRETS_ENCRYPTION_KEK_PREVIOUS') : undefined
|
|
23
|
+
});
|
|
24
|
+
return memoizedKeyProvider;
|
|
25
|
+
}
|
|
26
|
+
export function dekManager() {
|
|
27
|
+
if (memoizedDekManager) return memoizedDekManager;
|
|
28
|
+
memoizedDekManager = new DekManager(keyProvider(), {
|
|
29
|
+
maxEntries: 1000,
|
|
30
|
+
ttlMs: 5 * 60 * 1000
|
|
31
|
+
});
|
|
32
|
+
return memoizedDekManager;
|
|
33
|
+
}
|
|
34
|
+
export function localSecretStore() {
|
|
35
|
+
if (memoizedLocalStore) return memoizedLocalStore;
|
|
36
|
+
memoizedLocalStore = createLocalSecretStore({
|
|
37
|
+
dekManager: dekManager()
|
|
38
|
+
});
|
|
39
|
+
return memoizedLocalStore;
|
|
40
|
+
}
|
|
41
|
+
export function resolveSecretStore(name) {
|
|
42
|
+
return createSecretStoreResolver(localSecretStore())(name);
|
|
43
|
+
}
|
|
44
|
+
function secretApi() {
|
|
45
|
+
if (memoizedSecretApi) return memoizedSecretApi;
|
|
46
|
+
memoizedSecretApi = createSecretStoreApi({
|
|
47
|
+
dekManager: dekManager(),
|
|
48
|
+
resolveSecretStore
|
|
49
|
+
});
|
|
50
|
+
return memoizedSecretApi;
|
|
51
|
+
}
|
|
52
|
+
function managementApi() {
|
|
53
|
+
if (memoizedManagementApi) return memoizedManagementApi;
|
|
54
|
+
memoizedManagementApi = createSecretsManagementApi({
|
|
55
|
+
dekManager: dekManager()
|
|
56
|
+
});
|
|
57
|
+
return memoizedManagementApi;
|
|
58
|
+
}
|
|
59
|
+
export function getSecret(...args) {
|
|
60
|
+
return secretApi().getSecret(...args);
|
|
61
|
+
}
|
|
62
|
+
export function getSecretsByNamespace(...args) {
|
|
63
|
+
return secretApi().getSecretsByNamespace(...args);
|
|
64
|
+
}
|
|
65
|
+
export function setSecrets(...args) {
|
|
66
|
+
return secretApi().setSecrets(...args);
|
|
67
|
+
}
|
|
68
|
+
export function deleteSecrets(...args) {
|
|
69
|
+
return secretApi().deleteSecrets(...args);
|
|
70
|
+
}
|
|
71
|
+
export function listManagedSecrets(...args) {
|
|
72
|
+
return managementApi().listSecrets(...args);
|
|
73
|
+
}
|
|
74
|
+
export function listManagedVariables(...args) {
|
|
75
|
+
return managementApi().listVariables(...args);
|
|
76
|
+
}
|
|
77
|
+
export function getManagedVariable(...args) {
|
|
78
|
+
return managementApi().getVariable(...args);
|
|
79
|
+
}
|
|
80
|
+
export function setManagedSecrets(...args) {
|
|
81
|
+
return managementApi().setSecrets(...args);
|
|
82
|
+
}
|
|
83
|
+
export function setManagedVariables(...args) {
|
|
84
|
+
return managementApi().setVariables(...args);
|
|
85
|
+
}
|
|
86
|
+
export function deleteManagedSecret(...args) {
|
|
87
|
+
return managementApi().deleteSecret(...args);
|
|
88
|
+
}
|
|
89
|
+
export function deleteManagedVariable(...args) {
|
|
90
|
+
return managementApi().deleteVariable(...args);
|
|
91
|
+
}
|
|
92
|
+
export function rotateWorkspaceDataKeys() {
|
|
93
|
+
return rotateWorkspaceDataKeysWithProvider(keyProvider());
|
|
94
|
+
}
|
|
95
|
+
export { rotateWorkspaceDataKeysWithProvider };
|
|
96
|
+
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/index.ts"],"sourcesContent":["import {config} from '#config.js';\nimport {decodeBase64Key} from './crypto.js';\nimport {DekManager} from './dek-manager.js';\nimport {createLocalKeyProvider, type KeyProvider} from './key-provider.js';\nimport {createLocalSecretStore} from './local-secret-store.js';\nimport {createSecretsManagementApi} from './management.js';\nimport {rotateWorkspaceDataKeysWithProvider} from './rotate-kek.js';\nimport {createSecretStoreApi} from './secret-store.js';\nimport {\n BUILTIN_LOCAL_STORE,\n createSecretStoreResolver,\n type SecretStoreProvider,\n} from './store-resolver.js';\n\nexport * from './errors.js';\nexport type {\n ManagementEntry,\n ManagementKeyParams,\n ManagementListParams,\n ManagementWriteParams,\n} from './management.js';\nexport type {DeleteSecretsParams, SetSecretsParams} from './secret-store.js';\nexport type {DeleteVariablesParams, SetVariablesParams} from './variable-store.js';\nexport {\n deleteVariables,\n getVariable,\n getVariablesByNamespace,\n setVariables,\n} from './variable-store.js';\nexport {BUILTIN_LOCAL_STORE, type SecretStoreProvider};\n\nlet memoizedKeyProvider: KeyProvider | undefined;\nlet memoizedDekManager: DekManager | undefined;\nlet memoizedLocalStore: SecretStoreProvider | undefined;\nlet memoizedSecretApi: ReturnType<typeof createSecretStoreApi> | undefined;\nlet memoizedManagementApi: ReturnType<typeof createSecretsManagementApi> | undefined;\n\nexport function keyProvider(): KeyProvider {\n if (memoizedKeyProvider) return memoizedKeyProvider;\n memoizedKeyProvider = createLocalKeyProvider({\n currentKek: decodeBase64Key(config.SECRETS_ENCRYPTION_KEK, 'SECRETS_ENCRYPTION_KEK'),\n previousKek: config.SECRETS_ENCRYPTION_KEK_PREVIOUS\n ? decodeBase64Key(config.SECRETS_ENCRYPTION_KEK_PREVIOUS, 'SECRETS_ENCRYPTION_KEK_PREVIOUS')\n : undefined,\n });\n return memoizedKeyProvider;\n}\n\nexport function dekManager(): DekManager {\n if (memoizedDekManager) return memoizedDekManager;\n memoizedDekManager = new DekManager(keyProvider(), {\n maxEntries: 1000,\n ttlMs: 5 * 60 * 1000,\n });\n return memoizedDekManager;\n}\n\nexport function localSecretStore(): SecretStoreProvider {\n if (memoizedLocalStore) return memoizedLocalStore;\n memoizedLocalStore = createLocalSecretStore({dekManager: dekManager()});\n return memoizedLocalStore;\n}\n\nexport function resolveSecretStore(name?: string | undefined): SecretStoreProvider {\n return createSecretStoreResolver(localSecretStore())(name);\n}\n\nfunction secretApi(): ReturnType<typeof createSecretStoreApi> {\n if (memoizedSecretApi) return memoizedSecretApi;\n memoizedSecretApi = createSecretStoreApi({\n dekManager: dekManager(),\n resolveSecretStore,\n });\n return memoizedSecretApi;\n}\n\nfunction managementApi(): ReturnType<typeof createSecretsManagementApi> {\n if (memoizedManagementApi) return memoizedManagementApi;\n memoizedManagementApi = createSecretsManagementApi({dekManager: dekManager()});\n return memoizedManagementApi;\n}\n\nexport function getSecret(\n ...args: Parameters<ReturnType<typeof createSecretStoreApi>['getSecret']>\n) {\n return secretApi().getSecret(...args);\n}\n\nexport function getSecretsByNamespace(\n ...args: Parameters<ReturnType<typeof createSecretStoreApi>['getSecretsByNamespace']>\n) {\n return secretApi().getSecretsByNamespace(...args);\n}\n\nexport function setSecrets(\n ...args: Parameters<ReturnType<typeof createSecretStoreApi>['setSecrets']>\n) {\n return secretApi().setSecrets(...args);\n}\n\nexport function deleteSecrets(\n ...args: Parameters<ReturnType<typeof createSecretStoreApi>['deleteSecrets']>\n) {\n return secretApi().deleteSecrets(...args);\n}\n\nexport function listManagedSecrets(\n ...args: Parameters<ReturnType<typeof createSecretsManagementApi>['listSecrets']>\n) {\n return managementApi().listSecrets(...args);\n}\n\nexport function listManagedVariables(\n ...args: Parameters<ReturnType<typeof createSecretsManagementApi>['listVariables']>\n) {\n return managementApi().listVariables(...args);\n}\n\nexport function getManagedVariable(\n ...args: Parameters<ReturnType<typeof createSecretsManagementApi>['getVariable']>\n) {\n return managementApi().getVariable(...args);\n}\n\nexport function setManagedSecrets(\n ...args: Parameters<ReturnType<typeof createSecretsManagementApi>['setSecrets']>\n) {\n return managementApi().setSecrets(...args);\n}\n\nexport function setManagedVariables(\n ...args: Parameters<ReturnType<typeof createSecretsManagementApi>['setVariables']>\n) {\n return managementApi().setVariables(...args);\n}\n\nexport function deleteManagedSecret(\n ...args: Parameters<ReturnType<typeof createSecretsManagementApi>['deleteSecret']>\n) {\n return managementApi().deleteSecret(...args);\n}\n\nexport function deleteManagedVariable(\n ...args: Parameters<ReturnType<typeof createSecretsManagementApi>['deleteVariable']>\n) {\n return managementApi().deleteVariable(...args);\n}\n\nexport function rotateWorkspaceDataKeys() {\n return rotateWorkspaceDataKeysWithProvider(keyProvider());\n}\n\nexport {rotateWorkspaceDataKeysWithProvider};\n"],"names":["config","decodeBase64Key","DekManager","createLocalKeyProvider","createLocalSecretStore","createSecretsManagementApi","rotateWorkspaceDataKeysWithProvider","createSecretStoreApi","BUILTIN_LOCAL_STORE","createSecretStoreResolver","deleteVariables","getVariable","getVariablesByNamespace","setVariables","memoizedKeyProvider","memoizedDekManager","memoizedLocalStore","memoizedSecretApi","memoizedManagementApi","keyProvider","currentKek","SECRETS_ENCRYPTION_KEK","previousKek","SECRETS_ENCRYPTION_KEK_PREVIOUS","undefined","dekManager","maxEntries","ttlMs","localSecretStore","resolveSecretStore","name","secretApi","managementApi","getSecret","args","getSecretsByNamespace","setSecrets","deleteSecrets","listManagedSecrets","listSecrets","listManagedVariables","listVariables","getManagedVariable","setManagedSecrets","setManagedVariables","deleteManagedSecret","deleteSecret","deleteManagedVariable","deleteVariable","rotateWorkspaceDataKeys"],"mappings":"AAAA,SAAQA,MAAM,QAAO,aAAa;AAClC,SAAQC,eAAe,QAAO,cAAc;AAC5C,SAAQC,UAAU,QAAO,mBAAmB;AAC5C,SAAQC,sBAAsB,QAAyB,oBAAoB;AAC3E,SAAQC,sBAAsB,QAAO,0BAA0B;AAC/D,SAAQC,0BAA0B,QAAO,kBAAkB;AAC3D,SAAQC,mCAAmC,QAAO,kBAAkB;AACpE,SAAQC,oBAAoB,QAAO,oBAAoB;AACvD,SACEC,mBAAmB,EACnBC,yBAAyB,QAEpB,sBAAsB;AAE7B,cAAc,cAAc;AAS5B,SACEC,eAAe,EACfC,WAAW,EACXC,uBAAuB,EACvBC,YAAY,QACP,sBAAsB;AAC7B,SAAQL,mBAAmB,GAA4B;AAEvD,IAAIM;AACJ,IAAIC;AACJ,IAAIC;AACJ,IAAIC;AACJ,IAAIC;AAEJ,OAAO,SAASC;IACd,IAAIL,qBAAqB,OAAOA;IAChCA,sBAAsBX,uBAAuB;QAC3CiB,YAAYnB,gBAAgBD,OAAOqB,sBAAsB,EAAE;QAC3DC,aAAatB,OAAOuB,+BAA+B,GAC/CtB,gBAAgBD,OAAOuB,+BAA+B,EAAE,qCACxDC;IACN;IACA,OAAOV;AACT;AAEA,OAAO,SAASW;IACd,IAAIV,oBAAoB,OAAOA;IAC/BA,qBAAqB,IAAIb,WAAWiB,eAAe;QACjDO,YAAY;QACZC,OAAO,IAAI,KAAK;IAClB;IACA,OAAOZ;AACT;AAEA,OAAO,SAASa;IACd,IAAIZ,oBAAoB,OAAOA;IAC/BA,qBAAqBZ,uBAAuB;QAACqB,YAAYA;IAAY;IACrE,OAAOT;AACT;AAEA,OAAO,SAASa,mBAAmBC,IAAyB;IAC1D,OAAOrB,0BAA0BmB,oBAAoBE;AACvD;AAEA,SAASC;IACP,IAAId,mBAAmB,OAAOA;IAC9BA,oBAAoBV,qBAAqB;QACvCkB,YAAYA;QACZI;IACF;IACA,OAAOZ;AACT;AAEA,SAASe;IACP,IAAId,uBAAuB,OAAOA;IAClCA,wBAAwBb,2BAA2B;QAACoB,YAAYA;IAAY;IAC5E,OAAOP;AACT;AAEA,OAAO,SAASe,UACd,GAAGC,IAAsE;IAEzE,OAAOH,YAAYE,SAAS,IAAIC;AAClC;AAEA,OAAO,SAASC,sBACd,GAAGD,IAAkF;IAErF,OAAOH,YAAYI,qBAAqB,IAAID;AAC9C;AAEA,OAAO,SAASE,WACd,GAAGF,IAAuE;IAE1E,OAAOH,YAAYK,UAAU,IAAIF;AACnC;AAEA,OAAO,SAASG,cACd,GAAGH,IAA0E;IAE7E,OAAOH,YAAYM,aAAa,IAAIH;AACtC;AAEA,OAAO,SAASI,mBACd,GAAGJ,IAA8E;IAEjF,OAAOF,gBAAgBO,WAAW,IAAIL;AACxC;AAEA,OAAO,SAASM,qBACd,GAAGN,IAAgF;IAEnF,OAAOF,gBAAgBS,aAAa,IAAIP;AAC1C;AAEA,OAAO,SAASQ,mBACd,GAAGR,IAA8E;IAEjF,OAAOF,gBAAgBrB,WAAW,IAAIuB;AACxC;AAEA,OAAO,SAASS,kBACd,GAAGT,IAA6E;IAEhF,OAAOF,gBAAgBI,UAAU,IAAIF;AACvC;AAEA,OAAO,SAASU,oBACd,GAAGV,IAA+E;IAElF,OAAOF,gBAAgBnB,YAAY,IAAIqB;AACzC;AAEA,OAAO,SAASW,oBACd,GAAGX,IAA+E;IAElF,OAAOF,gBAAgBc,YAAY,IAAIZ;AACzC;AAEA,OAAO,SAASa,sBACd,GAAGb,IAAiF;IAEpF,OAAOF,gBAAgBgB,cAAc,IAAId;AAC3C;AAEA,OAAO,SAASe;IACd,OAAO3C,oCAAoCa;AAC7C;AAEA,SAAQb,mCAAmC,GAAE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface WrappedDek {
|
|
2
|
+
wrappedDek: string;
|
|
3
|
+
kekVersion: string;
|
|
4
|
+
}
|
|
5
|
+
export interface KeyProvider {
|
|
6
|
+
readonly currentKeyVersion: string;
|
|
7
|
+
readonly previousKeyVersion: string | null;
|
|
8
|
+
wrapDek(workspaceId: string, plaintextDek: Buffer): WrappedDek;
|
|
9
|
+
unwrapDek(workspaceId: string, wrappedDek: string, kekVersion: string): Buffer;
|
|
10
|
+
}
|
|
11
|
+
export interface LocalKeyProviderParams {
|
|
12
|
+
currentKek: Buffer;
|
|
13
|
+
previousKek?: Buffer | undefined;
|
|
14
|
+
}
|
|
15
|
+
export declare function createLocalKeyProvider(params: LocalKeyProviderParams): KeyProvider;
|
|
16
|
+
export declare function deriveLocalKekVersion(kek: Buffer): string;
|
|
17
|
+
//# sourceMappingURL=key-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"key-provider.d.ts","sourceRoot":"","sources":["../../src/core/key-provider.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,UAAU,CAAC;IAC/D,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAAC;CAChF;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB,GAAG,WAAW,CAyClF;AAED,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGzD"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
import { aadForDek, aesGcmOpen, aesGcmSeal } from './crypto.js';
|
|
3
|
+
import { DekUnwrapError, DekWrapError } from './errors.js';
|
|
4
|
+
const KEK_VERSION_DOMAIN = 'shipfox-secrets-kek-version';
|
|
5
|
+
export function createLocalKeyProvider(params) {
|
|
6
|
+
const currentKeyVersion = deriveLocalKekVersion(params.currentKek);
|
|
7
|
+
const previousKeyVersion = params.previousKek ? deriveLocalKekVersion(params.previousKek) : null;
|
|
8
|
+
return {
|
|
9
|
+
currentKeyVersion,
|
|
10
|
+
previousKeyVersion,
|
|
11
|
+
wrapDek (workspaceId, plaintextDek) {
|
|
12
|
+
try {
|
|
13
|
+
return {
|
|
14
|
+
wrappedDek: aesGcmSeal({
|
|
15
|
+
key: params.currentKek,
|
|
16
|
+
plaintext: plaintextDek,
|
|
17
|
+
aad: aadForDek(workspaceId, currentKeyVersion)
|
|
18
|
+
}),
|
|
19
|
+
kekVersion: currentKeyVersion
|
|
20
|
+
};
|
|
21
|
+
} catch {
|
|
22
|
+
throw new DekWrapError();
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
unwrapDek (workspaceId, wrappedDek, kekVersion) {
|
|
26
|
+
const key = kekVersion === currentKeyVersion ? params.currentKek : kekVersion === previousKeyVersion ? params.previousKek : undefined;
|
|
27
|
+
if (!key) throw new DekUnwrapError();
|
|
28
|
+
try {
|
|
29
|
+
return aesGcmOpen({
|
|
30
|
+
key,
|
|
31
|
+
encoded: wrappedDek,
|
|
32
|
+
aad: aadForDek(workspaceId, kekVersion)
|
|
33
|
+
});
|
|
34
|
+
} catch {
|
|
35
|
+
throw new DekUnwrapError();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function deriveLocalKekVersion(kek) {
|
|
41
|
+
const hash = crypto.createHash('sha256').update(KEK_VERSION_DOMAIN).update(kek).digest('hex');
|
|
42
|
+
return `local:${hash.slice(0, 16)}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
//# sourceMappingURL=key-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/key-provider.ts"],"sourcesContent":["import crypto from 'node:crypto';\nimport {aadForDek, aesGcmOpen, aesGcmSeal} from './crypto.js';\nimport {DekUnwrapError, DekWrapError} from './errors.js';\n\nconst KEK_VERSION_DOMAIN = 'shipfox-secrets-kek-version';\n\nexport interface WrappedDek {\n wrappedDek: string;\n kekVersion: string;\n}\n\nexport interface KeyProvider {\n readonly currentKeyVersion: string;\n readonly previousKeyVersion: string | null;\n wrapDek(workspaceId: string, plaintextDek: Buffer): WrappedDek;\n unwrapDek(workspaceId: string, wrappedDek: string, kekVersion: string): Buffer;\n}\n\nexport interface LocalKeyProviderParams {\n currentKek: Buffer;\n previousKek?: Buffer | undefined;\n}\n\nexport function createLocalKeyProvider(params: LocalKeyProviderParams): KeyProvider {\n const currentKeyVersion = deriveLocalKekVersion(params.currentKek);\n const previousKeyVersion = params.previousKek ? deriveLocalKekVersion(params.previousKek) : null;\n\n return {\n currentKeyVersion,\n previousKeyVersion,\n wrapDek(workspaceId, plaintextDek) {\n try {\n return {\n wrappedDek: aesGcmSeal({\n key: params.currentKek,\n plaintext: plaintextDek,\n aad: aadForDek(workspaceId, currentKeyVersion),\n }),\n kekVersion: currentKeyVersion,\n };\n } catch {\n throw new DekWrapError();\n }\n },\n unwrapDek(workspaceId, wrappedDek, kekVersion) {\n const key =\n kekVersion === currentKeyVersion\n ? params.currentKek\n : kekVersion === previousKeyVersion\n ? params.previousKek\n : undefined;\n if (!key) throw new DekUnwrapError();\n\n try {\n return aesGcmOpen({\n key,\n encoded: wrappedDek,\n aad: aadForDek(workspaceId, kekVersion),\n });\n } catch {\n throw new DekUnwrapError();\n }\n },\n };\n}\n\nexport function deriveLocalKekVersion(kek: Buffer): string {\n const hash = crypto.createHash('sha256').update(KEK_VERSION_DOMAIN).update(kek).digest('hex');\n return `local:${hash.slice(0, 16)}`;\n}\n"],"names":["crypto","aadForDek","aesGcmOpen","aesGcmSeal","DekUnwrapError","DekWrapError","KEK_VERSION_DOMAIN","createLocalKeyProvider","params","currentKeyVersion","deriveLocalKekVersion","currentKek","previousKeyVersion","previousKek","wrapDek","workspaceId","plaintextDek","wrappedDek","key","plaintext","aad","kekVersion","unwrapDek","undefined","encoded","kek","hash","createHash","update","digest","slice"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,SAAQC,SAAS,EAAEC,UAAU,EAAEC,UAAU,QAAO,cAAc;AAC9D,SAAQC,cAAc,EAAEC,YAAY,QAAO,cAAc;AAEzD,MAAMC,qBAAqB;AAmB3B,OAAO,SAASC,uBAAuBC,MAA8B;IACnE,MAAMC,oBAAoBC,sBAAsBF,OAAOG,UAAU;IACjE,MAAMC,qBAAqBJ,OAAOK,WAAW,GAAGH,sBAAsBF,OAAOK,WAAW,IAAI;IAE5F,OAAO;QACLJ;QACAG;QACAE,SAAQC,WAAW,EAAEC,YAAY;YAC/B,IAAI;gBACF,OAAO;oBACLC,YAAYd,WAAW;wBACrBe,KAAKV,OAAOG,UAAU;wBACtBQ,WAAWH;wBACXI,KAAKnB,UAAUc,aAAaN;oBAC9B;oBACAY,YAAYZ;gBACd;YACF,EAAE,OAAM;gBACN,MAAM,IAAIJ;YACZ;QACF;QACAiB,WAAUP,WAAW,EAAEE,UAAU,EAAEI,UAAU;YAC3C,MAAMH,MACJG,eAAeZ,oBACXD,OAAOG,UAAU,GACjBU,eAAeT,qBACbJ,OAAOK,WAAW,GAClBU;YACR,IAAI,CAACL,KAAK,MAAM,IAAId;YAEpB,IAAI;gBACF,OAAOF,WAAW;oBAChBgB;oBACAM,SAASP;oBACTG,KAAKnB,UAAUc,aAAaM;gBAC9B;YACF,EAAE,OAAM;gBACN,MAAM,IAAIjB;YACZ;QACF;IACF;AACF;AAEA,OAAO,SAASM,sBAAsBe,GAAW;IAC/C,MAAMC,OAAO1B,OAAO2B,UAAU,CAAC,UAAUC,MAAM,CAACtB,oBAAoBsB,MAAM,CAACH,KAAKI,MAAM,CAAC;IACvF,OAAO,CAAC,MAAM,EAAEH,KAAKI,KAAK,CAAC,GAAG,KAAK;AACrC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type StoreScope } from '#db/index.js';
|
|
2
|
+
import type { DekManager } from './dek-manager.js';
|
|
3
|
+
export interface LocalSecretStoreParams {
|
|
4
|
+
dekManager: DekManager;
|
|
5
|
+
}
|
|
6
|
+
export declare function createLocalSecretStore(params: LocalSecretStoreParams): {
|
|
7
|
+
getSecret(input: StoreScope & {
|
|
8
|
+
workspaceId: string;
|
|
9
|
+
namespace: string;
|
|
10
|
+
key: string;
|
|
11
|
+
}): Promise<string | null>;
|
|
12
|
+
getSecretsByNamespace(input: StoreScope & {
|
|
13
|
+
workspaceId: string;
|
|
14
|
+
namespace: string;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
[k: string]: string;
|
|
17
|
+
}>;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=local-secret-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-secret-store.d.ts","sourceRoot":"","sources":["../../src/core/local-secret-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,UAAU,EAChB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAGjD,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,UAAU,CAAC;CACxB;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,sBAAsB;qBAE1C,UAAU,GAAG;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAC;iCActD,UAAU,GAAG;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAC;;;EAoB3F"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { getSecretValueRowWithPrecedence, listSecretValueRowsByNamespace } from '#db/index.js';
|
|
2
|
+
import { decryptSecretValue } from './value-cipher.js';
|
|
3
|
+
export function createLocalSecretStore(params) {
|
|
4
|
+
return {
|
|
5
|
+
async getSecret (input) {
|
|
6
|
+
const row = await getSecretValueRowWithPrecedence(input);
|
|
7
|
+
if (!row) return null;
|
|
8
|
+
const dek = await params.dekManager.getPlaintextDek(input.workspaceId);
|
|
9
|
+
return decryptSecretValue({
|
|
10
|
+
dek,
|
|
11
|
+
workspaceId: row.workspaceId,
|
|
12
|
+
scope: {
|
|
13
|
+
projectId: row.projectId
|
|
14
|
+
},
|
|
15
|
+
namespace: row.namespace,
|
|
16
|
+
key: row.key,
|
|
17
|
+
ciphertext: row.ciphertext
|
|
18
|
+
});
|
|
19
|
+
},
|
|
20
|
+
async getSecretsByNamespace (input) {
|
|
21
|
+
const rows = await listSecretValueRowsByNamespace(input);
|
|
22
|
+
const dek = rows.length > 0 ? await params.dekManager.getPlaintextDek(input.workspaceId) : null;
|
|
23
|
+
return Object.fromEntries(rows.map((row)=>[
|
|
24
|
+
row.key,
|
|
25
|
+
decryptSecretValue({
|
|
26
|
+
dek: dek,
|
|
27
|
+
workspaceId: row.workspaceId,
|
|
28
|
+
scope: {
|
|
29
|
+
projectId: row.projectId
|
|
30
|
+
},
|
|
31
|
+
namespace: row.namespace,
|
|
32
|
+
key: row.key,
|
|
33
|
+
ciphertext: row.ciphertext
|
|
34
|
+
})
|
|
35
|
+
]));
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=local-secret-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/local-secret-store.ts"],"sourcesContent":["import {\n getSecretValueRowWithPrecedence,\n listSecretValueRowsByNamespace,\n type StoreScope,\n} from '#db/index.js';\nimport type {DekManager} from './dek-manager.js';\nimport {decryptSecretValue} from './value-cipher.js';\n\nexport interface LocalSecretStoreParams {\n dekManager: DekManager;\n}\n\nexport function createLocalSecretStore(params: LocalSecretStoreParams) {\n return {\n async getSecret(input: StoreScope & {workspaceId: string; namespace: string; key: string}) {\n const row = await getSecretValueRowWithPrecedence(input);\n if (!row) return null;\n\n const dek = await params.dekManager.getPlaintextDek(input.workspaceId);\n return decryptSecretValue({\n dek,\n workspaceId: row.workspaceId,\n scope: {projectId: row.projectId},\n namespace: row.namespace,\n key: row.key,\n ciphertext: row.ciphertext,\n });\n },\n async getSecretsByNamespace(input: StoreScope & {workspaceId: string; namespace: string}) {\n const rows = await listSecretValueRowsByNamespace(input);\n const dek =\n rows.length > 0 ? await params.dekManager.getPlaintextDek(input.workspaceId) : null;\n\n return Object.fromEntries(\n rows.map((row) => [\n row.key,\n decryptSecretValue({\n dek: dek as Buffer,\n workspaceId: row.workspaceId,\n scope: {projectId: row.projectId},\n namespace: row.namespace,\n key: row.key,\n ciphertext: row.ciphertext,\n }),\n ]),\n );\n },\n };\n}\n"],"names":["getSecretValueRowWithPrecedence","listSecretValueRowsByNamespace","decryptSecretValue","createLocalSecretStore","params","getSecret","input","row","dek","dekManager","getPlaintextDek","workspaceId","scope","projectId","namespace","key","ciphertext","getSecretsByNamespace","rows","length","Object","fromEntries","map"],"mappings":"AAAA,SACEA,+BAA+B,EAC/BC,8BAA8B,QAEzB,eAAe;AAEtB,SAAQC,kBAAkB,QAAO,oBAAoB;AAMrD,OAAO,SAASC,uBAAuBC,MAA8B;IACnE,OAAO;QACL,MAAMC,WAAUC,KAAyE;YACvF,MAAMC,MAAM,MAAMP,gCAAgCM;YAClD,IAAI,CAACC,KAAK,OAAO;YAEjB,MAAMC,MAAM,MAAMJ,OAAOK,UAAU,CAACC,eAAe,CAACJ,MAAMK,WAAW;YACrE,OAAOT,mBAAmB;gBACxBM;gBACAG,aAAaJ,IAAII,WAAW;gBAC5BC,OAAO;oBAACC,WAAWN,IAAIM,SAAS;gBAAA;gBAChCC,WAAWP,IAAIO,SAAS;gBACxBC,KAAKR,IAAIQ,GAAG;gBACZC,YAAYT,IAAIS,UAAU;YAC5B;QACF;QACA,MAAMC,uBAAsBX,KAA4D;YACtF,MAAMY,OAAO,MAAMjB,+BAA+BK;YAClD,MAAME,MACJU,KAAKC,MAAM,GAAG,IAAI,MAAMf,OAAOK,UAAU,CAACC,eAAe,CAACJ,MAAMK,WAAW,IAAI;YAEjF,OAAOS,OAAOC,WAAW,CACvBH,KAAKI,GAAG,CAAC,CAACf,MAAQ;oBAChBA,IAAIQ,GAAG;oBACPb,mBAAmB;wBACjBM,KAAKA;wBACLG,aAAaJ,IAAII,WAAW;wBAC5BC,OAAO;4BAACC,WAAWN,IAAIM,SAAS;wBAAA;wBAChCC,WAAWP,IAAIO,SAAS;wBACxBC,KAAKR,IAAIQ,GAAG;wBACZC,YAAYT,IAAIS,UAAU;oBAC5B;iBACD;QAEL;IACF;AACF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type SecretManagementRow, type StoreScope } from '#db/index.js';
|
|
2
|
+
import type { SecretVariable } from '#db/schema/variables.js';
|
|
3
|
+
import type { DekManager } from './dek-manager.js';
|
|
4
|
+
export interface ManagementEntry {
|
|
5
|
+
key: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}
|
|
8
|
+
export interface ManagementWriteParams extends StoreScope {
|
|
9
|
+
workspaceId: string;
|
|
10
|
+
entries: ManagementEntry[];
|
|
11
|
+
actorId: string;
|
|
12
|
+
}
|
|
13
|
+
export interface ManagementKeyParams extends StoreScope {
|
|
14
|
+
workspaceId: string;
|
|
15
|
+
key: string;
|
|
16
|
+
actorId: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ManagementListParams extends StoreScope {
|
|
19
|
+
workspaceId: string;
|
|
20
|
+
limit: number;
|
|
21
|
+
cursor?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
export declare function createSecretsManagementApi(params: {
|
|
24
|
+
dekManager: DekManager;
|
|
25
|
+
}): {
|
|
26
|
+
listSecrets(input: ManagementListParams): Promise<import("../db/management.js").SecretManagementListResult>;
|
|
27
|
+
listVariables(input: ManagementListParams): Promise<import("../db/management.js").VariableManagementListResult>;
|
|
28
|
+
getVariable(input: StoreScope & {
|
|
29
|
+
workspaceId: string;
|
|
30
|
+
key: string;
|
|
31
|
+
}): Promise<SecretVariable>;
|
|
32
|
+
setSecrets(input: ManagementWriteParams): Promise<SecretManagementRow[]>;
|
|
33
|
+
setVariables(input: ManagementWriteParams): Promise<SecretVariable[]>;
|
|
34
|
+
deleteSecret(input: ManagementKeyParams): Promise<void>;
|
|
35
|
+
deleteVariable(input: ManagementKeyParams): Promise<void>;
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=management.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"management.d.ts","sourceRoot":"","sources":["../../src/core/management.ts"],"names":[],"mappings":"AAUA,OAAO,EAWL,KAAK,mBAAmB,EACxB,KAAK,UAAU,EAKhB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,yBAAyB,CAAC;AAS5D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,kBAAkB,CAAC;AAUjD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAsB,SAAQ,UAAU;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAoB,SAAQ,UAAU;IACrD,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B;AAED,wBAAgB,0BAA0B,CAAC,MAAM,EAAE;IAAC,UAAU,EAAE,UAAU,CAAA;CAAC;uBAE9C,oBAAoB;yBA0BlB,oBAAoB;uBA2BtC,UAAU,GAAG;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAC,GACrD,OAAO,CAAC,cAAc,CAAC;sBA6BF,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC;wBA+EpD,qBAAqB,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;wBAsEjD,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;0BAkCjC,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;EAmClE"}
|