@mp-lb/arcnet 0.2.0 → 0.2.2

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/README.md CHANGED
@@ -21,6 +21,8 @@ Zap Arc remains the pinned Terraform engine dependency. Environment bootstrap, h
21
21
 
22
22
  `arcnet secrets add` attaches an existing Forum encrypted JSON file. `arcnet secrets init` creates one. Both register a file-specific decryption key in the selected GitHub repository, save an encrypted snapshot, and generate a validation workflow. Setup prompts for your Forum encryption password locally; it never prints the password or recipient key. Use `--existing-key` when the GitHub secret already exists. The local `fm` and `gh` CLIs must be authenticated; the selected Forum parent directory must exist.
23
23
 
24
+ Use `/projects/<project-slug>/secrets.json.enc` for project files in the company Forum store.
25
+
24
26
  The project keeps only `.arcnet/secrets.json`, encrypted snapshots under `.arcnet/secrets/`, and workflow references. Sources merge left to right, with later values winning. Each source names its own key environment variable. JSON must be an object; unused structured values are allowed, while selected environment values must be nonempty strings. Consumer mappings select and rename fields; an array of source names accepts aliases only when their values agree.
25
27
 
26
28
  ```json
@@ -29,7 +31,7 @@ The project keeps only `.arcnet/secrets.json`, encrypted snapshots under `.arcne
29
31
  "repository": "example/hello-world",
30
32
  "sources": [
31
33
  { "name": "standard", "store": "example/company", "path": "/admin/standard.json.enc", "keyEnv": "STANDARD_SECRETS_KEY" },
32
- { "name": "project", "store": "example/company", "path": "/admin/hello-world.json.enc", "keyEnv": "PROJECT_SECRETS_KEY" }
34
+ { "name": "project", "store": "example/company", "path": "/projects/hello-world/secrets.json.enc", "keyEnv": "PROJECT_SECRETS_KEY" }
33
35
  ],
34
36
  "consumers": {
35
37
  "publish": { "NODE_AUTH_TOKEN": ["NPM_TOKEN", "NODE_AUTH_TOKEN"] },
@@ -44,6 +46,8 @@ For live loading, omit a snapshot or select `--live`: the installed `fm` CLI fet
44
46
 
45
47
  `arcnet env check` reports source names and selected key names, never values. `arcnet env export` explicitly emits selected plaintext JSON. `arcnet env run` gives a subprocess only the selected values and a small execution environment; it removes file keys, isolates temporary HOME/cache paths, and withholds subprocess output. Keep npm publishing mappings scoped to publishing credentials. The command reference documents the exact options.
46
48
 
49
+ For the first local Terraform plan and deploy, GitHub's file keys cannot be read back. Run `arcnet plan --password` or `arcnet deploy --password` in your terminal: ArcNet prompts once for your Forum encryption password and decrypts the reviewed snapshots locally. `arcnet env check --password` validates them the same way. CI still uses the independent file keys and rejects password mode.
50
+
47
51
  When `.arcnet/secrets.json` exists, deployment commands automatically load it. The `deploy` consumer selects operator credentials; Terraform application values are selected using the existing service env lists in `zap.yaml`. No duplicated application map is required. Offline project checks remain offline. Secrets commands in GitHub Actions require the configured repository's main branch.
48
52
 
49
53
  Provisioning modifies Forum and GitHub separately. A failed GitHub upload leaves an unused Forum recipient; rerun `secrets add` to create/upload another and remove the unused recipient later. If upload succeeded but snapshot/config writing failed, attach the file with `--existing-key`. Existing sources are not silently rotated on reruns. Provision while nobody else is editing that file: the current fm write interface does not offer atomic revision-conditional writes, though ArcNet checks identity/revision before updating and refuses occupied init paths. GitHub secret names are repository-scoped; environment-level overrides take precedence in jobs that use an environment.
@@ -1 +1 @@
1
- {"version":3,"file":"createCli.d.ts","sourceRoot":"","sources":["../src/createCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,eAAO,MAAM,SAAS,eAiHrB,CAAC"}
1
+ {"version":3,"file":"createCli.d.ts","sourceRoot":"","sources":["../src/createCli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAcpC,eAAO,MAAM,SAAS,eA4HrB,CAAC"}
package/dist/createCli.js CHANGED
@@ -53,6 +53,8 @@ export const createCli = () => {
53
53
  create: "Create one explicitly approved Vercel project.",
54
54
  })) {
55
55
  const command = cli.command(name).description(description);
56
+ if (name === "plan" || name === "deploy")
57
+ command.option("--password", "Prompt for the Forum encryption password locally instead of using file keys");
56
58
  if (name === "create")
57
59
  command.argument("<site>", "Configured site name");
58
60
  command.action(async (site) => {
@@ -70,7 +72,7 @@ export const createCli = () => {
70
72
  };
71
73
  output(await (name === "check" || (name === "plan" && mode === "vercel")
72
74
  ? execute()
73
- : withDeploymentSecrets(root, mode, execute)));
75
+ : withDeploymentSecrets(root, mode, execute, Boolean(command.opts().password), Boolean(cli.opts().noninteractive))));
74
76
  });
