@umbra-privacy/qos-ceremony 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist-cli/cli.js +81 -35
  2. package/package.json +1 -1
package/dist-cli/cli.js CHANGED
@@ -6437,10 +6437,10 @@ var init_hex_encoding = __esm({
6437
6437
  });
6438
6438
 
6439
6439
  // ../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/serde/util-body-length/calculateBodyLength.js
6440
- var import_node_fs6, calculateBodyLength;
6440
+ var import_node_fs7, calculateBodyLength;
6441
6441
  var init_calculateBodyLength = __esm({
6442
6442
  "../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/serde/util-body-length/calculateBodyLength.js"() {
6443
- import_node_fs6 = require("node:fs");
6443
+ import_node_fs7 = require("node:fs");
6444
6444
  calculateBodyLength = (body) => {
6445
6445
  if (!body) {
6446
6446
  return 0;
@@ -6453,11 +6453,11 @@ var init_calculateBodyLength = __esm({
6453
6453
  return body.size;
6454
6454
  } else if (typeof body.start === "number" && typeof body.end === "number") {
6455
6455
  return body.end + 1 - body.start;
6456
- } else if (body instanceof import_node_fs6.ReadStream) {
6456
+ } else if (body instanceof import_node_fs7.ReadStream) {
6457
6457
  if (body.path != null) {
6458
- return (0, import_node_fs6.lstatSync)(body.path).size;
6458
+ return (0, import_node_fs7.lstatSync)(body.path).size;
6459
6459
  } else if (typeof body.fd === "number") {
6460
- return (0, import_node_fs6.fstatSync)(body.fd).size;
6460
+ return (0, import_node_fs7.fstatSync)(body.fd).size;
6461
6461
  }
6462
6462
  }
6463
6463
  throw new Error(`Body Length computation failed for ${body}`);
@@ -6756,11 +6756,11 @@ var init_types = __esm({
6756
6756
  });
6757
6757
 
6758
6758
  // ../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/getHomeDir.js
6759
- var import_node_os2, import_node_path5, homeDirCache, getHomeDirCacheKey, getHomeDir;
6759
+ var import_node_os2, import_node_path6, homeDirCache, getHomeDirCacheKey, getHomeDir;
6760
6760
  var init_getHomeDir = __esm({
6761
6761
  "../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/getHomeDir.js"() {
6762
6762
  import_node_os2 = require("node:os");
6763
- import_node_path5 = require("node:path");
6763
+ import_node_path6 = require("node:path");
6764
6764
  homeDirCache = {};
6765
6765
  getHomeDirCacheKey = () => {
6766
6766
  if (process && process.geteuid) {
@@ -6769,7 +6769,7 @@ var init_getHomeDir = __esm({
6769
6769
  return "DEFAULT";
6770
6770
  };
6771
6771
  getHomeDir = () => {
6772
- const { HOME, USERPROFILE, HOMEPATH, HOMEDRIVE = `C:${import_node_path5.sep}` } = process.env;
6772
+ const { HOME, USERPROFILE, HOMEPATH, HOMEDRIVE = `C:${import_node_path6.sep}` } = process.env;
6773
6773
  if (HOME)
6774
6774
  return HOME;
6775
6775
  if (USERPROFILE)
@@ -6795,16 +6795,16 @@ var init_getProfileName = __esm({
6795
6795
  });
6796
6796
 
6797
6797
  // ../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/getSSOTokenFilepath.js
6798
- var import_node_crypto, import_node_path6, getSSOTokenFilepath;
6798
+ var import_node_crypto, import_node_path7, getSSOTokenFilepath;
6799
6799
  var init_getSSOTokenFilepath = __esm({
6800
6800
  "../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/getSSOTokenFilepath.js"() {
6801
6801
  import_node_crypto = require("node:crypto");
6802
- import_node_path6 = require("node:path");
6802
+ import_node_path7 = require("node:path");
6803
6803
  init_getHomeDir();
6804
6804
  getSSOTokenFilepath = (id) => {
6805
6805
  const hasher = (0, import_node_crypto.createHash)("sha1");
6806
6806
  const cacheName = hasher.update(id).digest("hex");
6807
- return (0, import_node_path6.join)(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
6807
+ return (0, import_node_path7.join)(getHomeDir(), ".aws", "sso", "cache", `${cacheName}.json`);
6808
6808
  };
6809
6809
  }
6810
6810
  });
@@ -6859,24 +6859,24 @@ var init_getConfigData = __esm({
6859
6859
  });
6860
6860
 
6861
6861
  // ../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/getConfigFilepath.js
6862
- var import_node_path7, ENV_CONFIG_PATH, getConfigFilepath;
6862
+ var import_node_path8, ENV_CONFIG_PATH, getConfigFilepath;
6863
6863
  var init_getConfigFilepath = __esm({
6864
6864
  "../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/getConfigFilepath.js"() {
6865
- import_node_path7 = require("node:path");
6865
+ import_node_path8 = require("node:path");
6866
6866
  init_getHomeDir();
6867
6867
  ENV_CONFIG_PATH = "AWS_CONFIG_FILE";
6868
- getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || (0, import_node_path7.join)(getHomeDir(), ".aws", "config");
6868
+ getConfigFilepath = () => process.env[ENV_CONFIG_PATH] || (0, import_node_path8.join)(getHomeDir(), ".aws", "config");
6869
6869
  }
6870
6870
  });
6871
6871
 
6872
6872
  // ../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/getCredentialsFilepath.js
6873
- var import_node_path8, ENV_CREDENTIALS_PATH, getCredentialsFilepath;
6873
+ var import_node_path9, ENV_CREDENTIALS_PATH, getCredentialsFilepath;
6874
6874
  var init_getCredentialsFilepath = __esm({
6875
6875
  "../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/getCredentialsFilepath.js"() {
6876
- import_node_path8 = require("node:path");
6876
+ import_node_path9 = require("node:path");
6877
6877
  init_getHomeDir();
6878
6878
  ENV_CREDENTIALS_PATH = "AWS_SHARED_CREDENTIALS_FILE";
6879
- getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || (0, import_node_path8.join)(getHomeDir(), ".aws", "credentials");
6879
+ getCredentialsFilepath = () => process.env[ENV_CREDENTIALS_PATH] || (0, import_node_path9.join)(getHomeDir(), ".aws", "credentials");
6880
6880
  }
6881
6881
  });
6882
6882
 
@@ -6956,10 +6956,10 @@ var init_readFile = __esm({
6956
6956
  });
6957
6957
 
6958
6958
  // ../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/loadSharedConfigFiles.js
6959
- var import_node_path9, swallowError, loadSharedConfigFiles;
6959
+ var import_node_path10, swallowError, loadSharedConfigFiles;
6960
6960
  var init_loadSharedConfigFiles = __esm({
6961
6961
  "../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/config/shared-ini-file-loader/loadSharedConfigFiles.js"() {
6962
- import_node_path9 = require("node:path");
6962
+ import_node_path10 = require("node:path");
6963
6963
  init_getConfigData();
6964
6964
  init_getConfigFilepath();
6965
6965
  init_getCredentialsFilepath();
@@ -6974,11 +6974,11 @@ var init_loadSharedConfigFiles = __esm({
6974
6974
  const relativeHomeDirPrefix = "~/";
6975
6975
  let resolvedFilepath = filepath;
6976
6976
  if (filepath.startsWith(relativeHomeDirPrefix)) {
6977
- resolvedFilepath = (0, import_node_path9.join)(homeDir, filepath.slice(2));
6977
+ resolvedFilepath = (0, import_node_path10.join)(homeDir, filepath.slice(2));
6978
6978
  }
6979
6979
  let resolvedConfigFilepath = configFilepath;
6980
6980
  if (configFilepath.startsWith(relativeHomeDirPrefix)) {
6981
- resolvedConfigFilepath = (0, import_node_path9.join)(homeDir, configFilepath.slice(2));
6981
+ resolvedConfigFilepath = (0, import_node_path10.join)(homeDir, configFilepath.slice(2));
6982
6982
  }
6983
6983
  const parsedFiles = await Promise.all([
6984
6984
  readFile2(resolvedConfigFilepath, {
@@ -10082,17 +10082,17 @@ var init_HashCalculator = __esm({
10082
10082
  });
10083
10083
 
10084
10084
  // ../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/checksum/hash-stream-node/fileStreamHasher.js
10085
- var import_node_fs7, fileStreamHasher, isReadStream;
10085
+ var import_node_fs8, fileStreamHasher, isReadStream;
10086
10086
  var init_fileStreamHasher = __esm({
10087
10087
  "../../../node_modules/.pnpm/@smithy+core@3.29.6/node_modules/@smithy/core/dist-es/submodules/checksum/hash-stream-node/fileStreamHasher.js"() {
10088
- import_node_fs7 = require("node:fs");
10088
+ import_node_fs8 = require("node:fs");
10089
10089
  init_HashCalculator();
10090
10090
  fileStreamHasher = (hashCtor, fileStream) => new Promise((resolve2, reject) => {
10091
10091
  if (!isReadStream(fileStream)) {
10092
10092
  reject(new Error("Unable to calculate hash for non-file streams."));
10093
10093
  return;
10094
10094
  }
10095
- const fileStreamTee = (0, import_node_fs7.createReadStream)(fileStream.path, {
10095
+ const fileStreamTee = (0, import_node_fs8.createReadStream)(fileStream.path, {
10096
10096
  start: fileStream.start,
10097
10097
  end: fileStream.end
10098
10098
  });
@@ -12311,8 +12311,8 @@ var init_requestBuilder = __esm({
12311
12311
  async build() {
12312
12312
  const { hostname, protocol = "https", port, path: basePath } = await this.context.endpoint();
12313
12313
  this.path = basePath;
12314
- for (const resolvePath of this.resolvePathStack) {
12315
- resolvePath(this.path);
12314
+ for (const resolvePath2 of this.resolvePathStack) {
12315
+ resolvePath2(this.path);
12316
12316
  }
12317
12317
  return new HttpRequest({
12318
12318
  protocol,
@@ -26697,7 +26697,7 @@ var require_dist_cjs11 = __commonJS({
26697
26697
  var { createHash: createHash5, createPrivateKey, createPublicKey, sign: sign2 } = require("node:crypto");
26698
26698
  var { promises } = require("node:fs");
26699
26699
  var { homedir: homedir2 } = require("node:os");
26700
- var { dirname: dirname3, join: join8 } = require("node:path");
26700
+ var { dirname: dirname4, join: join9 } = require("node:path");
26701
26701
  var LoginCredentialsFetcher = class _LoginCredentialsFetcher {
26702
26702
  profileData;
26703
26703
  init;
@@ -26845,7 +26845,7 @@ var require_dist_cjs11 = __commonJS({
26845
26845
  }
26846
26846
  async saveToken(token) {
26847
26847
  const tokenFilePath = this.getTokenFilePath();
26848
- const directory = dirname3(tokenFilePath);
26848
+ const directory = dirname4(tokenFilePath);
26849
26849
  try {
26850
26850
  await promises.mkdir(directory, { recursive: true });
26851
26851
  } catch (error2) {
@@ -26853,10 +26853,10 @@ var require_dist_cjs11 = __commonJS({
26853
26853
  await promises.writeFile(tokenFilePath, JSON.stringify(token, null, 2), "utf8");
26854
26854
  }
26855
26855
  getTokenFilePath() {
26856
- const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join8(homedir2(), ".aws", "login", "cache");
26856
+ const directory = process.env.AWS_LOGIN_CACHE_DIRECTORY ?? join9(homedir2(), ".aws", "login", "cache");
26857
26857
  const loginSessionBytes = Buffer.from(this.loginSession, "utf8");
26858
26858
  const loginSessionSha256 = createHash5("sha256").update(loginSessionBytes).digest("hex");
26859
- return join8(directory, `${loginSessionSha256}.json`);
26859
+ return join9(directory, `${loginSessionSha256}.json`);
26860
26860
  }
26861
26861
  derToRawSignature(derSignature) {
26862
26862
  let offset = 2;
@@ -33382,6 +33382,49 @@ var approve = async (o3) => {
33382
33382
  }
33383
33383
  };
33384
33384
 
33385
+ // src/commands/fetch-config.ts
33386
+ var import_node_fs5 = require("node:fs");
33387
+ var import_node_path4 = require("node:path");
33388
+ var FILES = [
33389
+ { artifact: "config/pcr3_preimage", local: "pcr3_preimage" },
33390
+ {
33391
+ artifact: "config/qos_release/aws-x86_64.pcrs",
33392
+ local: "qos_release/aws-x86_64.pcrs"
33393
+ }
33394
+ ];
33395
+ var fetchConfig = async (o3) => {
33396
+ const apiUrl = o3.api ?? process.env.CEREMONY_API;
33397
+ const namespace = o3.namespace ?? process.env.CEREMONY_NAMESPACE;
33398
+ const nonceStr = o3.nonce ?? process.env.CEREMONY_NONCE;
33399
+ if (!apiUrl || !namespace || !nonceStr)
33400
+ throw new Error("fetch-config requires --api --namespace --nonce");
33401
+ const outDir = (0, import_node_path4.resolve)(o3.out ?? ".");
33402
+ const api = createCeremonyApi(apiUrl);
33403
+ const nonce = Number(nonceStr);
33404
+ for (const f5 of FILES) {
33405
+ const bytes = await api.getArtifact(namespace, nonce, f5.artifact);
33406
+ const target = (0, import_node_path4.join)(outDir, f5.local);
33407
+ (0, import_node_fs5.mkdirSync)((0, import_node_path4.dirname)(target), { recursive: true });
33408
+ (0, import_node_fs5.writeFileSync)(target, bytes);
33409
+ console.log(`fetch-config: wrote ${target} (${bytes.length} bytes)`);
33410
+ }
33411
+ console.log("");
33412
+ console.log("Pass these to every operator command:");
33413
+ console.log(
33414
+ ` --pcr3-preimage-path ${(0, import_node_path4.join)(outDir, "pcr3_preimage")} --qos-release-dir ${(0, import_node_path4.join)(outDir, "qos_release")}`
33415
+ );
33416
+ console.log("");
33417
+ console.log(
33418
+ "These are the values you check the enclave's attestation AGAINST. Fetching them from the"
33419
+ );
33420
+ console.log(
33421
+ "pipeline that deployed it is convenience, not proof \u2014 for a production ceremony, derive the"
33422
+ );
33423
+ console.log(
33424
+ "role ARN from the stack and the PCRs from the reproducible qos build, and diff them."
33425
+ );
33426
+ };
33427
+
33385
33428
  // src/commands/at-rest-tool.ts
33386
33429
  var import_node_child_process3 = require("node:child_process");
33387
33430
  var runAtRestTool = (tool, args) => {
@@ -33398,24 +33441,24 @@ This platform has no embedded build; install ${tool} on PATH or pass its path.`
33398
33441
  };
33399
33442
 
33400
33443
  // src/commands/keygen.ts
33401
- var import_node_fs5 = require("node:fs");
33402
- var import_node_path4 = require("node:path");
33444
+ var import_node_fs6 = require("node:fs");
33445
+ var import_node_path5 = require("node:path");
33403
33446
  var keygen = async (o3) => {
33404
33447
  const alias = o3.alias ?? process.env.CEREMONY_ALIAS ?? "operator";
33405
33448
  const secretPath = o3.secretPath ?? process.env.CEREMONY_SECRET;
33406
33449
  if (!secretPath) {
33407
33450
  throw new Error("keygen requires --secret-path (env CEREMONY_SECRET)");
33408
33451
  }
33409
- if ((0, import_node_fs5.existsSync)(secretPath)) {
33452
+ if ((0, import_node_fs6.existsSync)(secretPath)) {
33410
33453
  throw new Error(
33411
33454
  `refusing to overwrite existing secret at ${secretPath} \u2014 you already have a key; give its pubkey (${secretPath}.pub) to an admin to register-operator`
33412
33455
  );
33413
33456
  }
33414
- (0, import_node_fs5.mkdirSync)((0, import_node_path4.dirname)(secretPath), { recursive: true, mode: 448 });
33457
+ (0, import_node_fs6.mkdirSync)((0, import_node_path5.dirname)(secretPath), { recursive: true, mode: 448 });
33415
33458
  const qos = createQosClient({ bin: resolveQosBin(o3.qosClient) });
33416
33459
  const pubPath = `${secretPath}.pub`;
33417
33460
  qos.generateFileKey(secretPath, pubPath);
33418
- const pubHex = (0, import_node_fs5.readFileSync)(pubPath, "utf8").trim();
33461
+ const pubHex = (0, import_node_fs6.readFileSync)(pubPath, "utf8").trim();
33419
33462
  console.log(
33420
33463
  `keygen: seed written to ${secretPath} (keep it safe \u2014 it never leaves this device)`
33421
33464
  );
@@ -33838,6 +33881,9 @@ withCommon(
33838
33881
  "open the stored share and re-encrypt it to the enclave ephemeral key; post it (shareSet)"
33839
33882
  )
33840
33883
  ).action(run(provision));
33884
+ program2.command("fetch-config").description(
33885
+ "download the ceremony's public release files (pcr3_preimage + qos_release) \u2014 no AWS creds needed"
33886
+ ).option("--api <url>", "coordinator API base URL (env CEREMONY_API)").option("--namespace <ns>", "ceremony namespace (env CEREMONY_NAMESPACE)").option("--nonce <n>", "manifest nonce (env CEREMONY_NONCE)").option("--out <dir>", "directory to write into (default: cwd)").action(run(fetchConfig));
33841
33887
  program2.command("status").description("show ceremony phase + blockers (read-only)").option("--api <url>", "coordinator API base URL (env CEREMONY_API)").option("--namespace <ns>", "ceremony namespace (env CEREMONY_NAMESPACE)").option("--nonce <n>", "manifest nonce (env CEREMONY_NONCE)").action(run(status));
33842
33888
  program2.command("shift-traffic").description(
33843
33889
  "[ops] blue-green weighted traffic cutover across a service's colors (needs AWS creds)"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umbra-privacy/qos-ceremony",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "QOS TEE operator ceremony CLI — keygen/share/approve/provision + shift-traffic over the coordinator API, and the at-rest sealing tools. Shares are double-sealed everywhere they rest: ML-KEM-1024 over the QOS P-256 envelope. All crypto runs in embedded binaries (qos_client, umbra-encryption-key, umbra-seal-share, umbra-unseal-share); your private key never leaves the device. Ships NO coordinator code.",
5
5
  "keywords": [
6
6
  "qos",