@clef-sh/cli 0.1.7-beta.45 → 0.1.8-beta.52

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.cjs CHANGED
@@ -5872,8 +5872,8 @@ var require_int2 = __commonJS({
5872
5872
  var stringifyNumber = require_stringifyNumber();
5873
5873
  var intIdentify = (value) => typeof value === "bigint" || Number.isInteger(value);
5874
5874
  function intResolve(str2, offset, radix, { intAsBigInt }) {
5875
- const sign = str2[0];
5876
- if (sign === "-" || sign === "+")
5875
+ const sign2 = str2[0];
5876
+ if (sign2 === "-" || sign2 === "+")
5877
5877
  offset += 1;
5878
5878
  str2 = str2.substring(offset).replace(/_/g, "");
5879
5879
  if (intAsBigInt) {
@@ -5889,10 +5889,10 @@ var require_int2 = __commonJS({
5889
5889
  break;
5890
5890
  }
5891
5891
  const n2 = BigInt(str2);
5892
- return sign === "-" ? BigInt(-1) * n2 : n2;
5892
+ return sign2 === "-" ? BigInt(-1) * n2 : n2;
5893
5893
  }
5894
5894
  const n = parseInt(str2, radix);
5895
- return sign === "-" ? -1 * n : n;
5895
+ return sign2 === "-" ? -1 * n : n;
5896
5896
  }
5897
5897
  function intStringify(node, radix, prefix) {
5898
5898
  const { value } = node;
@@ -6039,11 +6039,11 @@ var require_timestamp = __commonJS({
6039
6039
  "use strict";
6040
6040
  var stringifyNumber = require_stringifyNumber();
6041
6041
  function parseSexagesimal(str2, asBigInt) {
6042
- const sign = str2[0];
6043
- const parts = sign === "-" || sign === "+" ? str2.substring(1) : str2;
6042
+ const sign2 = str2[0];
6043
+ const parts = sign2 === "-" || sign2 === "+" ? str2.substring(1) : str2;
6044
6044
  const num2 = (n) => asBigInt ? BigInt(n) : Number(n);
6045
6045
  const res = parts.replace(/_/g, "").split(":").reduce((res2, p) => res2 * num2(60) + num2(p), num2(0));
6046
- return sign === "-" ? num2(-1) * res : res;
6046
+ return sign2 === "-" ? num2(-1) * res : res;
6047
6047
  }
6048
6048
  function stringifySexagesimal(node) {
6049
6049
  let { value } = node;
@@ -6052,9 +6052,9 @@ var require_timestamp = __commonJS({
6052
6052
  num2 = (n) => BigInt(n);
6053
6053
  else if (isNaN(value) || !isFinite(value))
6054
6054
  return stringifyNumber.stringifyNumber(node);
6055
- let sign = "";
6055
+ let sign2 = "";
6056
6056
  if (value < 0) {
6057
- sign = "-";
6057
+ sign2 = "-";
6058
6058
  value *= num2(-1);
6059
6059
  }
6060
6060
  const _60 = num2(60);
@@ -6069,7 +6069,7 @@ var require_timestamp = __commonJS({
6069
6069
  parts.unshift(value);
6070
6070
  }
6071
6071
  }
6072
- return sign + parts.map((n) => String(n).padStart(2, "0")).join(":").replace(/000000\d*$/, "");
6072
+ return sign2 + parts.map((n) => String(n).padStart(2, "0")).join(":").replace(/000000\d*$/, "");
6073
6073
  }
6074
6074
  var intTime = {
6075
6075
  identify: (value) => typeof value === "bigint" || Number.isInteger(value),
@@ -15991,13 +15991,13 @@ var require_age_encryption = __commonJS({
15991
15991
  }
15992
15992
  return { seed, k2sig };
15993
15993
  }
15994
- function sign(message, secretKey, opts2 = {}) {
15994
+ function sign2(message, secretKey, opts2 = {}) {
15995
15995
  const { seed, k2sig } = prepSig(message, secretKey, opts2);
15996
15996
  const drbg = createHmacDrbg(hash.outputLen, Fn.BYTES, hmac4);
15997
15997
  const sig = drbg(seed, k2sig);
15998
15998
  return sig.toBytes(opts2.format);
15999
15999
  }
16000
- function verify(signature, message, publicKey, opts2 = {}) {
16000
+ function verify2(signature, message, publicKey, opts2 = {}) {
16001
16001
  const { lowS, prehash, format } = validateSigOpts(opts2, defaultSigOpts);
16002
16002
  publicKey = abytes4(publicKey, void 0, "publicKey");
16003
16003
  message = validateMsgAndHash(message, prehash);
@@ -16037,8 +16037,8 @@ var require_age_encryption = __commonJS({
16037
16037
  utils,
16038
16038
  lengths,
16039
16039
  Point,
16040
- sign,
16041
- verify,
16040
+ sign: sign2,
16041
+ verify: verify2,
16042
16042
  recoverPublicKey,
16043
16043
  Signature,
16044
16044
  hash
@@ -21863,16 +21863,101 @@ var init_resolve = __esm({
21863
21863
  }
21864
21864
  });
21865
21865
 
21866
+ // ../core/src/artifact/signer.ts
21867
+ function buildSigningPayload(artifact) {
21868
+ const fields = [
21869
+ "clef-sig-v1",
21870
+ String(artifact.version),
21871
+ artifact.identity,
21872
+ artifact.environment,
21873
+ artifact.revision,
21874
+ artifact.packedAt,
21875
+ artifact.ciphertextHash,
21876
+ [...artifact.keys].sort().join(","),
21877
+ artifact.expiresAt ?? "",
21878
+ artifact.envelope?.provider ?? "",
21879
+ artifact.envelope?.keyId ?? "",
21880
+ artifact.envelope?.wrappedKey ?? "",
21881
+ artifact.envelope?.algorithm ?? ""
21882
+ ];
21883
+ return Buffer.from(fields.join("\n"), "utf-8");
21884
+ }
21885
+ function generateSigningKeyPair() {
21886
+ const pair = crypto3.generateKeyPairSync("ed25519");
21887
+ return {
21888
+ publicKey: pair.publicKey.export({ type: "spki", format: "der" }).toString(
21889
+ "base64"
21890
+ ),
21891
+ privateKey: pair.privateKey.export({ type: "pkcs8", format: "der" }).toString(
21892
+ "base64"
21893
+ )
21894
+ };
21895
+ }
21896
+ function signEd25519(payload, privateKeyBase64) {
21897
+ const keyObj = crypto3.createPrivateKey({
21898
+ key: Buffer.from(privateKeyBase64, "base64"),
21899
+ format: "der",
21900
+ type: "pkcs8"
21901
+ });
21902
+ const signature = crypto3.sign(null, payload, keyObj);
21903
+ return signature.toString("base64");
21904
+ }
21905
+ async function signKms(payload, kms, signingKeyId) {
21906
+ if (!kms.sign) {
21907
+ throw new Error(
21908
+ "KMS provider does not support signing. Ensure the provider implements the sign() method."
21909
+ );
21910
+ }
21911
+ const digest = crypto3.createHash("sha256").update(payload).digest();
21912
+ const signature = await kms.sign(signingKeyId, digest);
21913
+ return signature.toString("base64");
21914
+ }
21915
+ function verifySignature(payload, signatureBase64, publicKeyBase64) {
21916
+ const keyObj = crypto3.createPublicKey({
21917
+ key: Buffer.from(publicKeyBase64, "base64"),
21918
+ format: "der",
21919
+ type: "spki"
21920
+ });
21921
+ const signature = Buffer.from(signatureBase64, "base64");
21922
+ const keyType = keyObj.asymmetricKeyType;
21923
+ if (keyType === "ed25519") {
21924
+ return crypto3.verify(null, payload, keyObj, signature);
21925
+ }
21926
+ if (keyType === "ec") {
21927
+ return crypto3.verify("sha256", payload, keyObj, signature);
21928
+ }
21929
+ throw new Error(`Unsupported key type for signature verification: ${keyType}`);
21930
+ }
21931
+ function detectAlgorithm(publicKeyBase64) {
21932
+ const keyObj = crypto3.createPublicKey({
21933
+ key: Buffer.from(publicKeyBase64, "base64"),
21934
+ format: "der",
21935
+ type: "spki"
21936
+ });
21937
+ const keyType = keyObj.asymmetricKeyType;
21938
+ if (keyType === "ed25519") return "Ed25519";
21939
+ if (keyType === "ec") return "ECDSA_SHA256";
21940
+ throw new Error(`Unsupported key type: ${keyType}`);
21941
+ }
21942
+ var crypto3;
21943
+ var init_signer = __esm({
21944
+ "../core/src/artifact/signer.ts"() {
21945
+ "use strict";
21946
+ crypto3 = __toESM(require("crypto"));
21947
+ }
21948
+ });
21949
+
21866
21950
  // ../core/src/artifact/packer.ts
21867
- var fs16, path18, crypto3, ArtifactPacker;
21951
+ var fs16, path18, crypto4, ArtifactPacker;
21868
21952
  var init_packer = __esm({
21869
21953
  "../core/src/artifact/packer.ts"() {
21870
21954
  "use strict";
21871
21955
  fs16 = __toESM(require("fs"));
21872
21956
  path18 = __toESM(require("path"));
21873
- crypto3 = __toESM(require("crypto"));
21957
+ crypto4 = __toESM(require("crypto"));
21874
21958
  init_types();
21875
21959
  init_resolve();
21960
+ init_signer();
21876
21961
  ArtifactPacker = class {
21877
21962
  constructor(encryption, matrixManager, kms) {
21878
21963
  this.encryption = encryption;
@@ -21884,6 +21969,11 @@ var init_packer = __esm({
21884
21969
  * values to the service identity's recipient, and write a JSON envelope.
21885
21970
  */
21886
21971
  async pack(config, manifest, repoRoot) {
21972
+ if (config.signingKey && config.signingKmsKeyId) {
21973
+ throw new Error(
21974
+ "Cannot specify both signingKey (Ed25519) and signingKmsKeyId (KMS). Choose one."
21975
+ );
21976
+ }
21887
21977
  const resolved = await resolveIdentitySecrets(
21888
21978
  config.identity,
21889
21979
  config.environment,
@@ -21912,8 +22002,8 @@ var init_packer = __esm({
21912
22002
  }
21913
22003
  const kmsConfig = resolved.envConfig.kms;
21914
22004
  const wrapped = await this.kms.wrap(kmsConfig.keyId, Buffer.from(ephemeralPrivateKey));
21915
- const revision = `${Date.now()}-${crypto3.randomBytes(4).toString("hex")}`;
21916
- const ciphertextHash = crypto3.createHash("sha256").update(ciphertext).digest("hex");
22005
+ const revision = `${Date.now()}-${crypto4.randomBytes(4).toString("hex")}`;
22006
+ const ciphertextHash = crypto4.createHash("sha256").update(ciphertext).digest("hex");
21917
22007
  artifact = {
21918
22008
  version: 1,
21919
22009
  identity: config.identity,
@@ -21940,8 +22030,8 @@ var init_packer = __esm({
21940
22030
  } catch {
21941
22031
  throw new Error("Failed to age-encrypt artifact. Check recipient key.");
21942
22032
  }
21943
- const revision = `${Date.now()}-${crypto3.randomBytes(4).toString("hex")}`;
21944
- const ciphertextHash = crypto3.createHash("sha256").update(ciphertext).digest("hex");
22033
+ const revision = `${Date.now()}-${crypto4.randomBytes(4).toString("hex")}`;
22034
+ const ciphertextHash = crypto4.createHash("sha256").update(ciphertext).digest("hex");
21945
22035
  artifact = {
21946
22036
  version: 1,
21947
22037
  identity: config.identity,
@@ -21960,6 +22050,18 @@ var init_packer = __esm({
21960
22050
  if (config.ttl && config.ttl > 0) {
21961
22051
  artifact.expiresAt = new Date(Date.now() + config.ttl * 1e3).toISOString();
21962
22052
  }
22053
+ if (config.signingKey) {
22054
+ const payload = buildSigningPayload(artifact);
22055
+ artifact.signature = signEd25519(payload, config.signingKey);
22056
+ artifact.signatureAlgorithm = "Ed25519";
22057
+ } else if (config.signingKmsKeyId) {
22058
+ if (!this.kms) {
22059
+ throw new Error("KMS provider required for KMS signing but none was provided.");
22060
+ }
22061
+ const payload = buildSigningPayload(artifact);
22062
+ artifact.signature = await signKms(payload, this.kms, config.signingKmsKeyId);
22063
+ artifact.signatureAlgorithm = "ECDSA_SHA256";
22064
+ }
21963
22065
  const json = JSON.stringify(artifact, null, 2);
21964
22066
  const tmpOutput = `${config.outputPath}.tmp.${process.pid}`;
21965
22067
  fs16.writeFileSync(tmpOutput, json, "utf-8");
@@ -22016,15 +22118,18 @@ __export(src_exports, {
22016
22118
  SopsMissingError: () => SopsMissingError,
22017
22119
  SopsVersionError: () => SopsVersionError,
22018
22120
  assertSops: () => assertSops,
22121
+ buildSigningPayload: () => buildSigningPayload,
22019
22122
  checkAll: () => checkAll,
22020
22123
  checkDependency: () => checkDependency,
22021
22124
  collectCIContext: () => collectCIContext,
22022
22125
  deriveAgePublicKey: () => deriveAgePublicKey,
22126
+ detectAlgorithm: () => detectAlgorithm,
22023
22127
  detectFormat: () => detectFormat,
22024
22128
  findRequest: () => findRequest,
22025
22129
  formatAgeKeyFile: () => formatAgeKeyFile,
22026
22130
  generateAgeIdentity: () => generateAgeIdentity,
22027
22131
  generateRandomValue: () => generateRandomValue,
22132
+ generateSigningKeyPair: () => generateSigningKeyPair,
22028
22133
  getPendingKeys: () => getPendingKeys,
22029
22134
  isHighEntropy: () => isHighEntropy,
22030
22135
  isKmsEnvelope: () => isKmsEnvelope,
@@ -22056,8 +22161,11 @@ __export(src_exports, {
22056
22161
  shannonEntropy: () => shannonEntropy,
22057
22162
  shouldIgnoreFile: () => shouldIgnoreFile,
22058
22163
  shouldIgnoreMatch: () => shouldIgnoreMatch,
22164
+ signEd25519: () => signEd25519,
22165
+ signKms: () => signKms,
22059
22166
  upsertRequest: () => upsertRequest,
22060
- validateAgePublicKey: () => validateAgePublicKey
22167
+ validateAgePublicKey: () => validateAgePublicKey,
22168
+ verifySignature: () => verifySignature
22061
22169
  });
22062
22170
  var init_src = __esm({
22063
22171
  "../core/src/index.ts"() {
@@ -22088,6 +22196,7 @@ var init_src = __esm({
22088
22196
  init_manager2();
22089
22197
  init_resolve();
22090
22198
  init_packer();
22199
+ init_signer();
22091
22200
  }
22092
22201
  });
22093
22202
 
@@ -22698,7 +22807,7 @@ var require_supports_color = __commonJS({
22698
22807
  return 1;
22699
22808
  }
22700
22809
  if ("CI" in env) {
22701
- if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
22810
+ if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign2) => sign2 in env) || env.CI_NAME === "codeship") {
22702
22811
  return 1;
22703
22812
  }
22704
22813
  return min;
@@ -37679,16 +37788,16 @@ var require_utils = __commonJS({
37679
37788
  var inflate = options?.inflate !== false;
37680
37789
  var limit = typeof options?.limit !== "number" ? bytes.parse(options?.limit || "100kb") : options?.limit;
37681
37790
  var type = options?.type || defaultType;
37682
- var verify = options?.verify || false;
37791
+ var verify2 = options?.verify || false;
37683
37792
  var defaultCharset = options?.defaultCharset || "utf-8";
37684
- if (verify !== false && typeof verify !== "function") {
37793
+ if (verify2 !== false && typeof verify2 !== "function") {
37685
37794
  throw new TypeError("option verify must be function");
37686
37795
  }
37687
37796
  var shouldParse = typeof type !== "function" ? typeChecker(type) : type;
37688
37797
  return {
37689
37798
  inflate,
37690
37799
  limit,
37691
- verify,
37800
+ verify: verify2,
37692
37801
  defaultCharset,
37693
37802
  shouldParse
37694
37803
  };
@@ -37746,7 +37855,7 @@ var require_read = __commonJS({
37746
37855
  var length;
37747
37856
  var opts = options;
37748
37857
  var stream;
37749
- var verify = opts.verify;
37858
+ var verify2 = opts.verify;
37750
37859
  try {
37751
37860
  stream = contentstream(req, debug, opts.inflate);
37752
37861
  length = stream.length;
@@ -37755,7 +37864,7 @@ var require_read = __commonJS({
37755
37864
  return next(err);
37756
37865
  }
37757
37866
  opts.length = length;
37758
- opts.encoding = verify ? null : encoding;
37867
+ opts.encoding = verify2 ? null : encoding;
37759
37868
  if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) {
37760
37869
  return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', {
37761
37870
  charset: encoding.toLowerCase(),
@@ -37783,10 +37892,10 @@ var require_read = __commonJS({
37783
37892
  });
37784
37893
  return;
37785
37894
  }
37786
- if (verify) {
37895
+ if (verify2) {
37787
37896
  try {
37788
37897
  debug("verify body");
37789
- verify(req, res, body, encoding);
37898
+ verify2(req, res, body, encoding);
37790
37899
  } catch (err) {
37791
37900
  next(createError(403, err, {
37792
37901
  body,
@@ -38737,7 +38846,7 @@ var require_sign = __commonJS({
38737
38846
  "../../node_modules/math-intrinsics/sign.js"(exports2, module2) {
38738
38847
  "use strict";
38739
38848
  var $isNaN = require_isNaN();
38740
- module2.exports = function sign(number) {
38849
+ module2.exports = function sign2(number) {
38741
38850
  if ($isNaN(number) || number === 0) {
38742
38851
  return number;
38743
38852
  }
@@ -39101,7 +39210,7 @@ var require_get_intrinsic = __commonJS({
39101
39210
  var min = require_min();
39102
39211
  var pow = require_pow();
39103
39212
  var round = require_round();
39104
- var sign = require_sign();
39213
+ var sign2 = require_sign();
39105
39214
  var $Function = Function;
39106
39215
  var getEvalledConstructor = function(expressionSyntax) {
39107
39216
  try {
@@ -39215,7 +39324,7 @@ var require_get_intrinsic = __commonJS({
39215
39324
  "%Math.min%": min,
39216
39325
  "%Math.pow%": pow,
39217
39326
  "%Math.round%": round,
39218
- "%Math.sign%": sign,
39327
+ "%Math.sign%": sign2,
39219
39328
  "%Reflect.getPrototypeOf%": $ReflectGPO
39220
39329
  };
39221
39330
  if (getProto) {
@@ -41001,14 +41110,14 @@ var require_etag = __commonJS({
41001
41110
  "../../node_modules/etag/index.js"(exports2, module2) {
41002
41111
  "use strict";
41003
41112
  module2.exports = etag;
41004
- var crypto5 = require("crypto");
41113
+ var crypto6 = require("crypto");
41005
41114
  var Stats = require("fs").Stats;
41006
41115
  var toString = Object.prototype.toString;
41007
41116
  function entitytag(entity) {
41008
41117
  if (entity.length === 0) {
41009
41118
  return '"0-2jmj7l5rSw0yVb/vlWAYkK/YBwk"';
41010
41119
  }
41011
- var hash = crypto5.createHash("sha1").update(entity, "utf8").digest("base64").substring(0, 27);
41120
+ var hash = crypto6.createHash("sha1").update(entity, "utf8").digest("base64").substring(0, 27);
41012
41121
  var len = typeof entity === "string" ? Buffer.byteLength(entity, "utf8") : entity.length;
41013
41122
  return '"' + len.toString(16) + "-" + hash + '"';
41014
41123
  }
@@ -63433,17 +63542,17 @@ var require_content_disposition = __commonJS({
63433
63542
  // ../../node_modules/cookie-signature/index.js
63434
63543
  var require_cookie_signature = __commonJS({
63435
63544
  "../../node_modules/cookie-signature/index.js"(exports2) {
63436
- var crypto5 = require("crypto");
63545
+ var crypto6 = require("crypto");
63437
63546
  exports2.sign = function(val, secret) {
63438
63547
  if ("string" != typeof val) throw new TypeError("Cookie value must be provided as a string.");
63439
63548
  if (null == secret) throw new TypeError("Secret key must be provided.");
63440
- return val + "." + crypto5.createHmac("sha256", secret).update(val).digest("base64").replace(/\=+$/, "");
63549
+ return val + "." + crypto6.createHmac("sha256", secret).update(val).digest("base64").replace(/\=+$/, "");
63441
63550
  };
63442
63551
  exports2.unsign = function(input, secret) {
63443
63552
  if ("string" != typeof input) throw new TypeError("Signed cookie string must be provided.");
63444
63553
  if (null == secret) throw new TypeError("Secret key must be provided.");
63445
63554
  var tentativeValue = input.slice(0, input.lastIndexOf(".")), expectedInput = exports2.sign(tentativeValue, secret), expectedBuffer = Buffer.from(expectedInput), inputBuffer = Buffer.from(input);
63446
- return expectedBuffer.length === inputBuffer.length && crypto5.timingSafeEqual(expectedBuffer, inputBuffer) ? tentativeValue : false;
63555
+ return expectedBuffer.length === inputBuffer.length && crypto6.timingSafeEqual(expectedBuffer, inputBuffer) ? tentativeValue : false;
63447
63556
  };
63448
63557
  }
63449
63558
  });
@@ -73690,7 +73799,7 @@ var require_response = __commonJS({
73690
73799
  var path44 = require("node:path");
73691
73800
  var pathIsAbsolute = require("node:path").isAbsolute;
73692
73801
  var statuses = require_statuses();
73693
- var sign = require_cookie_signature().sign;
73802
+ var sign2 = require_cookie_signature().sign;
73694
73803
  var normalizeType = require_utils3().normalizeType;
73695
73804
  var normalizeTypes = require_utils3().normalizeTypes;
73696
73805
  var setCharset = require_utils3().setCharset;
@@ -73981,7 +74090,7 @@ var require_response = __commonJS({
73981
74090
  }
73982
74091
  var val = typeof value === "object" ? "j:" + JSON.stringify(value) : String(value);
73983
74092
  if (signed) {
73984
- val = "s:" + sign(val, secret);
74093
+ val = "s:" + sign2(val, secret);
73985
74094
  }
73986
74095
  if (opts.maxAge != null) {
73987
74096
  var maxAge = opts.maxAge - 0;
@@ -75347,9 +75456,8 @@ var require_api = __commonJS({
75347
75456
  }
75348
75457
  res.json({ success: true, key });
75349
75458
  }
75350
- } catch (err) {
75351
- const detail = err instanceof Error ? err.message : String(err);
75352
- res.status(500).json({ error: `Failed to set value: ${detail}`, code: "SET_ERROR" });
75459
+ } catch {
75460
+ res.status(500).json({ error: "Failed to set value", code: "SET_ERROR" });
75353
75461
  }
75354
75462
  });
75355
75463
  router.delete("/namespace/:ns/:env/:key", async (req, res) => {
@@ -75886,7 +75994,7 @@ var require_server = __commonJS({
75886
75994
  const app = (0, express_1.default)();
75887
75995
  const sessionToken = (0, crypto_1.randomBytes)(32).toString("hex");
75888
75996
  app.use(express_1.default.json());
75889
- app.use("/api", (req, res, next) => {
75997
+ app.use((req, res, next) => {
75890
75998
  const host = req.headers.host ?? "";
75891
75999
  const actualPort = req.socket.address()?.port ?? port;
75892
76000
  const allowedHosts = [`127.0.0.1:${actualPort}`, `127.0.0.1:${port}`];
@@ -76312,6 +76420,20 @@ var require_aws = __commonJS({
76312
76420
  }
76313
76421
  return Buffer.from(response.Plaintext);
76314
76422
  }
76423
+ async sign(keyId, digest) {
76424
+ await this.ensureClient();
76425
+ const command = new this.sdk.SignCommand({
76426
+ KeyId: keyId,
76427
+ Message: digest,
76428
+ MessageType: "DIGEST",
76429
+ SigningAlgorithm: "ECDSA_SHA_256"
76430
+ });
76431
+ const response = await this.client.send(command);
76432
+ if (!response.Signature) {
76433
+ throw new Error("AWS KMS Sign returned no signature.");
76434
+ }
76435
+ return Buffer.from(response.Signature);
76436
+ }
76315
76437
  };
76316
76438
  exports2.AwsKmsProvider = AwsKmsProvider;
76317
76439
  }
@@ -76525,6 +76647,88 @@ var require_kms = __commonJS({
76525
76647
  }
76526
76648
  });
76527
76649
 
76650
+ // ../runtime/dist/signature.js
76651
+ var require_signature = __commonJS({
76652
+ "../runtime/dist/signature.js"(exports2) {
76653
+ "use strict";
76654
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? (function(o, m, k, k2) {
76655
+ if (k2 === void 0) k2 = k;
76656
+ var desc = Object.getOwnPropertyDescriptor(m, k);
76657
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
76658
+ desc = { enumerable: true, get: function() {
76659
+ return m[k];
76660
+ } };
76661
+ }
76662
+ Object.defineProperty(o, k2, desc);
76663
+ }) : (function(o, m, k, k2) {
76664
+ if (k2 === void 0) k2 = k;
76665
+ o[k2] = m[k];
76666
+ }));
76667
+ var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? (function(o, v) {
76668
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
76669
+ }) : function(o, v) {
76670
+ o["default"] = v;
76671
+ });
76672
+ var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ (function() {
76673
+ var ownKeys = function(o) {
76674
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
76675
+ var ar = [];
76676
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
76677
+ return ar;
76678
+ };
76679
+ return ownKeys(o);
76680
+ };
76681
+ return function(mod) {
76682
+ if (mod && mod.__esModule) return mod;
76683
+ var result = {};
76684
+ if (mod != null) {
76685
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
76686
+ }
76687
+ __setModuleDefault(result, mod);
76688
+ return result;
76689
+ };
76690
+ })();
76691
+ Object.defineProperty(exports2, "__esModule", { value: true });
76692
+ exports2.buildSigningPayload = buildSigningPayload2;
76693
+ exports2.verifySignature = verifySignature2;
76694
+ var crypto6 = __importStar(require("crypto"));
76695
+ function buildSigningPayload2(artifact) {
76696
+ const fields = [
76697
+ "clef-sig-v1",
76698
+ String(artifact.version),
76699
+ artifact.identity,
76700
+ artifact.environment,
76701
+ artifact.revision,
76702
+ artifact.packedAt,
76703
+ artifact.ciphertextHash,
76704
+ [...artifact.keys].sort().join(","),
76705
+ artifact.expiresAt ?? "",
76706
+ artifact.envelope?.provider ?? "",
76707
+ artifact.envelope?.keyId ?? "",
76708
+ artifact.envelope?.wrappedKey ?? "",
76709
+ artifact.envelope?.algorithm ?? ""
76710
+ ];
76711
+ return Buffer.from(fields.join("\n"), "utf-8");
76712
+ }
76713
+ function verifySignature2(payload, signatureBase64, publicKeyBase64) {
76714
+ const keyObj = crypto6.createPublicKey({
76715
+ key: Buffer.from(publicKeyBase64, "base64"),
76716
+ format: "der",
76717
+ type: "spki"
76718
+ });
76719
+ const signature = Buffer.from(signatureBase64, "base64");
76720
+ const keyType = keyObj.asymmetricKeyType;
76721
+ if (keyType === "ed25519") {
76722
+ return crypto6.verify(null, payload, keyObj, signature);
76723
+ }
76724
+ if (keyType === "ec") {
76725
+ return crypto6.verify("sha256", payload, keyObj, signature);
76726
+ }
76727
+ throw new Error(`Unsupported key type for signature verification: ${keyType}`);
76728
+ }
76729
+ }
76730
+ });
76731
+
76528
76732
  // ../runtime/dist/poller.js
76529
76733
  var require_poller = __commonJS({
76530
76734
  "../runtime/dist/poller.js"(exports2) {
@@ -76568,9 +76772,10 @@ var require_poller = __commonJS({
76568
76772
  })();
76569
76773
  Object.defineProperty(exports2, "__esModule", { value: true });
76570
76774
  exports2.ArtifactPoller = void 0;
76571
- var crypto5 = __importStar(require("crypto"));
76775
+ var crypto6 = __importStar(require("crypto"));
76572
76776
  var decrypt_1 = require_decrypt();
76573
76777
  var kms_1 = require_kms();
76778
+ var signature_1 = require_signature();
76574
76779
  var MIN_POLL_MS = 5e3;
76575
76780
  var ArtifactPoller = class {
76576
76781
  timer = null;
@@ -76686,7 +76891,7 @@ var require_poller = __commonJS({
76686
76891
  }
76687
76892
  if (artifact.revision === this.lastRevision)
76688
76893
  return;
76689
- const hash = crypto5.createHash("sha256").update(artifact.ciphertext).digest("hex");
76894
+ const hash = crypto6.createHash("sha256").update(artifact.ciphertext).digest("hex");
76690
76895
  if (hash !== artifact.ciphertextHash) {
76691
76896
  const err = new Error(`Artifact integrity check failed: expected hash ${artifact.ciphertextHash}, got ${hash}`);
76692
76897
  this.telemetry?.artifactInvalid({
@@ -76695,6 +76900,36 @@ var require_poller = __commonJS({
76695
76900
  });
76696
76901
  throw err;
76697
76902
  }
76903
+ if (this.options.verifyKey) {
76904
+ if (!artifact.signature) {
76905
+ const err = new Error("Artifact signature verification failed: artifact is unsigned but a verify key is configured. Only signed artifacts are accepted when signature verification is enabled.");
76906
+ this.telemetry?.artifactInvalid({
76907
+ reason: "signature_missing",
76908
+ error: err.message
76909
+ });
76910
+ throw err;
76911
+ }
76912
+ const payload = (0, signature_1.buildSigningPayload)(artifact);
76913
+ let valid;
76914
+ try {
76915
+ valid = (0, signature_1.verifySignature)(payload, artifact.signature, this.options.verifyKey);
76916
+ } catch (sigErr) {
76917
+ const err = new Error(`Artifact signature verification error: ${sigErr instanceof Error ? sigErr.message : String(sigErr)}`);
76918
+ this.telemetry?.artifactInvalid({
76919
+ reason: "signature_error",
76920
+ error: err.message
76921
+ });
76922
+ throw err;
76923
+ }
76924
+ if (!valid) {
76925
+ const err = new Error("Artifact signature verification failed: signature does not match the verify key. The artifact may have been tampered with or signed by a different key.");
76926
+ this.telemetry?.artifactInvalid({
76927
+ reason: "signature_invalid",
76928
+ error: err.message
76929
+ });
76930
+ throw err;
76931
+ }
76932
+ }
76698
76933
  let agePrivateKey;
76699
76934
  if (artifact.envelope) {
76700
76935
  try {
@@ -76816,6 +77051,8 @@ var require_poller = __commonJS({
76816
77051
  return "missing_fields";
76817
77052
  if (msg.includes("incomplete envelope"))
76818
77053
  return "incomplete_envelope";
77054
+ if (msg.includes("signature"))
77055
+ return "signature";
76819
77056
  return "unknown";
76820
77057
  }
76821
77058
  }
@@ -77284,7 +77521,7 @@ var require_dist4 = __commonJS({
77284
77521
  "../runtime/dist/index.js"(exports2) {
77285
77522
  "use strict";
77286
77523
  Object.defineProperty(exports2, "__esModule", { value: true });
77287
- exports2.ClefRuntime = exports2.VcsArtifactSource = exports2.FileArtifactSource = exports2.HttpArtifactSource = exports2.createKmsProvider = exports2.AwsKmsProvider = exports2.createVcsProvider = exports2.BitbucketProvider = exports2.GitLabProvider = exports2.GitHubProvider = exports2.TelemetryEmitter = exports2.ArtifactPoller = exports2.AgeDecryptor = exports2.DiskCache = exports2.SecretsCache = void 0;
77524
+ exports2.ClefRuntime = exports2.verifySignature = exports2.buildSigningPayload = exports2.VcsArtifactSource = exports2.FileArtifactSource = exports2.HttpArtifactSource = exports2.createKmsProvider = exports2.AwsKmsProvider = exports2.createVcsProvider = exports2.BitbucketProvider = exports2.GitLabProvider = exports2.GitHubProvider = exports2.TelemetryEmitter = exports2.ArtifactPoller = exports2.AgeDecryptor = exports2.DiskCache = exports2.SecretsCache = void 0;
77288
77525
  exports2.init = init;
77289
77526
  var secrets_cache_1 = require_secrets_cache();
77290
77527
  Object.defineProperty(exports2, "SecretsCache", { enumerable: true, get: function() {
@@ -77342,6 +77579,13 @@ var require_dist4 = __commonJS({
77342
77579
  Object.defineProperty(exports2, "VcsArtifactSource", { enumerable: true, get: function() {
77343
77580
  return vcs_1.VcsArtifactSource;
77344
77581
  } });
77582
+ var signature_1 = require_signature();
77583
+ Object.defineProperty(exports2, "buildSigningPayload", { enumerable: true, get: function() {
77584
+ return signature_1.buildSigningPayload;
77585
+ } });
77586
+ Object.defineProperty(exports2, "verifySignature", { enumerable: true, get: function() {
77587
+ return signature_1.verifySignature;
77588
+ } });
77345
77589
  var secrets_cache_2 = require_secrets_cache();
77346
77590
  var disk_cache_2 = require_disk_cache();
77347
77591
  var decrypt_2 = require_decrypt();
@@ -77370,7 +77614,8 @@ var require_dist4 = __commonJS({
77370
77614
  cache: this.cache,
77371
77615
  diskCache,
77372
77616
  cacheTtl: config.cacheTtl,
77373
- telemetry: config.telemetry
77617
+ telemetry: config.telemetry,
77618
+ verifyKey: config.verifyKey
77374
77619
  });
77375
77620
  }
77376
77621
  /** Initial fetch + decrypt. Must be called before get/getAll. */
@@ -78936,12 +79181,14 @@ function registerSetCommand(program3, deps2) {
78936
79181
  try {
78937
79182
  await markPendingWithRetry(filePath, [key], "clef set --random");
78938
79183
  } catch {
78939
- formatter.warn(
79184
+ formatter.error(
78940
79185
  `${key} was encrypted but pending state could not be recorded.
78941
- WARNING: The encrypted file contains a random placeholder value.
79186
+ The encrypted file contains a random placeholder value with no tracking metadata.
78942
79187
  This key MUST be set to a real value before deploying.
78943
79188
  Run: clef set ${namespace}/${environment} ${key}`
78944
79189
  );
79190
+ process.exit(1);
79191
+ return;
78945
79192
  }
78946
79193
  formatter.success(`${key} set in ${namespace}/${environment} ${sym("locked")}`);
78947
79194
  formatter.print(
@@ -78985,7 +79232,7 @@ function parseTarget2(target) {
78985
79232
  // src/commands/compare.ts
78986
79233
  var path23 = __toESM(require("path"));
78987
79234
  init_src();
78988
- var crypto4 = __toESM(require("crypto"));
79235
+ var crypto5 = __toESM(require("crypto"));
78989
79236
  function registerCompareCommand(program3, deps2) {
78990
79237
  program3.command("compare <target> <key> [value]").description(
78991
79238
  "Compare a stored secret with a supplied value.\n\n target: namespace/environment (e.g. payments/staging)\n key: the key name to compare\n value: optional \u2014 if omitted, prompts with hidden input\n\nNeither value is ever printed to stdout.\n\nExit codes:\n 0 values match\n 1 values do not match or operation failed"
@@ -79021,7 +79268,7 @@ function registerCompareCommand(program3, deps2) {
79021
79268
  return;
79022
79269
  }
79023
79270
  const stored = decrypted.values[key];
79024
- const match = stored.length === compareValue.length && crypto4.timingSafeEqual(Buffer.from(stored), Buffer.from(compareValue));
79271
+ const match = stored.length === compareValue.length && crypto5.timingSafeEqual(Buffer.from(stored), Buffer.from(compareValue));
79025
79272
  if (match) {
79026
79273
  formatter.success(`${key} ${sym("arrow")} values match`);
79027
79274
  } else {
@@ -79483,7 +79730,7 @@ async function fetchCheckpoint(config) {
79483
79730
  }
79484
79731
 
79485
79732
  // package.json
79486
- var version = "0.1.7-beta.45";
79733
+ var version = "0.1.8-beta.52";
79487
79734
  var package_default = {
79488
79735
  name: "@clef-sh/cli",
79489
79736
  version,
@@ -79582,6 +79829,7 @@ function registerLintCommand(program3, deps2) {
79582
79829
  formatter.raw(JSON.stringify(result, null, 2) + "\n");
79583
79830
  const hasErrors2 = result.issues.some((i) => i.severity === "error");
79584
79831
  process.exit(hasErrors2 ? 1 : 0);
79832
+ return;
79585
79833
  }
79586
79834
  formatLintOutput(result);
79587
79835
  const hasErrors = result.issues.some((i) => i.severity === "error");
@@ -81629,7 +81877,11 @@ Service Identity: ${identity.name}`);
81629
81877
  formatter.error(err.message);
81630
81878
  const partialEntries = Object.entries(err.rotatedKeys);
81631
81879
  const partialBlock = partialEntries.map(([env, key]) => `${env}: ${key}`).join("\n");
81632
- const partialCopied = copyToClipboard(partialBlock);
81880
+ let partialCopied = false;
81881
+ try {
81882
+ partialCopied = copyToClipboard(partialBlock);
81883
+ } catch {
81884
+ }
81633
81885
  if (partialCopied) {
81634
81886
  formatter.warn(
81635
81887
  "Partial rotation succeeded. Rotated keys copied to clipboard \u2014 store them NOW.\n"
@@ -81665,7 +81917,13 @@ init_src();
81665
81917
  function registerPackCommand(program3, deps2) {
81666
81918
  program3.command("pack <identity> <environment>").description(
81667
81919
  "Pack an encrypted artifact for a service identity.\n\n The artifact is a JSON envelope with age-encrypted secrets that can be\n fetched by the Clef agent at runtime from any HTTP URL or local file.\n\nUsage:\n clef pack api-gateway production --output ./artifact.json\n # Then upload with your CI tools:\n # aws s3 cp ./artifact.json s3://my-bucket/clef/api-gateway/production.json"
81668
- ).requiredOption("-o, --output <path>", "Output file path for the artifact JSON").option("--ttl <seconds>", "Artifact TTL \u2014 embeds an expiresAt timestamp in the envelope").action(
81920
+ ).requiredOption("-o, --output <path>", "Output file path for the artifact JSON").option("--ttl <seconds>", "Artifact TTL \u2014 embeds an expiresAt timestamp in the envelope").option(
81921
+ "--signing-key <key>",
81922
+ "Ed25519 private key for artifact signing (base64 DER PKCS8, or env CLEF_SIGNING_KEY)"
81923
+ ).option(
81924
+ "--signing-kms-key <keyId>",
81925
+ "KMS asymmetric signing key ARN/ID (ECDSA_SHA_256, or env CLEF_SIGNING_KMS_KEY)"
81926
+ ).action(
81669
81927
  async (identity, environment, opts) => {
81670
81928
  try {
81671
81929
  const repoRoot = program3.opts().dir || process.cwd();
@@ -81690,11 +81948,20 @@ function registerPackCommand(program3, deps2) {
81690
81948
  process.exit(1);
81691
81949
  return;
81692
81950
  }
81951
+ const signingKey = opts.signingKey ?? process.env.CLEF_SIGNING_KEY;
81952
+ const signingKmsKeyId = opts.signingKmsKey ?? process.env.CLEF_SIGNING_KMS_KEY;
81953
+ if (signingKey && signingKmsKeyId) {
81954
+ formatter.error(
81955
+ "Cannot specify both --signing-key (Ed25519) and --signing-kms-key (KMS). Choose one."
81956
+ );
81957
+ process.exit(1);
81958
+ return;
81959
+ }
81693
81960
  formatter.print(
81694
81961
  `${sym("working")} Packing artifact for '${identity}/${environment}'...`
81695
81962
  );
81696
81963
  const result = await packer.pack(
81697
- { identity, environment, outputPath, ttl },
81964
+ { identity, environment, outputPath, ttl, signingKey, signingKmsKeyId },
81698
81965
  manifest,
81699
81966
  repoRoot
81700
81967
  );
@@ -81707,11 +81974,13 @@ function registerPackCommand(program3, deps2) {
81707
81974
  if (envConfig && isKmsEnvelope(envConfig)) {
81708
81975
  formatter.print(` Envelope: KMS (${envConfig.kms.provider})`);
81709
81976
  }
81710
- formatter.warn(
81711
- "\nThe artifact contains encrypted secrets. Do NOT commit it to version control."
81712
- );
81977
+ if (signingKey) {
81978
+ formatter.print(` Signed: Ed25519`);
81979
+ } else if (signingKmsKeyId) {
81980
+ formatter.print(` Signed: KMS ECDSA_SHA256`);
81981
+ }
81713
81982
  formatter.hint(
81714
- "Upload the artifact to an HTTP-accessible store (S3, GCS, etc.) using your CI tools."
81983
+ "\nUpload the artifact to an HTTP-accessible store (S3, GCS, etc.) or commit to\n .clef/packed/ for VCS-based delivery. See: clef.sh/guide/service-identities"
81715
81984
  );
81716
81985
  } catch (err) {
81717
81986
  if (err instanceof SopsMissingError || err instanceof SopsVersionError) {
@@ -81814,6 +82083,7 @@ function registerDriftCommand(program3, _deps) {
81814
82083
  if (options.json) {
81815
82084
  formatter.raw(JSON.stringify(result, null, 2) + "\n");
81816
82085
  process.exit(result.issues.length > 0 ? 1 : 0);
82086
+ return;
81817
82087
  }
81818
82088
  formatDriftOutput(result);
81819
82089
  process.exit(result.issues.length > 0 ? 1 : 0);