@clef-sh/core 0.1.7-beta.48 → 0.1.8

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.mjs CHANGED
@@ -4457,7 +4457,87 @@ async function resolveIdentitySecrets(identityName, environment, manifest, repoR
4457
4457
  // src/artifact/packer.ts
4458
4458
  import * as fs16 from "fs";
4459
4459
  import * as path18 from "path";
4460
+ import * as crypto3 from "crypto";
4461
+
4462
+ // src/artifact/signer.ts
4460
4463
  import * as crypto2 from "crypto";
4464
+ function buildSigningPayload(artifact) {
4465
+ const fields = [
4466
+ "clef-sig-v1",
4467
+ String(artifact.version),
4468
+ artifact.identity,
4469
+ artifact.environment,
4470
+ artifact.revision,
4471
+ artifact.packedAt,
4472
+ artifact.ciphertextHash,
4473
+ [...artifact.keys].sort().join(","),
4474
+ artifact.expiresAt ?? "",
4475
+ artifact.envelope?.provider ?? "",
4476
+ artifact.envelope?.keyId ?? "",
4477
+ artifact.envelope?.wrappedKey ?? "",
4478
+ artifact.envelope?.algorithm ?? ""
4479
+ ];
4480
+ return Buffer.from(fields.join("\n"), "utf-8");
4481
+ }
4482
+ function generateSigningKeyPair() {
4483
+ const pair = crypto2.generateKeyPairSync("ed25519");
4484
+ return {
4485
+ publicKey: pair.publicKey.export({ type: "spki", format: "der" }).toString(
4486
+ "base64"
4487
+ ),
4488
+ privateKey: pair.privateKey.export({ type: "pkcs8", format: "der" }).toString(
4489
+ "base64"
4490
+ )
4491
+ };
4492
+ }
4493
+ function signEd25519(payload, privateKeyBase64) {
4494
+ const keyObj = crypto2.createPrivateKey({
4495
+ key: Buffer.from(privateKeyBase64, "base64"),
4496
+ format: "der",
4497
+ type: "pkcs8"
4498
+ });
4499
+ const signature = crypto2.sign(null, payload, keyObj);
4500
+ return signature.toString("base64");
4501
+ }
4502
+ async function signKms(payload, kms, signingKeyId) {
4503
+ if (!kms.sign) {
4504
+ throw new Error(
4505
+ "KMS provider does not support signing. Ensure the provider implements the sign() method."
4506
+ );
4507
+ }
4508
+ const digest = crypto2.createHash("sha256").update(payload).digest();
4509
+ const signature = await kms.sign(signingKeyId, digest);
4510
+ return signature.toString("base64");
4511
+ }
4512
+ function verifySignature(payload, signatureBase64, publicKeyBase64) {
4513
+ const keyObj = crypto2.createPublicKey({
4514
+ key: Buffer.from(publicKeyBase64, "base64"),
4515
+ format: "der",
4516
+ type: "spki"
4517
+ });
4518
+ const signature = Buffer.from(signatureBase64, "base64");
4519
+ const keyType = keyObj.asymmetricKeyType;
4520
+ if (keyType === "ed25519") {
4521
+ return crypto2.verify(null, payload, keyObj, signature);
4522
+ }
4523
+ if (keyType === "ec") {
4524
+ return crypto2.verify("sha256", payload, keyObj, signature);
4525
+ }
4526
+ throw new Error(`Unsupported key type for signature verification: ${keyType}`);
4527
+ }
4528
+ function detectAlgorithm(publicKeyBase64) {
4529
+ const keyObj = crypto2.createPublicKey({
4530
+ key: Buffer.from(publicKeyBase64, "base64"),
4531
+ format: "der",
4532
+ type: "spki"
4533
+ });
4534
+ const keyType = keyObj.asymmetricKeyType;
4535
+ if (keyType === "ed25519") return "Ed25519";
4536
+ if (keyType === "ec") return "ECDSA_SHA256";
4537
+ throw new Error(`Unsupported key type: ${keyType}`);
4538
+ }
4539
+
4540
+ // src/artifact/packer.ts
4461
4541
  var ArtifactPacker = class {
4462
4542
  constructor(encryption, matrixManager, kms) {
4463
4543
  this.encryption = encryption;
@@ -4469,6 +4549,11 @@ var ArtifactPacker = class {
4469
4549
  * values to the service identity's recipient, and write a JSON envelope.
4470
4550
  */
4471
4551
  async pack(config, manifest, repoRoot) {
4552
+ if (config.signingKey && config.signingKmsKeyId) {
4553
+ throw new Error(
4554
+ "Cannot specify both signingKey (Ed25519) and signingKmsKeyId (KMS). Choose one."
4555
+ );
4556
+ }
4472
4557
  const resolved = await resolveIdentitySecrets(
4473
4558
  config.identity,
4474
4559
  config.environment,
@@ -4500,8 +4585,8 @@ var ArtifactPacker = class {
4500
4585
  }
4501
4586
  const kmsConfig = resolved.envConfig.kms;
4502
4587
  const wrapped = await this.kms.wrap(kmsConfig.keyId, Buffer.from(ephemeralPrivateKey));
4503
- const revision = `${Date.now()}-${crypto2.randomBytes(4).toString("hex")}`;
4504
- const ciphertextHash = crypto2.createHash("sha256").update(ciphertext).digest("hex");
4588
+ const revision = `${Date.now()}-${crypto3.randomBytes(4).toString("hex")}`;
4589
+ const ciphertextHash = crypto3.createHash("sha256").update(ciphertext).digest("hex");
4505
4590
  artifact = {
4506
4591
  version: 1,
4507
4592
  identity: config.identity,
@@ -4528,8 +4613,8 @@ var ArtifactPacker = class {
4528
4613
  } catch {
4529
4614
  throw new Error("Failed to age-encrypt artifact. Check recipient key.");
4530
4615
  }
4531
- const revision = `${Date.now()}-${crypto2.randomBytes(4).toString("hex")}`;
4532
- const ciphertextHash = crypto2.createHash("sha256").update(ciphertext).digest("hex");
4616
+ const revision = `${Date.now()}-${crypto3.randomBytes(4).toString("hex")}`;
4617
+ const ciphertextHash = crypto3.createHash("sha256").update(ciphertext).digest("hex");
4533
4618
  artifact = {
4534
4619
  version: 1,
4535
4620
  identity: config.identity,
@@ -4548,6 +4633,18 @@ var ArtifactPacker = class {
4548
4633
  if (config.ttl && config.ttl > 0) {
4549
4634
  artifact.expiresAt = new Date(Date.now() + config.ttl * 1e3).toISOString();
4550
4635
  }
4636
+ if (config.signingKey) {
4637
+ const payload = buildSigningPayload(artifact);
4638
+ artifact.signature = signEd25519(payload, config.signingKey);
4639
+ artifact.signatureAlgorithm = "Ed25519";
4640
+ } else if (config.signingKmsKeyId) {
4641
+ if (!this.kms) {
4642
+ throw new Error("KMS provider required for KMS signing but none was provided.");
4643
+ }
4644
+ const payload = buildSigningPayload(artifact);
4645
+ artifact.signature = await signKms(payload, this.kms, config.signingKmsKeyId);
4646
+ artifact.signatureAlgorithm = "ECDSA_SHA256";
4647
+ }
4551
4648
  const json = JSON.stringify(artifact, null, 2);
4552
4649
  const tmpOutput = `${config.outputPath}.tmp.${process.pid}`;
4553
4650
  fs16.writeFileSync(tmpOutput, json, "utf-8");
@@ -4599,15 +4696,18 @@ export {
4599
4696
  SopsMissingError,
4600
4697
  SopsVersionError,
4601
4698
  assertSops,
4699
+ buildSigningPayload,
4602
4700
  checkAll,
4603
4701
  checkDependency,
4604
4702
  collectCIContext,
4605
4703
  deriveAgePublicKey,
4704
+ detectAlgorithm,
4606
4705
  detectFormat,
4607
4706
  findRequest,
4608
4707
  formatAgeKeyFile,
4609
4708
  generateAgeIdentity,
4610
4709
  generateRandomValue,
4710
+ generateSigningKeyPair,
4611
4711
  getPendingKeys,
4612
4712
  isHighEntropy,
4613
4713
  isKmsEnvelope,
@@ -4639,7 +4739,10 @@ export {
4639
4739
  shannonEntropy,
4640
4740
  shouldIgnoreFile,
4641
4741
  shouldIgnoreMatch,
4742
+ signEd25519,
4743
+ signKms,
4642
4744
  upsertRequest,
4643
- validateAgePublicKey
4745
+ validateAgePublicKey,
4746
+ verifySignature
4644
4747
  };
4645
4748
  //# sourceMappingURL=index.mjs.map