@clef-sh/core 0.1.15 → 0.1.16-beta.110
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/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +83 -44
- package/dist/index.js.map +2 -2
- package/dist/index.mjs +83 -44
- package/dist/index.mjs.map +2 -2
- package/dist/lint/runner.d.ts.map +1 -1
- package/dist/manifest/parser.d.ts.map +1 -1
- package/dist/service-identity/manager.d.ts +13 -5
- package/dist/service-identity/manager.d.ts.map +1 -1
- package/dist/types/index.d.ts +4 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -34,6 +34,7 @@ export { ReportGenerator, ReportSanitizer, ReportTransformer, CloudClient, colle
|
|
|
34
34
|
export { SopsMergeDriver } from "./merge/driver";
|
|
35
35
|
export type { MergeResult, MergeKey, MergeKeyStatus } from "./merge/driver";
|
|
36
36
|
export { ServiceIdentityManager } from "./service-identity/manager";
|
|
37
|
+
export type { CreateServiceIdentityOptions } from "./service-identity/manager";
|
|
37
38
|
export { StructureManager } from "./structure/manager";
|
|
38
39
|
export type { NamespaceEditOptions, EnvironmentEditOptions, AddNamespaceOptions, AddEnvironmentOptions, } from "./structure/manager";
|
|
39
40
|
export { resolveIdentitySecrets } from "./artifact/resolve";
|
package/dist/index.d.ts
CHANGED
|
@@ -34,6 +34,7 @@ export { ReportGenerator, ReportSanitizer, ReportTransformer, CloudClient, colle
|
|
|
34
34
|
export { SopsMergeDriver } from "./merge/driver";
|
|
35
35
|
export type { MergeResult, MergeKey, MergeKeyStatus } from "./merge/driver";
|
|
36
36
|
export { ServiceIdentityManager } from "./service-identity/manager";
|
|
37
|
+
export type { CreateServiceIdentityOptions } from "./service-identity/manager";
|
|
37
38
|
export { StructureManager } from "./structure/manager";
|
|
38
39
|
export type { NamespaceEditOptions, EnvironmentEditOptions, AddNamespaceOptions, AddEnvironmentOptions, } from "./structure/manager";
|
|
39
40
|
export { resolveIdentitySecrets } from "./artifact/resolve";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -9624,6 +9624,12 @@ var ManifestParser = class {
|
|
|
9624
9624
|
"service_identities"
|
|
9625
9625
|
);
|
|
9626
9626
|
}
|
|
9627
|
+
if (siObj.pack_only !== void 0 && typeof siObj.pack_only !== "boolean") {
|
|
9628
|
+
throw new ManifestValidationError(
|
|
9629
|
+
`Service identity '${siName}' has a non-boolean 'pack_only' field.`,
|
|
9630
|
+
"service_identities"
|
|
9631
|
+
);
|
|
9632
|
+
}
|
|
9627
9633
|
if (!Array.isArray(siObj.namespaces) || siObj.namespaces.length === 0) {
|
|
9628
9634
|
throw new ManifestValidationError(
|
|
9629
9635
|
`Service identity '${siName}' must have a non-empty 'namespaces' array.`,
|
|
@@ -9729,7 +9735,8 @@ var ManifestParser = class {
|
|
|
9729
9735
|
name: siName,
|
|
9730
9736
|
description: siObj.description ?? "",
|
|
9731
9737
|
namespaces: siObj.namespaces,
|
|
9732
|
-
environments: parsedEnvs
|
|
9738
|
+
environments: parsedEnvs,
|
|
9739
|
+
...siObj.pack_only === true ? { pack_only: true } : {}
|
|
9733
9740
|
};
|
|
9734
9741
|
});
|
|
9735
9742
|
const siNames = /* @__PURE__ */ new Set();
|
|
@@ -12075,6 +12082,18 @@ var LintRunner = class {
|
|
|
12075
12082
|
});
|
|
12076
12083
|
}
|
|
12077
12084
|
}
|
|
12085
|
+
if (si.pack_only) {
|
|
12086
|
+
const ageRecipients = Object.values(si.environments).filter((cfg) => !isKmsEnvelope(cfg) && cfg.recipient).map((cfg) => cfg.recipient);
|
|
12087
|
+
if (ageRecipients.length >= 2 && new Set(ageRecipients).size === 1) {
|
|
12088
|
+
issues.push({
|
|
12089
|
+
severity: "warning",
|
|
12090
|
+
category: "service-identity",
|
|
12091
|
+
file: "clef.yaml",
|
|
12092
|
+
message: `Runtime identity '${si.name}' uses a shared recipient across all environments. A compromised key in any environment decrypts artifacts for all environments. Consider per-environment keys for runtime workloads.`
|
|
12093
|
+
});
|
|
12094
|
+
}
|
|
12095
|
+
continue;
|
|
12096
|
+
}
|
|
12078
12097
|
for (const cell of existingCells) {
|
|
12079
12098
|
const envConfig = si.environments[cell.environment];
|
|
12080
12099
|
if (!envConfig) continue;
|
|
@@ -13434,12 +13453,10 @@ var ServiceIdentityManager = class {
|
|
|
13434
13453
|
* Create a new service identity with per-environment age key pairs or KMS envelope config.
|
|
13435
13454
|
* For age-only: generates keys, updates the manifest, and registers public keys as SOPS recipients.
|
|
13436
13455
|
* For KMS: stores KMS config in manifest, no age keys generated.
|
|
13437
|
-
*
|
|
13438
|
-
* @param kmsEnvConfigs - Optional per-environment KMS config. When provided, those envs use
|
|
13439
|
-
* KMS envelope encryption instead of generating age keys.
|
|
13440
|
-
* @returns The created identity definition and the per-environment private keys (empty for KMS envs).
|
|
13456
|
+
* For pack-only (runtime) identities: keys are generated but NOT registered on SOPS files.
|
|
13441
13457
|
*/
|
|
13442
|
-
async create(name, namespaces, description, manifest, repoRoot,
|
|
13458
|
+
async create(name, namespaces, description, manifest, repoRoot, options) {
|
|
13459
|
+
const { kmsEnvConfigs, sharedRecipient, packOnly } = options ?? {};
|
|
13443
13460
|
if (manifest.service_identities?.some((si) => si.name === name)) {
|
|
13444
13461
|
throw new Error(`Service identity '${name}' already exists.`);
|
|
13445
13462
|
}
|
|
@@ -13451,23 +13468,25 @@ var ServiceIdentityManager = class {
|
|
|
13451
13468
|
}
|
|
13452
13469
|
const environments = {};
|
|
13453
13470
|
const privateKeys = {};
|
|
13471
|
+
const sharedKey = sharedRecipient ? await generateAgeIdentity() : void 0;
|
|
13454
13472
|
for (const env of manifest.environments) {
|
|
13455
13473
|
const kmsConfig = kmsEnvConfigs?.[env.name];
|
|
13456
13474
|
if (kmsConfig) {
|
|
13457
13475
|
environments[env.name] = { kms: kmsConfig };
|
|
13458
13476
|
} else {
|
|
13459
|
-
const
|
|
13460
|
-
environments[env.name] = { recipient:
|
|
13461
|
-
privateKeys[env.name] =
|
|
13477
|
+
const ageIdentity = sharedKey ?? await generateAgeIdentity();
|
|
13478
|
+
environments[env.name] = { recipient: ageIdentity.publicKey };
|
|
13479
|
+
privateKeys[env.name] = ageIdentity.privateKey;
|
|
13462
13480
|
}
|
|
13463
13481
|
}
|
|
13464
13482
|
const definition = {
|
|
13465
13483
|
name,
|
|
13466
13484
|
description,
|
|
13467
13485
|
namespaces,
|
|
13468
|
-
environments
|
|
13486
|
+
environments,
|
|
13487
|
+
...packOnly ? { pack_only: true } : {}
|
|
13469
13488
|
};
|
|
13470
|
-
const cells = this.matrixManager.resolveMatrix(manifest, repoRoot).filter((c) => c.exists && namespaces.includes(c.namespace));
|
|
13489
|
+
const cells = packOnly ? [] : this.matrixManager.resolveMatrix(manifest, repoRoot).filter((c) => c.exists && namespaces.includes(c.namespace));
|
|
13471
13490
|
await this.tx.run(repoRoot, {
|
|
13472
13491
|
description: `clef service create ${name}`,
|
|
13473
13492
|
paths: this.txPaths(repoRoot, cells),
|
|
@@ -13481,12 +13500,13 @@ var ServiceIdentityManager = class {
|
|
|
13481
13500
|
name,
|
|
13482
13501
|
description,
|
|
13483
13502
|
namespaces,
|
|
13484
|
-
environments
|
|
13503
|
+
environments,
|
|
13504
|
+
...packOnly ? { pack_only: true } : {}
|
|
13485
13505
|
});
|
|
13486
13506
|
writeManifestYaml(repoRoot, doc);
|
|
13487
13507
|
}
|
|
13488
13508
|
});
|
|
13489
|
-
return { identity: definition, privateKeys };
|
|
13509
|
+
return { identity: definition, privateKeys, sharedRecipient: sharedKey !== void 0 };
|
|
13490
13510
|
}
|
|
13491
13511
|
/**
|
|
13492
13512
|
* List all service identities from the manifest.
|
|
@@ -13509,7 +13529,7 @@ var ServiceIdentityManager = class {
|
|
|
13509
13529
|
if (!identity) {
|
|
13510
13530
|
throw new Error(`Service identity '${name}' not found.`);
|
|
13511
13531
|
}
|
|
13512
|
-
const scopedCells = this.matrixManager.resolveMatrix(manifest, repoRoot).filter((c) => c.exists && identity.namespaces.includes(c.namespace));
|
|
13532
|
+
const scopedCells = identity.pack_only ? [] : this.matrixManager.resolveMatrix(manifest, repoRoot).filter((c) => c.exists && identity.namespaces.includes(c.namespace));
|
|
13513
13533
|
await this.tx.run(repoRoot, {
|
|
13514
13534
|
description: `clef service delete ${name}`,
|
|
13515
13535
|
paths: this.txPaths(repoRoot, scopedCells),
|
|
@@ -13565,7 +13585,7 @@ var ServiceIdentityManager = class {
|
|
|
13565
13585
|
const envs = siDoc.environments;
|
|
13566
13586
|
for (const [envName, kmsConfig] of Object.entries(kmsEnvConfigs)) {
|
|
13567
13587
|
const oldConfig = identity.environments[envName];
|
|
13568
|
-
if (oldConfig?.recipient && !isKmsEnvelope(oldConfig)) {
|
|
13588
|
+
if (!identity.pack_only && oldConfig?.recipient && !isKmsEnvelope(oldConfig)) {
|
|
13569
13589
|
const scopedCells = cells.filter((c) => c.environment === envName);
|
|
13570
13590
|
for (const cell of scopedCells) {
|
|
13571
13591
|
try {
|
|
@@ -13584,8 +13604,10 @@ var ServiceIdentityManager = class {
|
|
|
13584
13604
|
}
|
|
13585
13605
|
/**
|
|
13586
13606
|
* Register a service identity's public keys as SOPS recipients on scoped matrix files.
|
|
13607
|
+
* Pack-only (runtime) identities skip registration entirely.
|
|
13587
13608
|
*/
|
|
13588
13609
|
async registerRecipients(identity, manifest, repoRoot) {
|
|
13610
|
+
if (identity.pack_only) return;
|
|
13589
13611
|
const cells = this.matrixManager.resolveMatrix(manifest, repoRoot).filter((c) => c.exists);
|
|
13590
13612
|
for (const cell of cells) {
|
|
13591
13613
|
if (!identity.namespaces.includes(cell.namespace)) continue;
|
|
@@ -13635,18 +13657,20 @@ var ServiceIdentityManager = class {
|
|
|
13635
13657
|
description: `clef service update ${name}: add namespaces ${toAdd.join(",")}`,
|
|
13636
13658
|
paths: this.txPaths(repoRoot, cells),
|
|
13637
13659
|
mutate: async () => {
|
|
13638
|
-
|
|
13639
|
-
const
|
|
13640
|
-
|
|
13641
|
-
|
|
13642
|
-
|
|
13643
|
-
|
|
13644
|
-
|
|
13645
|
-
|
|
13646
|
-
|
|
13647
|
-
|
|
13648
|
-
|
|
13649
|
-
|
|
13660
|
+
if (!identity.pack_only) {
|
|
13661
|
+
for (const cell of cells) {
|
|
13662
|
+
const envConfig = identity.environments[cell.environment];
|
|
13663
|
+
if (!envConfig) continue;
|
|
13664
|
+
if (isKmsEnvelope(envConfig)) continue;
|
|
13665
|
+
if (!envConfig.recipient) continue;
|
|
13666
|
+
try {
|
|
13667
|
+
await this.encryption.addRecipient(cell.filePath, envConfig.recipient);
|
|
13668
|
+
affectedFiles.push(cell.filePath);
|
|
13669
|
+
} catch (err) {
|
|
13670
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
13671
|
+
if (!message.includes("already")) {
|
|
13672
|
+
throw err;
|
|
13673
|
+
}
|
|
13650
13674
|
}
|
|
13651
13675
|
}
|
|
13652
13676
|
}
|
|
@@ -13694,15 +13718,17 @@ var ServiceIdentityManager = class {
|
|
|
13694
13718
|
description: `clef service update ${name}: remove namespaces ${namespacesToRemove.join(",")}`,
|
|
13695
13719
|
paths: this.txPaths(repoRoot, cells),
|
|
13696
13720
|
mutate: async () => {
|
|
13697
|
-
|
|
13698
|
-
const
|
|
13699
|
-
|
|
13700
|
-
|
|
13701
|
-
|
|
13702
|
-
|
|
13703
|
-
|
|
13704
|
-
|
|
13705
|
-
|
|
13721
|
+
if (!identity.pack_only) {
|
|
13722
|
+
for (const cell of cells) {
|
|
13723
|
+
const envConfig = identity.environments[cell.environment];
|
|
13724
|
+
if (!envConfig) continue;
|
|
13725
|
+
if (isKmsEnvelope(envConfig)) continue;
|
|
13726
|
+
if (!envConfig.recipient) continue;
|
|
13727
|
+
try {
|
|
13728
|
+
await this.encryption.removeRecipient(cell.filePath, envConfig.recipient);
|
|
13729
|
+
affectedFiles.push(cell.filePath);
|
|
13730
|
+
} catch {
|
|
13731
|
+
}
|
|
13706
13732
|
}
|
|
13707
13733
|
}
|
|
13708
13734
|
const doc = readManifestYaml(repoRoot);
|
|
@@ -13765,7 +13791,7 @@ var ServiceIdentityManager = class {
|
|
|
13765
13791
|
description: `clef service add-env ${name} ${envName}`,
|
|
13766
13792
|
paths: this.txPaths(repoRoot, cells),
|
|
13767
13793
|
mutate: async () => {
|
|
13768
|
-
if (!isKmsEnvelope(envConfig) && envConfig.recipient) {
|
|
13794
|
+
if (!identity.pack_only && !isKmsEnvelope(envConfig) && envConfig.recipient) {
|
|
13769
13795
|
for (const cell of cells) {
|
|
13770
13796
|
try {
|
|
13771
13797
|
await this.encryption.addRecipient(cell.filePath, envConfig.recipient);
|
|
@@ -13824,7 +13850,7 @@ var ServiceIdentityManager = class {
|
|
|
13824
13850
|
if (targetEnvNames.size === 0) {
|
|
13825
13851
|
return newPrivateKeys;
|
|
13826
13852
|
}
|
|
13827
|
-
const cells = this.matrixManager.resolveMatrix(manifest, repoRoot).filter(
|
|
13853
|
+
const cells = identity.pack_only ? [] : this.matrixManager.resolveMatrix(manifest, repoRoot).filter(
|
|
13828
13854
|
(c) => c.exists && identity.namespaces.includes(c.namespace) && targetEnvNames.has(c.environment)
|
|
13829
13855
|
);
|
|
13830
13856
|
await this.tx.run(repoRoot, {
|
|
@@ -13841,13 +13867,15 @@ var ServiceIdentityManager = class {
|
|
|
13841
13867
|
const oldRecipient = identity.environments[envName].recipient;
|
|
13842
13868
|
const newPublicKey = newPublicKeys[envName];
|
|
13843
13869
|
envs[envName] = { recipient: newPublicKey };
|
|
13844
|
-
|
|
13845
|
-
|
|
13846
|
-
|
|
13847
|
-
|
|
13848
|
-
|
|
13870
|
+
if (!identity.pack_only) {
|
|
13871
|
+
const scopedCells = cells.filter((c) => c.environment === envName);
|
|
13872
|
+
for (const cell of scopedCells) {
|
|
13873
|
+
try {
|
|
13874
|
+
await this.encryption.removeRecipient(cell.filePath, oldRecipient);
|
|
13875
|
+
} catch {
|
|
13876
|
+
}
|
|
13877
|
+
await this.encryption.addRecipient(cell.filePath, newPublicKey);
|
|
13849
13878
|
}
|
|
13850
|
-
await this.encryption.addRecipient(cell.filePath, newPublicKey);
|
|
13851
13879
|
}
|
|
13852
13880
|
}
|
|
13853
13881
|
writeManifestYaml(repoRoot, doc);
|
|
@@ -13887,6 +13915,17 @@ var ServiceIdentityManager = class {
|
|
|
13887
13915
|
});
|
|
13888
13916
|
}
|
|
13889
13917
|
}
|
|
13918
|
+
if (si.pack_only) {
|
|
13919
|
+
const ageRecipients = Object.values(si.environments).filter((cfg) => !isKmsEnvelope(cfg) && cfg.recipient).map((cfg) => cfg.recipient);
|
|
13920
|
+
if (ageRecipients.length >= 2 && new Set(ageRecipients).size === 1) {
|
|
13921
|
+
issues.push({
|
|
13922
|
+
identity: si.name,
|
|
13923
|
+
type: "runtime_shared_recipient",
|
|
13924
|
+
message: `Runtime identity '${si.name}' uses a shared recipient across all environments. A compromised key in any environment decrypts artifacts for all environments. Consider per-environment keys for runtime workloads.`
|
|
13925
|
+
});
|
|
13926
|
+
}
|
|
13927
|
+
continue;
|
|
13928
|
+
}
|
|
13890
13929
|
for (const cell of cells) {
|
|
13891
13930
|
const envConfig = si.environments[cell.environment];
|
|
13892
13931
|
if (!envConfig) continue;
|