@clef-sh/core 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/artifact/packer.d.ts +2 -1
- package/dist/artifact/packer.d.ts.map +1 -1
- package/dist/artifact/signer.d.ts.map +1 -1
- package/dist/artifact/types.d.ts +7 -3
- package/dist/artifact/types.d.ts.map +1 -1
- package/dist/drift/detector.d.ts +1 -7
- package/dist/drift/detector.d.ts.map +1 -1
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +188 -203
- package/dist/index.js.map +4 -4
- package/dist/index.mjs +187 -206
- package/dist/index.mjs.map +4 -4
- package/dist/kms/index.d.ts +1 -0
- package/dist/kms/index.d.ts.map +1 -1
- package/dist/kms/types.d.ts +1 -0
- package/dist/kms/types.d.ts.map +1 -1
- package/dist/manifest/parser.d.ts.map +1 -1
- package/dist/matrix/manager.d.ts.map +1 -1
- package/dist/report/generator.d.ts.map +1 -1
- package/dist/scanner/index.d.ts.map +1 -1
- package/dist/sops/client.d.ts.map +1 -1
- package/dist/sops/keys.d.ts +9 -0
- package/dist/sops/keys.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -6949,6 +6949,7 @@ __export(src_exports, {
|
|
|
6949
6949
|
SopsMergeDriver: () => SopsMergeDriver,
|
|
6950
6950
|
SopsMissingError: () => SopsMissingError,
|
|
6951
6951
|
SopsVersionError: () => SopsVersionError,
|
|
6952
|
+
VALID_KMS_PROVIDERS: () => VALID_KMS_PROVIDERS,
|
|
6952
6953
|
assertSops: () => assertSops,
|
|
6953
6954
|
buildSigningPayload: () => buildSigningPayload,
|
|
6954
6955
|
checkAll: () => checkAll,
|
|
@@ -6975,7 +6976,7 @@ __export(src_exports, {
|
|
|
6975
6976
|
markResolved: () => markResolved,
|
|
6976
6977
|
matchPatterns: () => matchPatterns,
|
|
6977
6978
|
metadataPath: () => metadataPath,
|
|
6978
|
-
parse: () =>
|
|
6979
|
+
parse: () => parse8,
|
|
6979
6980
|
parseDotenv: () => parseDotenv,
|
|
6980
6981
|
parseIgnoreContent: () => parseIgnoreContent,
|
|
6981
6982
|
parseJson: () => parseJson,
|
|
@@ -7407,6 +7408,12 @@ var ManifestParser = class {
|
|
|
7407
7408
|
"namespaces"
|
|
7408
7409
|
);
|
|
7409
7410
|
}
|
|
7411
|
+
if (!ENV_NAME_PATTERN.test(nsObj.name)) {
|
|
7412
|
+
throw new ManifestValidationError(
|
|
7413
|
+
`Namespace name '${nsObj.name}' is invalid. Names must start with a lowercase letter and contain only lowercase letters, digits, hyphens, and underscores.`,
|
|
7414
|
+
"namespaces"
|
|
7415
|
+
);
|
|
7416
|
+
}
|
|
7410
7417
|
if (!nsObj.description || typeof nsObj.description !== "string") {
|
|
7411
7418
|
throw new ManifestValidationError(
|
|
7412
7419
|
`Namespace '${nsObj.name}' is missing a 'description' string.`,
|
|
@@ -7507,9 +7514,9 @@ var ManifestParser = class {
|
|
|
7507
7514
|
);
|
|
7508
7515
|
}
|
|
7509
7516
|
const siName = siObj.name;
|
|
7510
|
-
if (
|
|
7517
|
+
if (siObj.description != null && typeof siObj.description !== "string") {
|
|
7511
7518
|
throw new ManifestValidationError(
|
|
7512
|
-
`Service identity '${siName}'
|
|
7519
|
+
`Service identity '${siName}' has a non-string 'description'.`,
|
|
7513
7520
|
"service_identities"
|
|
7514
7521
|
);
|
|
7515
7522
|
}
|
|
@@ -7624,7 +7631,7 @@ var ManifestParser = class {
|
|
|
7624
7631
|
}
|
|
7625
7632
|
return {
|
|
7626
7633
|
name: siName,
|
|
7627
|
-
description: siObj.description,
|
|
7634
|
+
description: siObj.description ?? "",
|
|
7628
7635
|
namespaces: siObj.namespaces,
|
|
7629
7636
|
environments: parsedEnvs
|
|
7630
7637
|
};
|
|
@@ -7805,7 +7812,11 @@ function matchesGlob(filePath, pattern) {
|
|
|
7805
7812
|
|
|
7806
7813
|
// src/scanner/index.ts
|
|
7807
7814
|
var ALWAYS_SKIP_EXTENSIONS = [".enc.yaml", ".enc.json"];
|
|
7808
|
-
var ALWAYS_SKIP_NAMES = [
|
|
7815
|
+
var ALWAYS_SKIP_NAMES = [
|
|
7816
|
+
".clef-meta.yaml",
|
|
7817
|
+
".sops.yaml"
|
|
7818
|
+
// contains age public keys and KMS ARNs — configuration, not secrets
|
|
7819
|
+
];
|
|
7809
7820
|
var ALWAYS_SKIP_DIRS = ["node_modules", ".git"];
|
|
7810
7821
|
var MAX_FILE_SIZE = 1024 * 1024;
|
|
7811
7822
|
var ScanRunner = class {
|
|
@@ -8006,9 +8017,9 @@ var ScanRunner = class {
|
|
|
8006
8017
|
};
|
|
8007
8018
|
|
|
8008
8019
|
// src/matrix/manager.ts
|
|
8009
|
-
var
|
|
8020
|
+
var fs6 = __toESM(require("fs"));
|
|
8010
8021
|
var path4 = __toESM(require("path"));
|
|
8011
|
-
var
|
|
8022
|
+
var YAML4 = __toESM(require("yaml"));
|
|
8012
8023
|
|
|
8013
8024
|
// src/pending/metadata.ts
|
|
8014
8025
|
var fs4 = __toESM(require("fs"));
|
|
@@ -8098,6 +8109,20 @@ async function markPendingWithRetry(filePath, keys, setBy, retryDelayMs = 200) {
|
|
|
8098
8109
|
}
|
|
8099
8110
|
}
|
|
8100
8111
|
|
|
8112
|
+
// src/sops/keys.ts
|
|
8113
|
+
var fs5 = __toESM(require("fs"));
|
|
8114
|
+
var YAML3 = __toESM(require("yaml"));
|
|
8115
|
+
function readSopsKeyNames(filePath) {
|
|
8116
|
+
try {
|
|
8117
|
+
const raw = fs5.readFileSync(filePath, "utf-8");
|
|
8118
|
+
const parsed = YAML3.parse(raw);
|
|
8119
|
+
if (parsed === null || parsed === void 0 || typeof parsed !== "object") return null;
|
|
8120
|
+
return Object.keys(parsed).filter((k) => k !== "sops");
|
|
8121
|
+
} catch {
|
|
8122
|
+
return null;
|
|
8123
|
+
}
|
|
8124
|
+
}
|
|
8125
|
+
|
|
8101
8126
|
// src/matrix/manager.ts
|
|
8102
8127
|
var MatrixManager = class {
|
|
8103
8128
|
/**
|
|
@@ -8117,7 +8142,7 @@ var MatrixManager = class {
|
|
|
8117
8142
|
namespace: ns.name,
|
|
8118
8143
|
environment: env.name,
|
|
8119
8144
|
filePath,
|
|
8120
|
-
exists:
|
|
8145
|
+
exists: fs6.existsSync(filePath)
|
|
8121
8146
|
});
|
|
8122
8147
|
}
|
|
8123
8148
|
}
|
|
@@ -8141,8 +8166,8 @@ var MatrixManager = class {
|
|
|
8141
8166
|
*/
|
|
8142
8167
|
async scaffoldCell(cell, sopsClient, manifest) {
|
|
8143
8168
|
const dir = path4.dirname(cell.filePath);
|
|
8144
|
-
if (!
|
|
8145
|
-
|
|
8169
|
+
if (!fs6.existsSync(dir)) {
|
|
8170
|
+
fs6.mkdirSync(dir, { recursive: true });
|
|
8146
8171
|
}
|
|
8147
8172
|
await sopsClient.encrypt(cell.filePath, {}, manifest, cell.environment);
|
|
8148
8173
|
}
|
|
@@ -8211,22 +8236,15 @@ var MatrixManager = class {
|
|
|
8211
8236
|
* SOPS stores key names in plaintext — only values are encrypted.
|
|
8212
8237
|
*/
|
|
8213
8238
|
readKeyNames(filePath) {
|
|
8214
|
-
|
|
8215
|
-
const raw = fs5.readFileSync(filePath, "utf-8");
|
|
8216
|
-
const parsed = YAML3.parse(raw);
|
|
8217
|
-
if (!parsed || typeof parsed !== "object") return [];
|
|
8218
|
-
return Object.keys(parsed).filter((k) => k !== "sops");
|
|
8219
|
-
} catch {
|
|
8220
|
-
return [];
|
|
8221
|
-
}
|
|
8239
|
+
return readSopsKeyNames(filePath) ?? [];
|
|
8222
8240
|
}
|
|
8223
8241
|
/**
|
|
8224
8242
|
* Read the lastModified timestamp from SOPS metadata without decryption.
|
|
8225
8243
|
*/
|
|
8226
8244
|
readLastModified(filePath) {
|
|
8227
8245
|
try {
|
|
8228
|
-
const raw =
|
|
8229
|
-
const parsed =
|
|
8246
|
+
const raw = fs6.readFileSync(filePath, "utf-8");
|
|
8247
|
+
const parsed = YAML4.parse(raw);
|
|
8230
8248
|
const sops = parsed?.sops;
|
|
8231
8249
|
if (sops?.lastmodified) return new Date(String(sops.lastmodified));
|
|
8232
8250
|
return null;
|
|
@@ -8247,8 +8265,8 @@ var MatrixManager = class {
|
|
|
8247
8265
|
};
|
|
8248
8266
|
|
|
8249
8267
|
// src/schema/validator.ts
|
|
8250
|
-
var
|
|
8251
|
-
var
|
|
8268
|
+
var fs7 = __toESM(require("fs"));
|
|
8269
|
+
var YAML5 = __toESM(require("yaml"));
|
|
8252
8270
|
var SchemaValidator = class {
|
|
8253
8271
|
/**
|
|
8254
8272
|
* Read and parse a YAML schema file from disk.
|
|
@@ -8260,13 +8278,13 @@ var SchemaValidator = class {
|
|
|
8260
8278
|
loadSchema(filePath) {
|
|
8261
8279
|
let raw;
|
|
8262
8280
|
try {
|
|
8263
|
-
raw =
|
|
8281
|
+
raw = fs7.readFileSync(filePath, "utf-8");
|
|
8264
8282
|
} catch {
|
|
8265
8283
|
throw new SchemaLoadError(`Could not read schema file at '${filePath}'.`, filePath);
|
|
8266
8284
|
}
|
|
8267
8285
|
let parsed;
|
|
8268
8286
|
try {
|
|
8269
|
-
parsed =
|
|
8287
|
+
parsed = YAML5.parse(raw);
|
|
8270
8288
|
} catch {
|
|
8271
8289
|
throw new SchemaLoadError(`Schema file '${filePath}' contains invalid YAML.`, filePath);
|
|
8272
8290
|
}
|
|
@@ -8567,7 +8585,7 @@ ${details}`
|
|
|
8567
8585
|
};
|
|
8568
8586
|
|
|
8569
8587
|
// src/git/integration.ts
|
|
8570
|
-
var
|
|
8588
|
+
var fs8 = __toESM(require("fs"));
|
|
8571
8589
|
var path7 = __toESM(require("path"));
|
|
8572
8590
|
var PRE_COMMIT_HOOK = `#!/bin/sh
|
|
8573
8591
|
# Clef pre-commit hook \u2014 blocks commits of files missing SOPS encryption metadata
|
|
@@ -8776,14 +8794,14 @@ var GitIntegration = class {
|
|
|
8776
8794
|
});
|
|
8777
8795
|
const gitConfig = configResult.exitCode === 0 && configResult.stdout.trim().length > 0;
|
|
8778
8796
|
const attrFilePath = path7.join(repoRoot, ".gitattributes");
|
|
8779
|
-
const attrContent =
|
|
8797
|
+
const attrContent = fs8.existsSync(attrFilePath) ? fs8.readFileSync(attrFilePath, "utf-8") : "";
|
|
8780
8798
|
const gitattributes = attrContent.includes("merge=sops");
|
|
8781
8799
|
return { gitConfig, gitattributes };
|
|
8782
8800
|
}
|
|
8783
8801
|
async ensureGitattributes(repoRoot) {
|
|
8784
8802
|
const attrPath = path7.join(repoRoot, ".gitattributes");
|
|
8785
8803
|
const mergeRule = "*.enc.yaml merge=sops\n*.enc.json merge=sops";
|
|
8786
|
-
const existing =
|
|
8804
|
+
const existing = fs8.existsSync(attrPath) ? fs8.readFileSync(attrPath, "utf-8") : "";
|
|
8787
8805
|
if (existing.includes("merge=sops")) {
|
|
8788
8806
|
return;
|
|
8789
8807
|
}
|
|
@@ -8831,17 +8849,17 @@ ${mergeRule}
|
|
|
8831
8849
|
};
|
|
8832
8850
|
|
|
8833
8851
|
// src/sops/client.ts
|
|
8834
|
-
var
|
|
8852
|
+
var fs11 = __toESM(require("fs"));
|
|
8835
8853
|
var net = __toESM(require("net"));
|
|
8836
8854
|
var import_crypto = require("crypto");
|
|
8837
|
-
var
|
|
8855
|
+
var YAML6 = __toESM(require("yaml"));
|
|
8838
8856
|
|
|
8839
8857
|
// src/sops/resolver.ts
|
|
8840
|
-
var
|
|
8858
|
+
var fs10 = __toESM(require("fs"));
|
|
8841
8859
|
var path9 = __toESM(require("path"));
|
|
8842
8860
|
|
|
8843
8861
|
// src/sops/bundled.ts
|
|
8844
|
-
var
|
|
8862
|
+
var fs9 = __toESM(require("fs"));
|
|
8845
8863
|
var path8 = __toESM(require("path"));
|
|
8846
8864
|
function tryBundled() {
|
|
8847
8865
|
const platform = process.platform;
|
|
@@ -8856,7 +8874,7 @@ function tryBundled() {
|
|
|
8856
8874
|
const packageMain = require.resolve(`${packageName}/package.json`);
|
|
8857
8875
|
const packageDir = path8.dirname(packageMain);
|
|
8858
8876
|
const binPath = path8.join(packageDir, "bin", binName);
|
|
8859
|
-
return
|
|
8877
|
+
return fs9.existsSync(binPath) ? binPath : null;
|
|
8860
8878
|
} catch {
|
|
8861
8879
|
return null;
|
|
8862
8880
|
}
|
|
@@ -8880,7 +8898,7 @@ function resolveSopsPath() {
|
|
|
8880
8898
|
const envPath = process.env.CLEF_SOPS_PATH?.trim();
|
|
8881
8899
|
if (envPath) {
|
|
8882
8900
|
validateSopsPath(envPath);
|
|
8883
|
-
if (!
|
|
8901
|
+
if (!fs10.existsSync(envPath)) {
|
|
8884
8902
|
throw new Error(`CLEF_SOPS_PATH points to '${envPath}' but the file does not exist.`);
|
|
8885
8903
|
}
|
|
8886
8904
|
cached = { path: envPath, source: "env" };
|
|
@@ -9088,7 +9106,7 @@ var SopsClient = class {
|
|
|
9088
9106
|
}
|
|
9089
9107
|
let parsed;
|
|
9090
9108
|
try {
|
|
9091
|
-
parsed =
|
|
9109
|
+
parsed = YAML6.parse(result.stdout) ?? {};
|
|
9092
9110
|
} catch {
|
|
9093
9111
|
throw new SopsDecryptionError(
|
|
9094
9112
|
`Decrypted content of '${filePath}' is not valid YAML.`,
|
|
@@ -9115,7 +9133,7 @@ var SopsClient = class {
|
|
|
9115
9133
|
async encrypt(filePath, values, manifest, environment) {
|
|
9116
9134
|
await assertSops(this.runner, this.sopsCommand);
|
|
9117
9135
|
const fmt = formatFromPath(filePath);
|
|
9118
|
-
const content = fmt === "json" ? JSON.stringify(values, null, 2) :
|
|
9136
|
+
const content = fmt === "json" ? JSON.stringify(values, null, 2) : YAML6.stringify(values);
|
|
9119
9137
|
const args = this.buildEncryptArgs(filePath, manifest, environment);
|
|
9120
9138
|
const env = this.buildSopsEnv();
|
|
9121
9139
|
let inputArg;
|
|
@@ -9159,7 +9177,7 @@ var SopsClient = class {
|
|
|
9159
9177
|
);
|
|
9160
9178
|
}
|
|
9161
9179
|
try {
|
|
9162
|
-
|
|
9180
|
+
fs11.writeFileSync(filePath, result.stdout);
|
|
9163
9181
|
} catch {
|
|
9164
9182
|
throw new SopsEncryptionError(`Failed to write encrypted data to '${filePath}'.`, filePath);
|
|
9165
9183
|
}
|
|
@@ -9172,21 +9190,7 @@ var SopsClient = class {
|
|
|
9172
9190
|
* @throws {@link SopsEncryptionError} On failure.
|
|
9173
9191
|
*/
|
|
9174
9192
|
async reEncrypt(filePath, newKey) {
|
|
9175
|
-
await
|
|
9176
|
-
const env = this.buildSopsEnv();
|
|
9177
|
-
const result = await this.runner.run(
|
|
9178
|
-
this.sopsCommand,
|
|
9179
|
-
["rotate", "-i", "--add-age", newKey, filePath],
|
|
9180
|
-
{
|
|
9181
|
-
...env ? { env } : {}
|
|
9182
|
-
}
|
|
9183
|
-
);
|
|
9184
|
-
if (result.exitCode !== 0) {
|
|
9185
|
-
throw new SopsEncryptionError(
|
|
9186
|
-
`Failed to re-encrypt '${filePath}': ${result.stderr.trim()}`,
|
|
9187
|
-
filePath
|
|
9188
|
-
);
|
|
9189
|
-
}
|
|
9193
|
+
await this.addRecipient(filePath, newKey);
|
|
9190
9194
|
}
|
|
9191
9195
|
/**
|
|
9192
9196
|
* Add an age recipient to an existing SOPS file.
|
|
@@ -9289,7 +9293,7 @@ var SopsClient = class {
|
|
|
9289
9293
|
if (!this.ageKey && !this.ageKeyFile) return "key-not-found";
|
|
9290
9294
|
let keyContent;
|
|
9291
9295
|
try {
|
|
9292
|
-
keyContent = this.ageKey ??
|
|
9296
|
+
keyContent = this.ageKey ?? fs11.readFileSync(this.ageKeyFile, "utf-8");
|
|
9293
9297
|
} catch {
|
|
9294
9298
|
return "key-not-found";
|
|
9295
9299
|
}
|
|
@@ -9306,7 +9310,7 @@ var SopsClient = class {
|
|
|
9306
9310
|
parseMetadataFromFile(filePath) {
|
|
9307
9311
|
let content;
|
|
9308
9312
|
try {
|
|
9309
|
-
content =
|
|
9313
|
+
content = fs11.readFileSync(filePath, "utf-8");
|
|
9310
9314
|
} catch {
|
|
9311
9315
|
throw new SopsDecryptionError(
|
|
9312
9316
|
`Could not read file '${filePath}' to extract SOPS metadata.`,
|
|
@@ -9315,7 +9319,7 @@ var SopsClient = class {
|
|
|
9315
9319
|
}
|
|
9316
9320
|
let parsed;
|
|
9317
9321
|
try {
|
|
9318
|
-
parsed =
|
|
9322
|
+
parsed = YAML6.parse(content);
|
|
9319
9323
|
} catch {
|
|
9320
9324
|
throw new SopsDecryptionError(
|
|
9321
9325
|
`File '${filePath}' is not valid YAML. Cannot extract SOPS metadata.`,
|
|
@@ -9747,7 +9751,7 @@ var path12 = __toESM(require("path"));
|
|
|
9747
9751
|
|
|
9748
9752
|
// src/import/parsers.ts
|
|
9749
9753
|
var path11 = __toESM(require("path"));
|
|
9750
|
-
var
|
|
9754
|
+
var YAML7 = __toESM(require("yaml"));
|
|
9751
9755
|
function detectFormat(filePath, content) {
|
|
9752
9756
|
const base = path11.basename(filePath);
|
|
9753
9757
|
const ext = path11.extname(filePath).toLowerCase();
|
|
@@ -9771,7 +9775,7 @@ function detectFormat(filePath, content) {
|
|
|
9771
9775
|
} catch {
|
|
9772
9776
|
}
|
|
9773
9777
|
try {
|
|
9774
|
-
const parsed =
|
|
9778
|
+
const parsed = YAML7.parse(content);
|
|
9775
9779
|
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
9776
9780
|
return "yaml";
|
|
9777
9781
|
}
|
|
@@ -9852,7 +9856,7 @@ function parseJson(content) {
|
|
|
9852
9856
|
function parseYaml(content) {
|
|
9853
9857
|
let parsed;
|
|
9854
9858
|
try {
|
|
9855
|
-
parsed =
|
|
9859
|
+
parsed = YAML7.parse(content);
|
|
9856
9860
|
} catch (err) {
|
|
9857
9861
|
throw new Error(`Invalid YAML: ${err.message}`);
|
|
9858
9862
|
}
|
|
@@ -9886,7 +9890,7 @@ function parseYaml(content) {
|
|
|
9886
9890
|
}
|
|
9887
9891
|
return { pairs, format: "yaml", skipped, warnings };
|
|
9888
9892
|
}
|
|
9889
|
-
function
|
|
9893
|
+
function parse8(content, format, filePath) {
|
|
9890
9894
|
const resolved = format === "auto" ? detectFormat(filePath ?? "", content) : format;
|
|
9891
9895
|
switch (resolved) {
|
|
9892
9896
|
case "dotenv":
|
|
@@ -9919,7 +9923,7 @@ var ImportRunner = class {
|
|
|
9919
9923
|
repoRoot,
|
|
9920
9924
|
manifest.file_pattern.replace("{namespace}", ns).replace("{environment}", env)
|
|
9921
9925
|
);
|
|
9922
|
-
const parsed =
|
|
9926
|
+
const parsed = parse8(content, options.format ?? "auto", sourcePath ?? "");
|
|
9923
9927
|
let candidates = Object.entries(parsed.pairs);
|
|
9924
9928
|
if (options.prefix) {
|
|
9925
9929
|
const prefix = options.prefix;
|
|
@@ -9973,9 +9977,9 @@ var ImportRunner = class {
|
|
|
9973
9977
|
};
|
|
9974
9978
|
|
|
9975
9979
|
// src/recipients/index.ts
|
|
9976
|
-
var
|
|
9980
|
+
var fs12 = __toESM(require("fs"));
|
|
9977
9981
|
var path13 = __toESM(require("path"));
|
|
9978
|
-
var
|
|
9982
|
+
var YAML8 = __toESM(require("yaml"));
|
|
9979
9983
|
function parseRecipientEntry(entry) {
|
|
9980
9984
|
if (typeof entry === "string") {
|
|
9981
9985
|
return { key: entry };
|
|
@@ -9998,12 +10002,12 @@ function toRecipient(entry) {
|
|
|
9998
10002
|
}
|
|
9999
10003
|
function readManifestYaml(repoRoot) {
|
|
10000
10004
|
const manifestPath = path13.join(repoRoot, CLEF_MANIFEST_FILENAME);
|
|
10001
|
-
const raw =
|
|
10002
|
-
return
|
|
10005
|
+
const raw = fs12.readFileSync(manifestPath, "utf-8");
|
|
10006
|
+
return YAML8.parse(raw);
|
|
10003
10007
|
}
|
|
10004
10008
|
function writeManifestYaml(repoRoot, doc) {
|
|
10005
10009
|
const manifestPath = path13.join(repoRoot, CLEF_MANIFEST_FILENAME);
|
|
10006
|
-
|
|
10010
|
+
fs12.writeFileSync(manifestPath, YAML8.stringify(doc), "utf-8");
|
|
10007
10011
|
}
|
|
10008
10012
|
function getRecipientsArray(doc) {
|
|
10009
10013
|
const sops = doc.sops;
|
|
@@ -10104,7 +10108,7 @@ var RecipientManager = class {
|
|
|
10104
10108
|
throw new Error(`Recipient '${keyPreview(normalizedKey)}' is already present.`);
|
|
10105
10109
|
}
|
|
10106
10110
|
const manifestPath = path13.join(repoRoot, CLEF_MANIFEST_FILENAME);
|
|
10107
|
-
const manifestBackup =
|
|
10111
|
+
const manifestBackup = fs12.readFileSync(manifestPath, "utf-8");
|
|
10108
10112
|
const recipients = environment ? ensureEnvironmentRecipientsArray(doc, environment) : ensureRecipientsArray(doc);
|
|
10109
10113
|
if (label) {
|
|
10110
10114
|
recipients.push({ key: normalizedKey, label });
|
|
@@ -10119,16 +10123,16 @@ var RecipientManager = class {
|
|
|
10119
10123
|
const fileBackups = /* @__PURE__ */ new Map();
|
|
10120
10124
|
for (const cell of cells) {
|
|
10121
10125
|
try {
|
|
10122
|
-
fileBackups.set(cell.filePath,
|
|
10126
|
+
fileBackups.set(cell.filePath, fs12.readFileSync(cell.filePath, "utf-8"));
|
|
10123
10127
|
await this.encryption.addRecipient(cell.filePath, normalizedKey);
|
|
10124
10128
|
reEncryptedFiles.push(cell.filePath);
|
|
10125
10129
|
} catch {
|
|
10126
10130
|
failedFiles.push(cell.filePath);
|
|
10127
|
-
|
|
10131
|
+
fs12.writeFileSync(manifestPath, manifestBackup, "utf-8");
|
|
10128
10132
|
for (const reEncryptedFile of reEncryptedFiles) {
|
|
10129
10133
|
const backup = fileBackups.get(reEncryptedFile);
|
|
10130
10134
|
if (backup) {
|
|
10131
|
-
|
|
10135
|
+
fs12.writeFileSync(reEncryptedFile, backup, "utf-8");
|
|
10132
10136
|
}
|
|
10133
10137
|
}
|
|
10134
10138
|
const restoredDoc = readManifestYaml(repoRoot);
|
|
@@ -10182,7 +10186,7 @@ var RecipientManager = class {
|
|
|
10182
10186
|
}
|
|
10183
10187
|
const removedEntry = parsed[matchIndex];
|
|
10184
10188
|
const manifestPath = path13.join(repoRoot, CLEF_MANIFEST_FILENAME);
|
|
10185
|
-
const manifestBackup =
|
|
10189
|
+
const manifestBackup = fs12.readFileSync(manifestPath, "utf-8");
|
|
10186
10190
|
const recipients = environment ? ensureEnvironmentRecipientsArray(doc, environment) : ensureRecipientsArray(doc);
|
|
10187
10191
|
recipients.splice(matchIndex, 1);
|
|
10188
10192
|
writeManifestYaml(repoRoot, doc);
|
|
@@ -10193,16 +10197,16 @@ var RecipientManager = class {
|
|
|
10193
10197
|
const fileBackups = /* @__PURE__ */ new Map();
|
|
10194
10198
|
for (const cell of cells) {
|
|
10195
10199
|
try {
|
|
10196
|
-
fileBackups.set(cell.filePath,
|
|
10200
|
+
fileBackups.set(cell.filePath, fs12.readFileSync(cell.filePath, "utf-8"));
|
|
10197
10201
|
await this.encryption.removeRecipient(cell.filePath, trimmedKey);
|
|
10198
10202
|
reEncryptedFiles.push(cell.filePath);
|
|
10199
10203
|
} catch {
|
|
10200
10204
|
failedFiles.push(cell.filePath);
|
|
10201
|
-
|
|
10205
|
+
fs12.writeFileSync(manifestPath, manifestBackup, "utf-8");
|
|
10202
10206
|
for (const reEncryptedFile of reEncryptedFiles) {
|
|
10203
10207
|
const backup = fileBackups.get(reEncryptedFile);
|
|
10204
10208
|
if (backup) {
|
|
10205
|
-
|
|
10209
|
+
fs12.writeFileSync(reEncryptedFile, backup, "utf-8");
|
|
10206
10210
|
}
|
|
10207
10211
|
}
|
|
10208
10212
|
const restoredDoc = readManifestYaml(repoRoot);
|
|
@@ -10236,9 +10240,9 @@ var RecipientManager = class {
|
|
|
10236
10240
|
};
|
|
10237
10241
|
|
|
10238
10242
|
// src/recipients/requests.ts
|
|
10239
|
-
var
|
|
10243
|
+
var fs13 = __toESM(require("fs"));
|
|
10240
10244
|
var path14 = __toESM(require("path"));
|
|
10241
|
-
var
|
|
10245
|
+
var YAML9 = __toESM(require("yaml"));
|
|
10242
10246
|
var REQUESTS_FILENAME = ".clef-requests.yaml";
|
|
10243
10247
|
var HEADER_COMMENT2 = "# Pending recipient access requests. Approve with: clef recipients approve <label>\n";
|
|
10244
10248
|
function requestsFilePath(repoRoot) {
|
|
@@ -10247,9 +10251,9 @@ function requestsFilePath(repoRoot) {
|
|
|
10247
10251
|
function loadRequests(repoRoot) {
|
|
10248
10252
|
const filePath = requestsFilePath(repoRoot);
|
|
10249
10253
|
try {
|
|
10250
|
-
if (!
|
|
10251
|
-
const content =
|
|
10252
|
-
const parsed =
|
|
10254
|
+
if (!fs13.existsSync(filePath)) return [];
|
|
10255
|
+
const content = fs13.readFileSync(filePath, "utf-8");
|
|
10256
|
+
const parsed = YAML9.parse(content);
|
|
10253
10257
|
if (!parsed || !Array.isArray(parsed.requests)) return [];
|
|
10254
10258
|
return parsed.requests.map((r) => ({
|
|
10255
10259
|
key: r.key,
|
|
@@ -10265,7 +10269,7 @@ function saveRequests(repoRoot, requests) {
|
|
|
10265
10269
|
const filePath = requestsFilePath(repoRoot);
|
|
10266
10270
|
if (requests.length === 0) {
|
|
10267
10271
|
try {
|
|
10268
|
-
|
|
10272
|
+
fs13.unlinkSync(filePath);
|
|
10269
10273
|
} catch {
|
|
10270
10274
|
}
|
|
10271
10275
|
return;
|
|
@@ -10281,7 +10285,7 @@ function saveRequests(repoRoot, requests) {
|
|
|
10281
10285
|
return raw;
|
|
10282
10286
|
})
|
|
10283
10287
|
};
|
|
10284
|
-
|
|
10288
|
+
fs13.writeFileSync(filePath, HEADER_COMMENT2 + YAML9.stringify(data), "utf-8");
|
|
10285
10289
|
}
|
|
10286
10290
|
function upsertRequest(repoRoot, key, label, environment) {
|
|
10287
10291
|
const requests = loadRequests(repoRoot);
|
|
@@ -10317,9 +10321,7 @@ function findInList(requests, identifier) {
|
|
|
10317
10321
|
}
|
|
10318
10322
|
|
|
10319
10323
|
// src/drift/detector.ts
|
|
10320
|
-
var fs13 = __toESM(require("fs"));
|
|
10321
10324
|
var path15 = __toESM(require("path"));
|
|
10322
|
-
var YAML9 = __toESM(require("yaml"));
|
|
10323
10325
|
var DriftDetector = class {
|
|
10324
10326
|
parser = new ManifestParser();
|
|
10325
10327
|
matrix = new MatrixManager();
|
|
@@ -10347,45 +10349,30 @@ var DriftDetector = class {
|
|
|
10347
10349
|
}
|
|
10348
10350
|
const issues = [];
|
|
10349
10351
|
let namespacesClean = 0;
|
|
10352
|
+
const remoteEnvSet = new Set(remoteEnvNames);
|
|
10353
|
+
const sharedEnvSet = new Set(localEnvNames.filter((e) => remoteEnvSet.has(e)));
|
|
10350
10354
|
for (const ns of sharedNamespaces) {
|
|
10351
|
-
const
|
|
10352
|
-
const
|
|
10353
|
-
const localNsCells = localCells.filter((c) => c.namespace === ns);
|
|
10354
|
-
for (const cell of localNsCells) {
|
|
10355
|
-
const keys = this.readKeysFromFile(cell.filePath);
|
|
10356
|
-
if (keys === null) continue;
|
|
10357
|
-
allEnvs.add(cell.environment);
|
|
10358
|
-
for (const key of keys) {
|
|
10359
|
-
if (!keyEnvs.has(key)) keyEnvs.set(key, /* @__PURE__ */ new Set());
|
|
10360
|
-
keyEnvs.get(key).add(cell.environment);
|
|
10361
|
-
}
|
|
10362
|
-
}
|
|
10363
|
-
const remoteNsCells = remoteCells.filter((c) => c.namespace === ns);
|
|
10364
|
-
for (const cell of remoteNsCells) {
|
|
10365
|
-
const keys = this.readKeysFromFile(cell.filePath);
|
|
10366
|
-
if (keys === null) continue;
|
|
10367
|
-
allEnvs.add(cell.environment);
|
|
10368
|
-
for (const key of keys) {
|
|
10369
|
-
if (!keyEnvs.has(key)) keyEnvs.set(key, /* @__PURE__ */ new Set());
|
|
10370
|
-
keyEnvs.get(key).add(cell.environment);
|
|
10371
|
-
}
|
|
10372
|
-
}
|
|
10373
|
-
const envList = [...allEnvs];
|
|
10355
|
+
const localKeyEnvs = this.collectKeyEnvs(localCells, ns, sharedEnvSet);
|
|
10356
|
+
const remoteKeyEnvs = this.collectKeyEnvs(remoteCells, ns, sharedEnvSet);
|
|
10374
10357
|
let nsClean = true;
|
|
10375
|
-
|
|
10376
|
-
const
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10358
|
+
const reportDrift = (sourceMap, targetMap, direction) => {
|
|
10359
|
+
for (const [key, sourceEnvs] of sourceMap) {
|
|
10360
|
+
const targetEnvs = targetMap.get(key);
|
|
10361
|
+
const missingFrom = [...sourceEnvs].filter((e) => !targetEnvs?.has(e)).sort();
|
|
10362
|
+
if (missingFrom.length > 0) {
|
|
10363
|
+
nsClean = false;
|
|
10364
|
+
issues.push({
|
|
10365
|
+
namespace: ns,
|
|
10366
|
+
key,
|
|
10367
|
+
presentIn: [...sourceEnvs].sort(),
|
|
10368
|
+
missingFrom,
|
|
10369
|
+
message: `Key '${key}' in namespace '${ns}' exists in ${direction} [${[...sourceEnvs].sort().join(", ")}] but is missing from [${missingFrom.join(", ")}]`
|
|
10370
|
+
});
|
|
10371
|
+
}
|
|
10387
10372
|
}
|
|
10388
|
-
}
|
|
10373
|
+
};
|
|
10374
|
+
reportDrift(remoteKeyEnvs, localKeyEnvs, "remote");
|
|
10375
|
+
reportDrift(localKeyEnvs, remoteKeyEnvs, "local");
|
|
10389
10376
|
if (nsClean) namespacesClean++;
|
|
10390
10377
|
}
|
|
10391
10378
|
return {
|
|
@@ -10396,29 +10383,23 @@ var DriftDetector = class {
|
|
|
10396
10383
|
remoteEnvironments: remoteEnvNames
|
|
10397
10384
|
};
|
|
10398
10385
|
}
|
|
10399
|
-
|
|
10400
|
-
|
|
10401
|
-
|
|
10402
|
-
|
|
10403
|
-
|
|
10404
|
-
|
|
10405
|
-
|
|
10406
|
-
|
|
10407
|
-
|
|
10408
|
-
|
|
10409
|
-
const parsed = YAML9.parse(raw);
|
|
10410
|
-
if (parsed === null || parsed === void 0 || typeof parsed !== "object") return null;
|
|
10411
|
-
return Object.keys(parsed).filter((k) => k !== "sops");
|
|
10412
|
-
} catch {
|
|
10413
|
-
return null;
|
|
10386
|
+
collectKeyEnvs(cells, ns, sharedEnvSet) {
|
|
10387
|
+
const keyEnvs = /* @__PURE__ */ new Map();
|
|
10388
|
+
for (const cell of cells) {
|
|
10389
|
+
if (cell.namespace !== ns || !sharedEnvSet.has(cell.environment)) continue;
|
|
10390
|
+
const keys = readSopsKeyNames(cell.filePath);
|
|
10391
|
+
if (keys === null) continue;
|
|
10392
|
+
for (const key of keys) {
|
|
10393
|
+
if (!keyEnvs.has(key)) keyEnvs.set(key, /* @__PURE__ */ new Set());
|
|
10394
|
+
keyEnvs.get(key).add(cell.environment);
|
|
10395
|
+
}
|
|
10414
10396
|
}
|
|
10397
|
+
return keyEnvs;
|
|
10415
10398
|
}
|
|
10416
10399
|
};
|
|
10417
10400
|
|
|
10418
10401
|
// src/report/generator.ts
|
|
10419
|
-
var fs14 = __toESM(require("fs"));
|
|
10420
10402
|
var path16 = __toESM(require("path"));
|
|
10421
|
-
var YAML10 = __toESM(require("yaml"));
|
|
10422
10403
|
|
|
10423
10404
|
// src/report/sanitizer.ts
|
|
10424
10405
|
var ReportSanitizer = class {
|
|
@@ -10723,15 +10704,7 @@ var ReportGenerator = class {
|
|
|
10723
10704
|
};
|
|
10724
10705
|
}
|
|
10725
10706
|
readKeyCount(filePath) {
|
|
10726
|
-
|
|
10727
|
-
if (!fs14.existsSync(filePath)) return 0;
|
|
10728
|
-
const raw = fs14.readFileSync(filePath, "utf-8");
|
|
10729
|
-
const parsed = YAML10.parse(raw);
|
|
10730
|
-
if (parsed === null || parsed === void 0 || typeof parsed !== "object") return 0;
|
|
10731
|
-
return Object.keys(parsed).filter((k) => k !== "sops").length;
|
|
10732
|
-
} catch {
|
|
10733
|
-
return 0;
|
|
10734
|
-
}
|
|
10707
|
+
return readSopsKeyNames(filePath)?.length ?? 0;
|
|
10735
10708
|
}
|
|
10736
10709
|
async buildPolicy(manifest, repoRoot) {
|
|
10737
10710
|
try {
|
|
@@ -11060,10 +11033,10 @@ var SopsMergeDriver = class {
|
|
|
11060
11033
|
};
|
|
11061
11034
|
|
|
11062
11035
|
// src/service-identity/manager.ts
|
|
11063
|
-
var
|
|
11036
|
+
var fs14 = __toESM(require("fs"));
|
|
11064
11037
|
var os = __toESM(require("os"));
|
|
11065
11038
|
var path17 = __toESM(require("path"));
|
|
11066
|
-
var
|
|
11039
|
+
var YAML10 = __toESM(require("yaml"));
|
|
11067
11040
|
var PartialRotationError = class extends Error {
|
|
11068
11041
|
constructor(message, rotatedKeys) {
|
|
11069
11042
|
super(message);
|
|
@@ -11115,8 +11088,8 @@ var ServiceIdentityManager = class {
|
|
|
11115
11088
|
};
|
|
11116
11089
|
await this.registerRecipients(definition, manifest, repoRoot);
|
|
11117
11090
|
const manifestPath = path17.join(repoRoot, CLEF_MANIFEST_FILENAME);
|
|
11118
|
-
const raw =
|
|
11119
|
-
const doc =
|
|
11091
|
+
const raw = fs14.readFileSync(manifestPath, "utf-8");
|
|
11092
|
+
const doc = YAML10.parse(raw);
|
|
11120
11093
|
if (!Array.isArray(doc.service_identities)) {
|
|
11121
11094
|
doc.service_identities = [];
|
|
11122
11095
|
}
|
|
@@ -11128,11 +11101,11 @@ var ServiceIdentityManager = class {
|
|
|
11128
11101
|
});
|
|
11129
11102
|
const tmpCreate = path17.join(os.tmpdir(), `clef-manifest-${process.pid}-${Date.now()}.tmp`);
|
|
11130
11103
|
try {
|
|
11131
|
-
|
|
11132
|
-
|
|
11104
|
+
fs14.writeFileSync(tmpCreate, YAML10.stringify(doc), "utf-8");
|
|
11105
|
+
fs14.renameSync(tmpCreate, manifestPath);
|
|
11133
11106
|
} finally {
|
|
11134
11107
|
try {
|
|
11135
|
-
|
|
11108
|
+
fs14.unlinkSync(tmpCreate);
|
|
11136
11109
|
} catch {
|
|
11137
11110
|
}
|
|
11138
11111
|
}
|
|
@@ -11171,8 +11144,8 @@ var ServiceIdentityManager = class {
|
|
|
11171
11144
|
}
|
|
11172
11145
|
}
|
|
11173
11146
|
const manifestPath = path17.join(repoRoot, CLEF_MANIFEST_FILENAME);
|
|
11174
|
-
const raw =
|
|
11175
|
-
const doc =
|
|
11147
|
+
const raw = fs14.readFileSync(manifestPath, "utf-8");
|
|
11148
|
+
const doc = YAML10.parse(raw);
|
|
11176
11149
|
const identities = doc.service_identities;
|
|
11177
11150
|
if (Array.isArray(identities)) {
|
|
11178
11151
|
doc.service_identities = identities.filter(
|
|
@@ -11181,11 +11154,11 @@ var ServiceIdentityManager = class {
|
|
|
11181
11154
|
}
|
|
11182
11155
|
const tmp = path17.join(os.tmpdir(), `clef-manifest-${process.pid}-${Date.now()}.tmp`);
|
|
11183
11156
|
try {
|
|
11184
|
-
|
|
11185
|
-
|
|
11157
|
+
fs14.writeFileSync(tmp, YAML10.stringify(doc), "utf-8");
|
|
11158
|
+
fs14.renameSync(tmp, manifestPath);
|
|
11186
11159
|
} finally {
|
|
11187
11160
|
try {
|
|
11188
|
-
|
|
11161
|
+
fs14.unlinkSync(tmp);
|
|
11189
11162
|
} catch {
|
|
11190
11163
|
}
|
|
11191
11164
|
}
|
|
@@ -11201,8 +11174,8 @@ var ServiceIdentityManager = class {
|
|
|
11201
11174
|
throw new Error(`Service identity '${name}' not found.`);
|
|
11202
11175
|
}
|
|
11203
11176
|
const manifestPath = path17.join(repoRoot, CLEF_MANIFEST_FILENAME);
|
|
11204
|
-
const raw =
|
|
11205
|
-
const doc =
|
|
11177
|
+
const raw = fs14.readFileSync(manifestPath, "utf-8");
|
|
11178
|
+
const doc = YAML10.parse(raw);
|
|
11206
11179
|
const identities = doc.service_identities;
|
|
11207
11180
|
const siDoc = identities.find((si) => si.name === name);
|
|
11208
11181
|
const envs = siDoc.environments;
|
|
@@ -11229,11 +11202,11 @@ var ServiceIdentityManager = class {
|
|
|
11229
11202
|
}
|
|
11230
11203
|
const tmp = path17.join(os.tmpdir(), `clef-manifest-${process.pid}-${Date.now()}.tmp`);
|
|
11231
11204
|
try {
|
|
11232
|
-
|
|
11233
|
-
|
|
11205
|
+
fs14.writeFileSync(tmp, YAML10.stringify(doc), "utf-8");
|
|
11206
|
+
fs14.renameSync(tmp, manifestPath);
|
|
11234
11207
|
} finally {
|
|
11235
11208
|
try {
|
|
11236
|
-
|
|
11209
|
+
fs14.unlinkSync(tmp);
|
|
11237
11210
|
} catch {
|
|
11238
11211
|
}
|
|
11239
11212
|
}
|
|
@@ -11270,8 +11243,8 @@ var ServiceIdentityManager = class {
|
|
|
11270
11243
|
throw new Error(`Service identity '${name}' not found.`);
|
|
11271
11244
|
}
|
|
11272
11245
|
const manifestPath = path17.join(repoRoot, CLEF_MANIFEST_FILENAME);
|
|
11273
|
-
const raw =
|
|
11274
|
-
const doc =
|
|
11246
|
+
const raw = fs14.readFileSync(manifestPath, "utf-8");
|
|
11247
|
+
const doc = YAML10.parse(raw);
|
|
11275
11248
|
const identities = doc.service_identities;
|
|
11276
11249
|
const siDoc = identities.find((si) => si.name === name);
|
|
11277
11250
|
const envs = siDoc.environments;
|
|
@@ -11326,11 +11299,11 @@ var ServiceIdentityManager = class {
|
|
|
11326
11299
|
}
|
|
11327
11300
|
const tmpRotate = path17.join(os.tmpdir(), `clef-manifest-${process.pid}-${Date.now()}.tmp`);
|
|
11328
11301
|
try {
|
|
11329
|
-
|
|
11330
|
-
|
|
11302
|
+
fs14.writeFileSync(tmpRotate, YAML10.stringify(doc), "utf-8");
|
|
11303
|
+
fs14.renameSync(tmpRotate, manifestPath);
|
|
11331
11304
|
} finally {
|
|
11332
11305
|
try {
|
|
11333
|
-
|
|
11306
|
+
fs14.unlinkSync(tmpRotate);
|
|
11334
11307
|
} catch {
|
|
11335
11308
|
}
|
|
11336
11309
|
}
|
|
@@ -11451,7 +11424,7 @@ async function resolveIdentitySecrets(identityName, environment, manifest, repoR
|
|
|
11451
11424
|
}
|
|
11452
11425
|
|
|
11453
11426
|
// src/artifact/packer.ts
|
|
11454
|
-
var
|
|
11427
|
+
var fs15 = __toESM(require("fs"));
|
|
11455
11428
|
var path18 = __toESM(require("path"));
|
|
11456
11429
|
var crypto4 = __toESM(require("crypto"));
|
|
11457
11430
|
|
|
@@ -11459,7 +11432,7 @@ var crypto4 = __toESM(require("crypto"));
|
|
|
11459
11432
|
var crypto3 = __toESM(require("crypto"));
|
|
11460
11433
|
function buildSigningPayload(artifact) {
|
|
11461
11434
|
const fields = [
|
|
11462
|
-
"clef-sig-
|
|
11435
|
+
"clef-sig-v2",
|
|
11463
11436
|
String(artifact.version),
|
|
11464
11437
|
artifact.identity,
|
|
11465
11438
|
artifact.environment,
|
|
@@ -11471,7 +11444,9 @@ function buildSigningPayload(artifact) {
|
|
|
11471
11444
|
artifact.envelope?.provider ?? "",
|
|
11472
11445
|
artifact.envelope?.keyId ?? "",
|
|
11473
11446
|
artifact.envelope?.wrappedKey ?? "",
|
|
11474
|
-
artifact.envelope?.algorithm ?? ""
|
|
11447
|
+
artifact.envelope?.algorithm ?? "",
|
|
11448
|
+
artifact.envelope?.iv ?? "",
|
|
11449
|
+
artifact.envelope?.authTag ?? ""
|
|
11475
11450
|
];
|
|
11476
11451
|
return Buffer.from(fields.join("\n"), "utf-8");
|
|
11477
11452
|
}
|
|
@@ -11565,37 +11540,41 @@ var ArtifactPacker = class {
|
|
|
11565
11540
|
if (!this.kms) {
|
|
11566
11541
|
throw new Error("KMS provider required for envelope encryption but none was provided.");
|
|
11567
11542
|
}
|
|
11568
|
-
const
|
|
11569
|
-
const
|
|
11570
|
-
const ephemeralPublicKey = await identityToRecipient(ephemeralPrivateKey);
|
|
11543
|
+
const dek = crypto4.randomBytes(32);
|
|
11544
|
+
const iv = crypto4.randomBytes(12);
|
|
11571
11545
|
try {
|
|
11572
|
-
const
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
|
|
11576
|
-
|
|
11577
|
-
|
|
11546
|
+
const cipher = crypto4.createCipheriv("aes-256-gcm", dek, iv);
|
|
11547
|
+
const ciphertextBuf = Buffer.concat([
|
|
11548
|
+
cipher.update(Buffer.from(plaintext, "utf-8")),
|
|
11549
|
+
cipher.final()
|
|
11550
|
+
]);
|
|
11551
|
+
const authTag = cipher.getAuthTag();
|
|
11552
|
+
ciphertext = ciphertextBuf.toString("base64");
|
|
11553
|
+
const kmsConfig = resolved.envConfig.kms;
|
|
11554
|
+
const wrapped = await this.kms.wrap(kmsConfig.keyId, dek);
|
|
11555
|
+
const revision = `${Date.now()}-${crypto4.randomBytes(4).toString("hex")}`;
|
|
11556
|
+
const ciphertextHash = crypto4.createHash("sha256").update(ciphertext).digest("hex");
|
|
11557
|
+
artifact = {
|
|
11558
|
+
version: 1,
|
|
11559
|
+
identity: config.identity,
|
|
11560
|
+
environment: config.environment,
|
|
11561
|
+
packedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11562
|
+
revision,
|
|
11563
|
+
ciphertextHash,
|
|
11564
|
+
ciphertext,
|
|
11565
|
+
keys: Object.keys(resolved.values),
|
|
11566
|
+
envelope: {
|
|
11567
|
+
provider: kmsConfig.provider,
|
|
11568
|
+
keyId: kmsConfig.keyId,
|
|
11569
|
+
wrappedKey: wrapped.wrappedKey.toString("base64"),
|
|
11570
|
+
algorithm: wrapped.algorithm,
|
|
11571
|
+
iv: iv.toString("base64"),
|
|
11572
|
+
authTag: authTag.toString("base64")
|
|
11573
|
+
}
|
|
11574
|
+
};
|
|
11575
|
+
} finally {
|
|
11576
|
+
dek.fill(0);
|
|
11578
11577
|
}
|
|
11579
|
-
const kmsConfig = resolved.envConfig.kms;
|
|
11580
|
-
const wrapped = await this.kms.wrap(kmsConfig.keyId, Buffer.from(ephemeralPrivateKey));
|
|
11581
|
-
const revision = `${Date.now()}-${crypto4.randomBytes(4).toString("hex")}`;
|
|
11582
|
-
const ciphertextHash = crypto4.createHash("sha256").update(ciphertext).digest("hex");
|
|
11583
|
-
artifact = {
|
|
11584
|
-
version: 1,
|
|
11585
|
-
identity: config.identity,
|
|
11586
|
-
environment: config.environment,
|
|
11587
|
-
packedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
11588
|
-
revision,
|
|
11589
|
-
ciphertextHash,
|
|
11590
|
-
ciphertext,
|
|
11591
|
-
keys: Object.keys(resolved.values),
|
|
11592
|
-
envelope: {
|
|
11593
|
-
provider: kmsConfig.provider,
|
|
11594
|
-
keyId: kmsConfig.keyId,
|
|
11595
|
-
wrappedKey: wrapped.wrappedKey.toString("base64"),
|
|
11596
|
-
algorithm: wrapped.algorithm
|
|
11597
|
-
}
|
|
11598
|
-
};
|
|
11599
11578
|
} else {
|
|
11600
11579
|
try {
|
|
11601
11580
|
const { Encrypter } = await Promise.resolve().then(() => __toESM(require_age_encryption()));
|
|
@@ -11603,8 +11582,10 @@ var ArtifactPacker = class {
|
|
|
11603
11582
|
e.addRecipient(resolved.recipient);
|
|
11604
11583
|
const encrypted = await e.encrypt(plaintext);
|
|
11605
11584
|
ciphertext = Buffer.from(encrypted).toString("base64");
|
|
11606
|
-
} catch {
|
|
11607
|
-
throw new Error(
|
|
11585
|
+
} catch (err) {
|
|
11586
|
+
throw new Error(
|
|
11587
|
+
`Failed to age-encrypt artifact: ${err instanceof Error ? err.message : String(err)}`
|
|
11588
|
+
);
|
|
11608
11589
|
}
|
|
11609
11590
|
const revision = `${Date.now()}-${crypto4.randomBytes(4).toString("hex")}`;
|
|
11610
11591
|
const ciphertextHash = crypto4.createHash("sha256").update(ciphertext).digest("hex");
|
|
@@ -11620,8 +11601,8 @@ var ArtifactPacker = class {
|
|
|
11620
11601
|
};
|
|
11621
11602
|
}
|
|
11622
11603
|
const outputDir = path18.dirname(config.outputPath);
|
|
11623
|
-
if (!
|
|
11624
|
-
|
|
11604
|
+
if (!fs15.existsSync(outputDir)) {
|
|
11605
|
+
fs15.mkdirSync(outputDir, { recursive: true });
|
|
11625
11606
|
}
|
|
11626
11607
|
if (config.ttl && config.ttl > 0) {
|
|
11627
11608
|
artifact.expiresAt = new Date(Date.now() + config.ttl * 1e3).toISOString();
|
|
@@ -11640,8 +11621,8 @@ var ArtifactPacker = class {
|
|
|
11640
11621
|
}
|
|
11641
11622
|
const json = JSON.stringify(artifact, null, 2);
|
|
11642
11623
|
const tmpOutput = `${config.outputPath}.tmp.${process.pid}`;
|
|
11643
|
-
|
|
11644
|
-
|
|
11624
|
+
fs15.writeFileSync(tmpOutput, json, "utf-8");
|
|
11625
|
+
fs15.renameSync(tmpOutput, config.outputPath);
|
|
11645
11626
|
return {
|
|
11646
11627
|
outputPath: config.outputPath,
|
|
11647
11628
|
namespaceCount: resolved.identity.namespaces.length,
|
|
@@ -11651,6 +11632,9 @@ var ArtifactPacker = class {
|
|
|
11651
11632
|
};
|
|
11652
11633
|
}
|
|
11653
11634
|
};
|
|
11635
|
+
|
|
11636
|
+
// src/kms/types.ts
|
|
11637
|
+
var VALID_KMS_PROVIDERS = ["aws", "gcp", "azure"];
|
|
11654
11638
|
// Annotate the CommonJS export names for ESM import in node:
|
|
11655
11639
|
0 && (module.exports = {
|
|
11656
11640
|
ArtifactPacker,
|
|
@@ -11689,6 +11673,7 @@ var ArtifactPacker = class {
|
|
|
11689
11673
|
SopsMergeDriver,
|
|
11690
11674
|
SopsMissingError,
|
|
11691
11675
|
SopsVersionError,
|
|
11676
|
+
VALID_KMS_PROVIDERS,
|
|
11692
11677
|
assertSops,
|
|
11693
11678
|
buildSigningPayload,
|
|
11694
11679
|
checkAll,
|