75
77
  }
76
78
  cli
@@ -1 +1 @@
1
- {"version":3,"file":"createCli.js","sourceRoot":"","sources":["../src/createCli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createCli.js","sourceRoot":"","sources":["../src/createCli.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"createSecretsCommands.d.ts","sourceRoot":"","sources":["../../src/secrets/createSecretsCommands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAUpC,eAAO,MAAM,qBAAqB,GAChC,KAAK,OAAO,EACZ,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,SAgLjC,CAAC"}
1
+ {"version":3,"file":"createSecretsCommands.d.ts","sourceRoot":"","sources":["../../src/secrets/createSecretsCommands.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,eAAO,MAAM,qBAAqB,GAChC,KAAK,OAAO,EACZ,QAAQ,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,SAgMjC,CAAC"}
@@ -6,6 +6,7 @@ import { runWithSecrets } from "./runWithSecrets.js";
6
6
  import { selectSecrets } from "./selectSecrets.js";
7
7
  import { syncSecrets } from "./syncSecrets.js";
8
8
  import { writeSecretsWorkflow } from "./writeSecretsWorkflow.js";
9
+ import { promptPassword } from "./promptPassword.js";
9
10
  export const createSecretsCommands = (cli, output) => {
10
11
  const env = cli
11
12
  .command("env")
@@ -20,7 +21,8 @@ export const createSecretsCommands = (cli, output) => {
20
21
  }[action])
21
22
  .option("--config <file>", "Secrets source configuration", ".arcnet/secrets.json")
22
23
  .option("--consumer <name>", "Named mapping in the secrets configuration")
23
- .option("--live", "Fetch current ciphertext through the installed fm CLI instead of snapshots");
24
+ .option("--live", "Fetch current ciphertext through the installed fm CLI instead of snapshots")
25
+ .option("--password", "Prompt for the Forum encryption password locally instead of using file keys");
24
26
  if (action === "run")
25
27
  command.argument("<command...>", "Executable and arguments after --");
26
28
  command.action(async (...args) => {
@@ -31,9 +33,14 @@ export const createSecretsCommands = (cli, output) => {
31
33
  (process.env.GITHUB_REPOSITORY !== config.repository ||
32
34
  process.env.GITHUB_REF !== "refs/heads/main"))
33
35
  throw new Error("Secrets commands in CI require the configured repository main branch.");
36
+ if (options.password && process.env.GITHUB_ACTIONS === "true")
37
+ throw new Error("Password decryption is local-only; CI must use file keys.");
34
38
  if (action !== "check" && !options.consumer)
35
39
  throw new Error("Choose --consumer to explicitly select output keys.");
36
- const values = await loadSecrets(config, root, process.env, options.live);
40
+ const password = options.password
41
+ ? await promptPassword(Boolean(cli.opts().noninteractive))
42
+ : undefined;
43
+ const values = await loadSecrets(config, root, process.env, options.live, password);
37
44
  const names = options.consumer
38
45
  ? [options.consumer]
39
46
  : Object.keys(config.consumers);
@@ -1 +1 @@
1
- {"version":3,"file":"createSecretsCommands.js","sourceRoot":"","sources":["../../src/secrets/createSecretsCommands.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"createSecretsCommands.js","sourceRoot":"","sources":["../../src/secrets/createSecretsCommands.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,3 @@
1
1
  import type { SecretsConfig } from "./config.js";
2
- export declare const loadSecrets: (config: SecretsConfig, root: string, environment?: NodeJS.ProcessEnv, live?: boolean) => Promise<Record<string, unknown>>;
2
+ export declare const loadSecrets: (config: SecretsConfig, root: string, environment?: NodeJS.ProcessEnv, live?: boolean, password?: string) => Promise<Record<string, unknown>>;
3
3
  //# sourceMappingURL=loadSecrets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loadSecrets.d.ts","sourceRoot":"","sources":["../../src/secrets/loadSecrets.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAGjD,eAAO,MAAM,WAAW,GACtB,QAAQ,aAAa,EACrB,MAAM,MAAM,EACZ,+BAAyB,EACzB,cAAY,qCAyCb,CAAC"}
1
+ {"version":3,"file":"loadSecrets.d.ts","sourceRoot":"","sources":["../../src/secrets/loadSecrets.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,eAAO,MAAM,WAAW,GACtB,QAAQ,aAAa,EACrB,MAAM,MAAM,EACZ,+BAAyB,EACzB,cAAY,EACZ,WAAW,MAAM,qCAqDlB,CAAC"}
@@ -1,13 +1,16 @@
1
1
  import { decryptForumEncryptedFileText } from "@mp-lb/forum-secrets";
2
2
  import { createHash } from "node:crypto";
3
- import { readFileSync } from "node:fs";
3
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
4
6
  import { safeTargetPath } from "../safeTargetPath.js";
5
7
  import { readRemoteSource } from "./readRemoteSource.js";
6
- export const loadSecrets = async (config, root, environment = process.env, live = false) => {
8
+ import { secretCommand } from "./secretCommand.js";
9
+ export const loadSecrets = async (config, root, environment = process.env, live = false, password) => {
7
10
  let values = {};
8
11
  for (const source of config.sources) {
9
12
  const key = environment[source.keyEnv];
10
- if (!key)
13
+ if (!key && !password)
11
14
  throw new Error(`Missing decryption credential: ${source.keyEnv}.`);
12
15
  try {
13
16
  const text = !live && source.snapshot
@@ -18,10 +21,25 @@ export const loadSecrets = async (config, root, environment = process.env, live
18
21
  createHash("sha256").update(text).digest("hex") !==
19
22
  source.snapshot.sha256)
20
23
  throw new Error("Snapshot integrity mismatch");
21
- const decoded = JSON.parse(await decryptForumEncryptedFileText({
22
- encryptedText: text,
23
- recipientSecret: key,
24
- }));
24
+ let plaintext;
25
+ if (password) {
26
+ const temporary = mkdtempSync(join(tmpdir(), "arcnet-decrypt-"));
27
+ try {
28
+ const file = join(temporary, "source.json.enc");
29
+ writeFileSync(file, text, { mode: 0o600 });
30
+ plaintext = secretCommand("fm", ["decrypt", "--file", file], root, undefined, { ...environment, DOCTRINE_ENCRYPTION_PASSWORD: password });
31
+ }
32
+ finally {
33
+ rmSync(temporary, { recursive: true, force: true });
34
+ }
35
+ }
36
+ else {
37
+ plaintext = await decryptForumEncryptedFileText({
38
+ encryptedText: text,
39
+ recipientSecret: key,
40
+ });
41
+ }
42
+ const decoded = JSON.parse(plaintext);
25
43
  if (!decoded || Array.isArray(decoded) || typeof decoded !== "object")
26
44
  throw new Error("Not an object");
27
45
  values = { ...values, ...decoded };
@@ -1 +1 @@
1
- {"version":3,"file":"loadSecrets.js","sourceRoot":"","sources":["../../src/secrets/loadSecrets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,6BAA6B,EAAE,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,MAAM,CAAC,MAAM,WAAW,GAAG,KAAK,EAC9B,MAAqB,EACrB,IAAY,EACZ,WAAW,GAAG,OAAO,CAAC,GAAG,EACzB,IAAI,GAAG,KAAK,EACZ,EAAE;IACF,IAAI,MAAM,GAA4B,EAAE,CAAC;IAEzC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG;YACN,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;QAEtE,IAAI,CAAC;YACH,MAAM,IAAI,GACR,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ;gBACtB,CAAC,CAAC,YAAY,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAClE,CAAC,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,IAAI,CAAC;YAEvD,IACE,CAAC,IAAI;gBACL,MAAM,CAAC,QAAQ;gBACf,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;oBAC7C,MAAM,CAAC,QAAQ,CAAC,MAAM;gBAExB,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;YAEjD,MAAM,OAAO,GAAY,IAAI,CAAC,KAAK,CACjC,MAAM,6BAA6B,CAAC;gBAClC,aAAa,EAAE,IAAI;gBACnB,eAAe,EAAE,GAAG;aACrB,CAAC,CACH,CAAC;YAEF,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,OAAO,KAAK,QAAQ;gBACnE,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC;YACnC,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CACb,UAAU,MAAM,CAAC,IAAI,oFAAoF,CAC1G,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC"}
1
+ {"version":3,"file":"loadSecrets.js","sourceRoot":"","sources":["../../src/secrets/loadSecrets.ts"],"names":[],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- export declare const withDeploymentSecrets: <T>(root: string, mode: string | undefined, action: () => T | Promise<T>) => Promise<T>;
1
+ export declare const withDeploymentSecrets: <T>(root: string, mode: string | undefined, action: () => T | Promise<T>, usePassword?: boolean, noninteractive?: boolean) => Promise<T>;
2
2
  //# sourceMappingURL=withDeploymentSecrets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"withDeploymentSecrets.d.ts","sourceRoot":"","sources":["../../src/secrets/withDeploymentSecrets.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,qBAAqB,GAAU,CAAC,EAC3C,MAAM,MAAM,EACZ,MAAM,MAAM,GAAG,SAAS,EACxB,QAAQ,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,KAC3B,OAAO,CAAC,CAAC,CAiEX,CAAC"}
1
+ {"version":3,"file":"withDeploymentSecrets.d.ts","sourceRoot":"","sources":["../../src/secrets/withDeploymentSecrets.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,qBAAqB,GAAU,CAAC,EAC3C,MAAM,MAAM,EACZ,MAAM,MAAM,GAAG,SAAS,EACxB,QAAQ,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC5B,qBAAmB,EACnB,wBAAsB,KACrB,OAAO,CAAC,CAAC,CAoEX,CAAC"}
@@ -4,7 +4,8 @@ import { parse } from "yaml";
4
4
  import { readSecretsConfig } from "./config.js";
5
5
  import { loadSecrets } from "./loadSecrets.js";
6
6
  import { selectSecrets } from "./selectSecrets.js";
7
- export const withDeploymentSecrets = async (root, mode, action) => {
7
+ import { promptPassword } from "./promptPassword.js";
8
+ export const withDeploymentSecrets = async (root, mode, action, usePassword = false, noninteractive = false) => {
8
9
  if (!existsSync(join(root, ".arcnet/secrets.json")))
9
10
  return action();
10
11
  const config = readSecretsConfig(root);
@@ -12,7 +13,10 @@ export const withDeploymentSecrets = async (root, mode, action) => {
12
13
  (process.env.GITHUB_REPOSITORY !== config.repository ||
13
14
  process.env.GITHUB_REF !== "refs/heads/main"))
14
15
  throw new Error("Secrets commands in CI require the configured repository main branch.");
15
- const pool = await loadSecrets(config, root);
16
+ if (usePassword && process.env.GITHUB_ACTIONS === "true")
17
+ throw new Error("Password decryption is local-only; CI must use file keys.");
18
+ const password = usePassword ? await promptPassword(noninteractive) : undefined;
19
+ const pool = await loadSecrets(config, root, process.env, false, password);
16
20
  const selected = selectSecrets(pool, config, "deploy");
17
21
  if (mode !== "vercel") {
18
22
  const manifest = parse(readFileSync(join(root, "zap.yaml"), "utf8"));
@@ -1 +1 @@
1
- {"version":3,"file":"withDeploymentSecrets.js","sourceRoot":"","sources":["../../src/secrets/withDeploymentSecrets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"withDeploymentSecrets.js","sourceRoot":"","sources":["../../src/secrets/withDeploymentSecrets.ts"],"names":[],"mappings":"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"}
@@ -25,6 +25,7 @@ Validate decryption and mappings; report key names only.
25
25
  | `--config <file>` | Secrets source configuration |
26
26
  | `--consumer <name>` | Named mapping in the secrets configuration |
27
27
  | `--live` | Fetch current ciphertext through the installed fm CLI instead of snapshots |
28
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
28
29
 
29
30
  ### `arcnet env export`
30
31
 
@@ -35,6 +36,7 @@ Write selected plaintext JSON to stdout for an explicit pipeline.
35
36
  | `--config <file>` | Secrets source configuration |
36
37
  | `--consumer <name>` | Named mapping in the secrets configuration |
37
38
  | `--live` | Fetch current ciphertext through the installed fm CLI instead of snapshots |
39
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
38
40
 
39
41
  ### `arcnet env run <command...>`
40
42
 
@@ -45,6 +47,7 @@ Run a command with selected keys only; withhold child output.
45
47
  | `--config <file>` | Secrets source configuration |
46
48
  | `--consumer <name>` | Named mapping in the secrets configuration |
47
49
  | `--live` | Fetch current ciphertext through the installed fm CLI instead of snapshots |
50
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
48
51
 
49
52
  ## `arcnet secrets`
50
53
 
@@ -111,10 +114,18 @@ Validate project configuration offline.
111
114
 
112
115
  Plan deployment (Terraform contacts providers; static Vercel stays offline).
113
116
 
117
+ | Option | Description |
118
+ | --- | --- |
119
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
120
+
114
121
  ## `arcnet deploy`
115
122
 
116
123
  Deploy the approved project.
117
124
 
125
+ | Option | Description |
126
+ | --- | --- |
127
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
128
+
118
129
  ## `arcnet preview`
119
130
 
120
131
  Deploy static Vercel sites to preview.
@@ -21,6 +21,8 @@ Zap Arc remains the pinned Terraform engine dependency. Environment bootstrap, h
21
21
 
22
22
  `arcnet secrets add` attaches an existing Forum encrypted JSON file. `arcnet secrets init` creates one. Both register a file-specific decryption key in the selected GitHub repository, save an encrypted snapshot, and generate a validation workflow. Setup prompts for your Forum encryption password locally; it never prints the password or recipient key. Use `--existing-key` when the GitHub secret already exists. The local `fm` and `gh` CLIs must be authenticated; the selected Forum parent directory must exist.
23
23
 
24
+ Use `/projects/<project-slug>/secrets.json.enc` for project files in the company Forum store.
25
+
24
26
  The project keeps only `.arcnet/secrets.json`, encrypted snapshots under `.arcnet/secrets/`, and workflow references. Sources merge left to right, with later values winning. Each source names its own key environment variable. JSON must be an object; unused structured values are allowed, while selected environment values must be nonempty strings. Consumer mappings select and rename fields; an array of source names accepts aliases only when their values agree.
25
27
 
26
28
  ```json
@@ -29,7 +31,7 @@ The project keeps only `.arcnet/secrets.json`, encrypted snapshots under `.arcne
29
31
  "repository": "example/hello-world",
30
32
  "sources": [
31
33
  { "name": "standard", "store": "example/company", "path": "/admin/standard.json.enc", "keyEnv": "STANDARD_SECRETS_KEY" },
32
- { "name": "project", "store": "example/company", "path": "/admin/hello-world.json.enc", "keyEnv": "PROJECT_SECRETS_KEY" }
34
+ { "name": "project", "store": "example/company", "path": "/projects/hello-world/secrets.json.enc", "keyEnv": "PROJECT_SECRETS_KEY" }
33
35
  ],
34
36
  "consumers": {
35
37
  "publish": { "NODE_AUTH_TOKEN": ["NPM_TOKEN", "NODE_AUTH_TOKEN"] },
@@ -44,6 +46,8 @@ For live loading, omit a snapshot or select `--live`: the installed `fm` CLI fet
44
46
 
45
47
  `arcnet env check` reports source names and selected key names, never values. `arcnet env export` explicitly emits selected plaintext JSON. `arcnet env run` gives a subprocess only the selected values and a small execution environment; it removes file keys, isolates temporary HOME/cache paths, and withholds subprocess output. Keep npm publishing mappings scoped to publishing credentials. The command reference documents the exact options.
46
48
 
49
+ For the first local Terraform plan and deploy, GitHub's file keys cannot be read back. Run `arcnet plan --password` or `arcnet deploy --password` in your terminal: ArcNet prompts once for your Forum encryption password and decrypts the reviewed snapshots locally. `arcnet env check --password` validates them the same way. CI still uses the independent file keys and rejects password mode.
50
+
47
51
  When `.arcnet/secrets.json` exists, deployment commands automatically load it. The `deploy` consumer selects operator credentials; Terraform application values are selected using the existing service env lists in `zap.yaml`. No duplicated application map is required. Offline project checks remain offline. Secrets commands in GitHub Actions require the configured repository's main branch.
48
52
 
49
53
  Provisioning modifies Forum and GitHub separately. A failed GitHub upload leaves an unused Forum recipient; rerun `secrets add` to create/upload another and remove the unused recipient later. If upload succeeded but snapshot/config writing failed, attach the file with `--existing-key`. Existing sources are not silently rotated on reruns. Provision while nobody else is editing that file: the current fm write interface does not offer atomic revision-conditional writes, though ArcNet checks identity/revision before updating and refuses occupied init paths. GitHub secret names are repository-scoped; environment-level overrides take precedence in jobs that use an environment.
@@ -75,6 +79,7 @@ Validate decryption and mappings; report key names only.
75
79
  | `--config <file>` | Secrets source configuration |
76
80
  | `--consumer <name>` | Named mapping in the secrets configuration |
77
81
  | `--live` | Fetch current ciphertext through the installed fm CLI instead of snapshots |
82
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
78
83
 
79
84
  ### `arcnet env export`
80
85
 
@@ -85,6 +90,7 @@ Write selected plaintext JSON to stdout for an explicit pipeline.
85
90
  | `--config <file>` | Secrets source configuration |
86
91
  | `--consumer <name>` | Named mapping in the secrets configuration |
87
92
  | `--live` | Fetch current ciphertext through the installed fm CLI instead of snapshots |
93
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
88
94
 
89
95
  ### `arcnet env run <command...>`
90
96
 
@@ -95,6 +101,7 @@ Run a command with selected keys only; withhold child output.
95
101
  | `--config <file>` | Secrets source configuration |
96
102
  | `--consumer <name>` | Named mapping in the secrets configuration |
97
103
  | `--live` | Fetch current ciphertext through the installed fm CLI instead of snapshots |
104
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
98
105
 
99
106
  ## `arcnet secrets`
100
107
 
@@ -161,10 +168,18 @@ Validate project configuration offline.
161
168
 
162
169
  Plan deployment (Terraform contacts providers; static Vercel stays offline).
163
170
 
171
+ | Option | Description |
172
+ | --- | --- |
173
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
174
+
164
175
  ## `arcnet deploy`
165
176
 
166
177
  Deploy the approved project.
167
178
 
179
+ | Option | Description |
180
+ | --- | --- |
181
+ | `--password` | Prompt for the Forum encryption password locally instead of using file keys |
182
+
168
183
  ## `arcnet preview`
169
184
 
170
185
  Deploy static Vercel sites to preview.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mp-lb/arcnet",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "description": "ArcNet project installation and deployment CLI.",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/createCli.ts CHANGED
@@ -70,6 +70,11 @@ export const createCli = () => {
70
70
  create: "Create one explicitly approved Vercel project.",
71
71
  })) {
72
72
  const command = cli.command(name).description(description);
73
+ if (name === "plan" || name === "deploy")
74
+ command.option(
75
+ "--password",
76
+ "Prompt for the Forum encryption password locally instead of using file keys",
77
+ );
73
78
  if (name === "create") command.argument("<site>", "Configured site name");
74
79
  command.action(async (site: unknown) => {
75
80
  const root = realpathSync(cli.opts().root);
@@ -100,7 +105,13 @@ export const createCli = () => {
100
105
  output(
101
106
  await (name === "check" || (name === "plan" && mode === "vercel")
102
107
  ? execute()
103
- : withDeploymentSecrets(root, mode, execute)),
108
+ : withDeploymentSecrets(
109
+ root,
110
+ mode,
111
+ execute,
112
+ Boolean(command.opts().password),
113
+ Boolean(cli.opts().noninteractive),
114
+ )),
104
115
  );
105
116
  });
106
117
  }
@@ -7,6 +7,7 @@ import { runWithSecrets } from "./runWithSecrets.js";
7
7
  import { selectSecrets } from "./selectSecrets.js";
8
8
  import { syncSecrets } from "./syncSecrets.js";
9
9
  import { writeSecretsWorkflow } from "./writeSecretsWorkflow.js";
10
+ import { promptPassword } from "./promptPassword.js";
10
11
 
11
12
  export const createSecretsCommands = (
12
13
  cli: Command,
@@ -38,6 +39,10 @@ export const createSecretsCommands = (
38
39
  .option(
39
40
  "--live",
40
41
  "Fetch current ciphertext through the installed fm CLI instead of snapshots",
42
+ )
43
+ .option(
44
+ "--password",
45
+ "Prompt for the Forum encryption password locally instead of using file keys",
41
46
  );
42
47
 
43
48
  if (action === "run")
@@ -47,6 +52,7 @@ export const createSecretsCommands = (
47
52
  config: string;
48
53
  consumer?: string;
49
54
  live?: boolean;
55
+ password?: boolean;
50
56
  }>();
51
57
 
52
58
  const root = realpathSync(cli.opts().root);
@@ -59,9 +65,20 @@ export const createSecretsCommands = (
59
65
  throw new Error(
60
66
  "Secrets commands in CI require the configured repository main branch.",
61
67
  );
68
+ if (options.password && process.env.GITHUB_ACTIONS === "true")
69
+ throw new Error("Password decryption is local-only; CI must use file keys.");
62
70
  if (action !== "check" && !options.consumer)
63
71
  throw new Error("Choose --consumer to explicitly select output keys.");
64
- const values = await loadSecrets(config, root, process.env, options.live);
72
+ const password = options.password
73
+ ? await promptPassword(Boolean(cli.opts().noninteractive))
74
+ : undefined;
75
+ const values = await loadSecrets(
76
+ config,
77
+ root,
78
+ process.env,
79
+ options.live,
80
+ password,
81
+ );
65
82
 
66
83
  const names = options.consumer
67
84
  ? [options.consumer]
@@ -1,21 +1,25 @@
1
1
  import { decryptForumEncryptedFileText } from "@mp-lb/forum-secrets";
2
2
  import { createHash } from "node:crypto";
3
- import { readFileSync } from "node:fs";
3
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
4
+ import { tmpdir } from "node:os";
5
+ import { join } from "node:path";
4
6
  import { safeTargetPath } from "../safeTargetPath.js";
5
7
  import type { SecretsConfig } from "./config.js";
6
8
  import { readRemoteSource } from "./readRemoteSource.js";
9
+ import { secretCommand } from "./secretCommand.js";
7
10
 
8
11
  export const loadSecrets = async (
9
12
  config: SecretsConfig,
10
13
  root: string,
11
14
  environment = process.env,
12
15
  live = false,
16
+ password?: string,
13
17
  ) => {
14
18
  let values: Record<string, unknown> = {};
15
19
 
16
20
  for (const source of config.sources) {
17
21
  const key = environment[source.keyEnv];
18
- if (!key)
22
+ if (!key && !password)
19
23
  throw new Error(`Missing decryption credential: ${source.keyEnv}.`);
20
24
 
21
25
  try {
@@ -32,12 +36,24 @@ export const loadSecrets = async (
32
36
  )
33
37
  throw new Error("Snapshot integrity mismatch");
34
38
 
35
- const decoded: unknown = JSON.parse(
36
- await decryptForumEncryptedFileText({
39
+ let plaintext: string;
40
+ if (password) {
41
+ const temporary = mkdtempSync(join(tmpdir(), "arcnet-decrypt-"));
42
+ try {
43
+ const file = join(temporary, "source.json.enc");
44
+ writeFileSync(file, text, { mode: 0o600 });
45
+ plaintext = secretCommand("fm", ["decrypt", "--file", file], root,
46
+ undefined, { ...environment, DOCTRINE_ENCRYPTION_PASSWORD: password });
47
+ } finally {
48
+ rmSync(temporary, { recursive: true, force: true });
49
+ }
50
+ } else {
51
+ plaintext = await decryptForumEncryptedFileText({
37
52
  encryptedText: text,
38
- recipientSecret: key,
39
- }),
40
- );
53
+ recipientSecret: key!,
54
+ });
55
+ }
56
+ const decoded: unknown = JSON.parse(plaintext);
41
57
 
42
58
  if (!decoded || Array.isArray(decoded) || typeof decoded !== "object")
43
59
  throw new Error("Not an object");
@@ -4,11 +4,14 @@ import { parse } from "yaml";
4
4
  import { readSecretsConfig } from "./config.js";
5
5
  import { loadSecrets } from "./loadSecrets.js";
6
6
  import { selectSecrets } from "./selectSecrets.js";
7
+ import { promptPassword } from "./promptPassword.js";
7
8
 
8
9
  export const withDeploymentSecrets = async <T>(
9
10
  root: string,
10
11
  mode: string | undefined,
11
12
  action: () => T | Promise<T>,
13
+ usePassword = false,
14
+ noninteractive = false,
12
15
  ): Promise<T> => {
13
16
  if (!existsSync(join(root, ".arcnet/secrets.json"))) return action();
14
17
  const config = readSecretsConfig(root);
@@ -20,7 +23,10 @@ export const withDeploymentSecrets = async <T>(
20
23
  throw new Error(
21
24
  "Secrets commands in CI require the configured repository main branch.",
22
25
  );
23
- const pool = await loadSecrets(config, root);
26
+ if (usePassword && process.env.GITHUB_ACTIONS === "true")
27
+ throw new Error("Password decryption is local-only; CI must use file keys.");
28
+ const password = usePassword ? await promptPassword(noninteractive) : undefined;
29
+ const pool = await loadSecrets(config, root, process.env, false, password);
24
30
  const selected = selectSecrets(pool, config, "deploy");
25
31
 
26
32
  if (mode !== "vercel") {
@@ -2,24 +2,24 @@
2
2
  name: mp-lb
3
3
 
4
4
  # Template vars. gcp-project encodes our convention: one GCP project per code
5
- # project, mp-lb-<slug> — the per-project inventory, drift and teardown unit.
5
+ # project, arcnet-<slug> — the per-project inventory, drift and teardown unit.
6
6
  region: asia-southeast1
7
7
  # AWS region for aws-s3 buckets — matches the legacy manual bucket's region.
8
8
  aws-region: ap-southeast-1
9
9
  gcp-project: arcnet-{slug}
10
- network-project: mp-lb-arcnet
10
+ network-project: arcnet-platform
11
11
  billing-account: REPLACE_BILLING_ACCOUNT
12
12
 
13
13
  dns:
14
14
  zone: mp-lb.dev
15
15
 
16
16
  env:
17
- resolver: dx decrypt --file docs/secrets.json.enc
18
- public-file: .env.production
17
+ resolver: "false"
18
+ public-file: .arcnet/unused.env
19
19
 
20
20
  backend:
21
21
  gcs:
22
- bucket: mp-lb-arcnet-terraform-state
22
+ bucket: arcnet-platform-terraform-state
23
23
  prefix: terraform/state/{slug}
24
24
 
25
25
  # Image template; arc appends /<service>:<tag>.
@@ -83,7 +83,7 @@ providers:
83
83
  module-defaults:
84
84
  github-ci:
85
85
  gcp-project-id: "{gcp-project}"
86
- state-bucket: mp-lb-arcnet-terraform-state
86
+ state-bucket: arcnet-platform-terraform-state
87
87
  network-project: "{network-project}"
88
88
  billing-account: "{billing-account}"
89
89
  gcp-project: