getmyenv 0.5.3 → 0.6.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 (161) hide show
  1. package/README.md +57 -13
  2. package/dist/bin.js +1 -24
  3. package/dist/bin.js.map +1 -1
  4. package/dist/cli.d.ts +10 -0
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +179 -106
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/backup.d.ts +2 -1
  9. package/dist/commands/backup.d.ts.map +1 -1
  10. package/dist/commands/backup.js +15 -19
  11. package/dist/commands/backup.js.map +1 -1
  12. package/dist/commands/claim.d.ts +2 -1
  13. package/dist/commands/claim.d.ts.map +1 -1
  14. package/dist/commands/claim.js +114 -80
  15. package/dist/commands/claim.js.map +1 -1
  16. package/dist/commands/context.d.ts +11 -0
  17. package/dist/commands/context.d.ts.map +1 -0
  18. package/dist/commands/context.js +53 -0
  19. package/dist/commands/context.js.map +1 -0
  20. package/dist/commands/export.d.ts +11 -0
  21. package/dist/commands/export.d.ts.map +1 -0
  22. package/dist/commands/export.js +67 -0
  23. package/dist/commands/export.js.map +1 -0
  24. package/dist/commands/guest.d.ts +9 -3
  25. package/dist/commands/guest.d.ts.map +1 -1
  26. package/dist/commands/guest.js +32 -28
  27. package/dist/commands/guest.js.map +1 -1
  28. package/dist/commands/import.d.ts +26 -0
  29. package/dist/commands/import.d.ts.map +1 -0
  30. package/dist/commands/import.js +168 -0
  31. package/dist/commands/import.js.map +1 -0
  32. package/dist/commands/lock.d.ts +5 -0
  33. package/dist/commands/lock.d.ts.map +1 -0
  34. package/dist/commands/lock.js +18 -0
  35. package/dist/commands/lock.js.map +1 -0
  36. package/dist/commands/ls.d.ts +6 -0
  37. package/dist/commands/ls.d.ts.map +1 -0
  38. package/dist/commands/ls.js +37 -0
  39. package/dist/commands/ls.js.map +1 -0
  40. package/dist/commands/restore.d.ts +7 -2
  41. package/dist/commands/restore.d.ts.map +1 -1
  42. package/dist/commands/restore.js +57 -49
  43. package/dist/commands/restore.js.map +1 -1
  44. package/dist/commands/run.d.ts +7 -5
  45. package/dist/commands/run.d.ts.map +1 -1
  46. package/dist/commands/run.js +98 -187
  47. package/dist/commands/run.js.map +1 -1
  48. package/dist/commands/set.d.ts +16 -0
  49. package/dist/commands/set.d.ts.map +1 -0
  50. package/dist/commands/set.js +111 -0
  51. package/dist/commands/set.js.map +1 -0
  52. package/dist/commands/start.d.ts +16 -0
  53. package/dist/commands/start.d.ts.map +1 -0
  54. package/dist/commands/start.js +118 -0
  55. package/dist/commands/start.js.map +1 -0
  56. package/dist/commands/status.d.ts +5 -0
  57. package/dist/commands/status.d.ts.map +1 -0
  58. package/dist/commands/status.js +40 -0
  59. package/dist/commands/status.js.map +1 -0
  60. package/dist/commands/unlink.d.ts +9 -0
  61. package/dist/commands/unlink.d.ts.map +1 -0
  62. package/dist/commands/unlink.js +70 -0
  63. package/dist/commands/unlink.js.map +1 -0
  64. package/dist/lib/api-url.d.ts +12 -0
  65. package/dist/lib/api-url.d.ts.map +1 -1
  66. package/dist/lib/api-url.js +32 -0
  67. package/dist/lib/api-url.js.map +1 -1
  68. package/dist/lib/api.d.ts +35 -23
  69. package/dist/lib/api.d.ts.map +1 -1
  70. package/dist/lib/api.js +23 -59
  71. package/dist/lib/api.js.map +1 -1
  72. package/dist/lib/authorize.d.ts +13 -6
  73. package/dist/lib/authorize.d.ts.map +1 -1
  74. package/dist/lib/authorize.js +68 -61
  75. package/dist/lib/authorize.js.map +1 -1
  76. package/dist/lib/bootstrap.d.ts +18 -15
  77. package/dist/lib/bootstrap.d.ts.map +1 -1
  78. package/dist/lib/bootstrap.js +59 -69
  79. package/dist/lib/bootstrap.js.map +1 -1
  80. package/dist/lib/confirm.js +4 -4
  81. package/dist/lib/confirm.js.map +1 -1
  82. package/dist/lib/context.d.ts +12 -0
  83. package/dist/lib/context.d.ts.map +1 -0
  84. package/dist/lib/context.js +43 -0
  85. package/dist/lib/context.js.map +1 -0
  86. package/dist/lib/credentials.d.ts +8 -13
  87. package/dist/lib/credentials.d.ts.map +1 -1
  88. package/dist/lib/credentials.js +2 -9
  89. package/dist/lib/credentials.js.map +1 -1
  90. package/dist/lib/fs.d.ts +26 -40
  91. package/dist/lib/fs.d.ts.map +1 -1
  92. package/dist/lib/fs.js +112 -326
  93. package/dist/lib/fs.js.map +1 -1
  94. package/dist/lib/guest-key.d.ts +2 -5
  95. package/dist/lib/guest-key.d.ts.map +1 -1
  96. package/dist/lib/guest-key.js +9 -2
  97. package/dist/lib/guest-key.js.map +1 -1
  98. package/dist/lib/identity.d.ts +9 -11
  99. package/dist/lib/identity.d.ts.map +1 -1
  100. package/dist/lib/identity.js +34 -24
  101. package/dist/lib/identity.js.map +1 -1
  102. package/dist/lib/keychain.d.ts +21 -0
  103. package/dist/lib/keychain.d.ts.map +1 -0
  104. package/dist/lib/keychain.js +124 -0
  105. package/dist/lib/keychain.js.map +1 -0
  106. package/dist/lib/pek.d.ts +15 -24
  107. package/dist/lib/pek.d.ts.map +1 -1
  108. package/dist/lib/pek.js +30 -54
  109. package/dist/lib/pek.js.map +1 -1
  110. package/dist/lib/run-env.d.ts +50 -0
  111. package/dist/lib/run-env.d.ts.map +1 -0
  112. package/dist/lib/run-env.js +114 -0
  113. package/dist/lib/run-env.js.map +1 -0
  114. package/dist/lib/unlock.d.ts +24 -0
  115. package/dist/lib/unlock.d.ts.map +1 -0
  116. package/dist/lib/unlock.js +87 -0
  117. package/dist/lib/unlock.js.map +1 -0
  118. package/dist/lib/update-check.d.ts +4 -2
  119. package/dist/lib/update-check.d.ts.map +1 -1
  120. package/dist/lib/update-check.js +54 -68
  121. package/dist/lib/update-check.js.map +1 -1
  122. package/dist/lib/upload.d.ts +21 -0
  123. package/dist/lib/upload.d.ts.map +1 -0
  124. package/dist/lib/upload.js +53 -0
  125. package/dist/lib/upload.js.map +1 -0
  126. package/package.json +5 -3
  127. package/dist/commands/delete.d.ts +0 -6
  128. package/dist/commands/delete.d.ts.map +0 -1
  129. package/dist/commands/delete.js +0 -55
  130. package/dist/commands/delete.js.map +0 -1
  131. package/dist/commands/link.d.ts +0 -16
  132. package/dist/commands/link.d.ts.map +0 -1
  133. package/dist/commands/link.js +0 -142
  134. package/dist/commands/link.js.map +0 -1
  135. package/dist/commands/pull.d.ts +0 -15
  136. package/dist/commands/pull.d.ts.map +0 -1
  137. package/dist/commands/pull.js +0 -155
  138. package/dist/commands/pull.js.map +0 -1
  139. package/dist/commands/push.d.ts +0 -15
  140. package/dist/commands/push.d.ts.map +0 -1
  141. package/dist/commands/push.js +0 -261
  142. package/dist/commands/push.js.map +0 -1
  143. package/dist/commands/remove.d.ts +0 -11
  144. package/dist/commands/remove.d.ts.map +0 -1
  145. package/dist/commands/remove.js +0 -39
  146. package/dist/commands/remove.js.map +0 -1
  147. package/dist/commands/token.d.ts +0 -14
  148. package/dist/commands/token.d.ts.map +0 -1
  149. package/dist/commands/token.js +0 -132
  150. package/dist/commands/token.js.map +0 -1
  151. package/dist/commands/whoami.d.ts +0 -6
  152. package/dist/commands/whoami.d.ts.map +0 -1
  153. package/dist/commands/whoami.js +0 -46
  154. package/dist/commands/whoami.js.map +0 -1
  155. package/dist/lib/env-name.d.ts +0 -3
  156. package/dist/lib/env-name.d.ts.map +0 -1
  157. package/dist/lib/env-name.js +0 -5
  158. package/dist/lib/env-name.js.map +0 -1
  159. package/dist/lib/guest-key.test.d.ts +0 -2
  160. package/dist/lib/guest-key.test.d.ts.map +0 -1
  161. package/dist/lib/guest-key.test.js.map +0 -1
@@ -10,10 +10,7 @@ export type ResolveVaultPasswordOpts = {
10
10
  */
11
11
  create?: boolean;
12
12
  };
13
- /**
14
- * Guest projects wrap the PEK with the passphrase in claim.json.
15
- * Use that silently so guest → push → run needs no Vault password prompt.
16
- * Claimed / human projects still prompt for the Vault password.
17
- */
13
+ /** Password already read from stdin by the command (for example `set --stdin`). */
14
+ export declare function presetVaultPassword(password: string): void;
18
15
  export declare function resolveVaultPassword(opts: ResolveVaultPasswordOpts): Promise<string>;
19
16
  //# sourceMappingURL=guest-key.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"guest-key.d.ts","sourceRoot":"","sources":["../../src/lib/guest-key.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,wBAAwB,GAAG;IACrC,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAsCjB"}
1
+ {"version":3,"file":"guest-key.d.ts","sourceRoot":"","sources":["../../src/lib/guest-key.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,wBAAwB,GAAG;IACrC,wCAAwC;IACxC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AASF,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE1D;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,MAAM,CAAC,CAuCjB"}
@@ -1,16 +1,23 @@
1
1
  import { promptHidden, readClaimFile } from "./fs.js";
2
2
  /**
3
3
  * Guest projects wrap the PEK with the passphrase in claim.json.
4
- * Use that silently so guest → push → run needs no Vault password prompt.
4
+ * Use that silently so guest, set and run need no Vault password prompt.
5
5
  * Claimed / human projects still prompt for the Vault password.
6
6
  */
7
+ let presetPassword = null;
8
+ /** Password already read from stdin by the command (for example `set --stdin`). */
9
+ export function presetVaultPassword(password) {
10
+ presetPassword = password;
11
+ }
7
12
  export async function resolveVaultPassword(opts) {
13
+ if (!opts.isGuest && presetPassword)
14
+ return presetPassword;
8
15
  if (opts.isGuest) {
9
16
  const claim = readClaimFile();
10
17
  if (claim?.passphrase) {
11
18
  return claim.passphrase;
12
19
  }
13
- throw new Error("Guest project is missing .getmyenv/claim.json. Restore it, or run: npx getmyenv claim");
20
+ throw new Error("Guest project is missing .getmyenv/claim.json. Restore it from your repo or a copy.");
14
21
  }
15
22
  if (opts.create) {
16
23
  const password = await promptHidden("New Vault password (hidden): ", {
@@ -1 +1 @@
1
- {"version":3,"file":"guest-key.js","sourceRoot":"","sources":["../../src/lib/guest-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAetD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAA8B;IAE9B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;QAC9B,IAAI,KAAK,EAAE,UAAU,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC,UAAU,CAAC;QAC1B,CAAC;QACD,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,+BAA+B,EAAE;YACnE,UAAU,EAAE,IAAI,CAAC,kBAAkB;SACpC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,mCAAmC,CAAC,CAAC;QACxE,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,YAAY,CACjC,IAAI,CAAC,MAAM,IAAI,2BAA2B,EAC1C;QACE,UAAU,EAAE,IAAI,CAAC,kBAAkB;KACpC,CACF,CAAC;IACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
1
+ {"version":3,"file":"guest-key.js","sourceRoot":"","sources":["../../src/lib/guest-key.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAetD;;;;GAIG;AACH,IAAI,cAAc,GAAkB,IAAI,CAAC;AAEzC,mFAAmF;AACnF,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,cAAc,GAAG,QAAQ,CAAC;AAC5B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,IAA8B;IAE9B,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,cAAc;QAAE,OAAO,cAAc,CAAC;IAC3D,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,KAAK,GAAG,aAAa,EAAE,CAAC;QAC9B,IAAI,KAAK,EAAE,UAAU,EAAE,CAAC;YACtB,OAAO,KAAK,CAAC,UAAU,CAAC;QAC1B,CAAC;QACD,MAAM,IAAI,KAAK,CACb,qFAAqF,CACtF,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,+BAA+B,EAAE;YACnE,UAAU,EAAE,IAAI,CAAC,kBAAkB;SACpC,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,mCAAmC,CAAC,CAAC;QACxE,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,YAAY,CACjC,IAAI,CAAC,MAAM,IAAI,2BAA2B,EAC1C;QACE,UAAU,EAAE,IAAI,CAAC,kBAAkB;KACpC,CACF,CAAC;IACF,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -1,12 +1,10 @@
1
- import { type DevelopmentKeypair } from "@getmyenv/crypto";
2
- export declare function loadOrCreateIdentity(projectId: string): DevelopmentKeypair;
3
- export type StoredGrant = {
4
- grantToken: string;
5
- expiresAt: string;
6
- projectId: string;
7
- environmentId: string;
8
- };
9
- export declare function loadGrant(projectId: string, environmentId: string): StoredGrant | null;
10
- export declare function saveGrant(grant: StoredGrant): void;
11
- export declare function clearGrant(projectId: string, environmentId: string): void;
1
+ import { type MachineKeypair } from "@getmyenv/crypto";
2
+ import { type MachineProof } from "@getmyenv/shared";
3
+ /**
4
+ * Machine identity per project, stored in the OS user config (never the repo).
5
+ * It identifies this machine for locked contexts. It does not decrypt values.
6
+ */
7
+ export declare function loadOrCreateIdentity(projectId: string): MachineKeypair;
8
+ export declare function machineLabel(): string;
9
+ export declare function signMachineProof(projectId: string, contextSlug: string): MachineProof;
12
10
  //# sourceMappingURL=identity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/lib/identity.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,kBAAkB,CAAC;AAG1B,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,CAU1E;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,wBAAgB,SAAS,CACvB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,GACpB,WAAW,GAAG,IAAI,CASpB;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAQlD;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAGzE"}
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/lib/identity.ts"],"names":[],"mappings":"AAGA,OAAO,EAGL,KAAK,cAAc,EACpB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAG1E;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAiBtE;AAED,wBAAgB,YAAY,IAAI,MAAM,CAKrC;AAED,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,YAAY,CAed"}
@@ -1,38 +1,48 @@
1
1
  import fs from "node:fs";
2
+ import os from "node:os";
2
3
  import path from "node:path";
3
- import { generateDevelopmentIdentity, } from "@getmyenv/crypto";
4
+ import { generateMachineIdentity, signAccessRequest, } from "@getmyenv/crypto";
5
+ import { machineProofMessage } from "@getmyenv/shared";
4
6
  import { getConfigDir } from "./fs.js";
7
+ /**
8
+ * Machine identity per project, stored in the OS user config (never the repo).
9
+ * It identifies this machine for locked contexts. It does not decrypt values.
10
+ */
5
11
  export function loadOrCreateIdentity(projectId) {
6
- const dir = path.join(getConfigDir(), "identities");
12
+ const dir = path.join(getConfigDir(), "machines");
7
13
  fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
8
14
  const file = path.join(dir, `${projectId}.json`);
9
15
  if (fs.existsSync(file)) {
10
- return JSON.parse(fs.readFileSync(file, "utf8"));
16
+ try {
17
+ const data = JSON.parse(fs.readFileSync(file, "utf8"));
18
+ if (typeof data.publicKey === "string" && typeof data.privateKey === "string") {
19
+ return { publicKey: data.publicKey, privateKey: data.privateKey };
20
+ }
21
+ }
22
+ catch {
23
+ /* regenerate below */
24
+ }
11
25
  }
12
- const identity = generateDevelopmentIdentity();
26
+ const identity = generateMachineIdentity();
13
27
  fs.writeFileSync(file, JSON.stringify(identity, null, 2), { mode: 0o600 });
14
28
  return identity;
15
29
  }
16
- export function loadGrant(projectId, environmentId) {
17
- const file = path.join(getConfigDir(), "grants", `${projectId}-${environmentId}.json`);
18
- if (!fs.existsSync(file))
19
- return null;
20
- const grant = JSON.parse(fs.readFileSync(file, "utf8"));
21
- if (new Date(grant.expiresAt).getTime() <= Date.now()) {
22
- fs.unlinkSync(file);
23
- return null;
24
- }
25
- return grant;
26
- }
27
- export function saveGrant(grant) {
28
- const dir = path.join(getConfigDir(), "grants");
29
- fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
30
- const file = path.join(dir, `${grant.projectId}-${grant.environmentId}.json`);
31
- fs.writeFileSync(file, JSON.stringify(grant, null, 2), { mode: 0o600 });
30
+ export function machineLabel() {
31
+ const fromEnv = process.env.GETMYENV_MACHINE_LABEL?.trim();
32
+ if (fromEnv)
33
+ return fromEnv.slice(0, 120);
34
+ const user = process.env.USERNAME ?? process.env.USER ?? "user";
35
+ return `${user}@${os.hostname()}`.slice(0, 120);
32
36
  }
33
- export function clearGrant(projectId, environmentId) {
34
- const file = path.join(getConfigDir(), "grants", `${projectId}-${environmentId}.json`);
35
- if (fs.existsSync(file))
36
- fs.unlinkSync(file);
37
+ export function signMachineProof(projectId, contextSlug) {
38
+ const identity = loadOrCreateIdentity(projectId);
39
+ const timestamp = String(Date.now());
40
+ const message = machineProofMessage(projectId, contextSlug, identity.publicKey, timestamp);
41
+ return {
42
+ publicKey: identity.publicKey,
43
+ label: machineLabel(),
44
+ signature: signAccessRequest(identity.privateKey, message),
45
+ timestamp,
46
+ };
37
47
  }
38
48
  //# sourceMappingURL=identity.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/lib/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,2BAA2B,GAE5B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,YAAY,CAAC,CAAC;IACpD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;IACjD,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAuB,CAAC;IACzE,CAAC;IACD,MAAM,QAAQ,GAAG,2BAA2B,EAAE,CAAC;IAC/C,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3E,OAAO,QAAQ,CAAC;AAClB,CAAC;AASD,MAAM,UAAU,SAAS,CACvB,SAAiB,EACjB,aAAqB;IAErB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,GAAG,SAAS,IAAI,aAAa,OAAO,CAAC,CAAC;IACvF,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAgB,CAAC;IACvE,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;QACtD,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAkB;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,QAAQ,CAAC,CAAC;IAChD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CACpB,GAAG,EACH,GAAG,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,aAAa,OAAO,CACjD,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAAiB,EAAE,aAAqB;IACjE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,QAAQ,EAAE,GAAG,SAAS,IAAI,aAAa,OAAO,CAAC,CAAC;IACvF,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;AAC/C,CAAC"}
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/lib/identity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,uBAAuB,EACvB,iBAAiB,GAElB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAqB,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAAiB;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,UAAU,CAAC,CAAC;IAClD,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,OAAO,CAAC,CAAC;IACjD,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxB,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAA4B,CAAC;YAClF,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;gBAC9E,OAAO,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,IAAI,CAAC,UAAU,EAAE,CAAC;YACpE,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,uBAAuB,EAAE,CAAC;IAC3C,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3E,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,IAAI,EAAE,CAAC;IAC3D,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,MAAM,CAAC;IAChE,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,SAAiB,EACjB,WAAmB;IAEnB,MAAM,QAAQ,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,mBAAmB,CACjC,SAAS,EACT,WAAW,EACX,QAAQ,CAAC,SAAS,EAClB,SAAS,CACV,CAAC;IACF,OAAO;QACL,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,KAAK,EAAE,YAAY,EAAE;QACrB,SAAS,EAAE,iBAAiB,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;QAC1D,SAAS;KACV,CAAC;AACJ,CAAC"}
@@ -0,0 +1,21 @@
1
+ export declare const KEYCHAIN_TTL_MS: number;
2
+ type KeyringEntry = {
3
+ getPassword(): string | null;
4
+ setPassword(password: string): void;
5
+ deletePassword(): boolean;
6
+ };
7
+ export type KeyringFactory = (service: string, account: string) => KeyringEntry;
8
+ /** Tests swap in an in-memory keyring. `null` means no keyring available. */
9
+ export declare function setKeyringForTests(factory: KeyringFactory | null | undefined): void;
10
+ /** Off with `GETMYENV_KEYCHAIN=0` or in CI (`CI` set to anything but `false` or `0`). */
11
+ export declare function keychainEnabled(env?: NodeJS.ProcessEnv): boolean;
12
+ /** One keychain entry per server origin and project, so staging and production keys never mix. */
13
+ export declare function keychainAccount(apiUrl: string, projectId: string): string;
14
+ /** The cached key, only if it has not expired and matches the server's wrapped key. */
15
+ export declare function readCachedPek(account: string, wrappedRaw: string, now?: number): Promise<Uint8Array | null>;
16
+ /** Returns false when no keychain is available; the CLI then keeps asking. */
17
+ export declare function storeCachedPek(account: string, wrappedRaw: string, pek: Uint8Array, now?: number): Promise<boolean>;
18
+ /** True when an entry was removed. False when there was none or no keychain is available. */
19
+ export declare function clearCachedPek(account: string): Promise<boolean>;
20
+ export {};
21
+ //# sourceMappingURL=keychain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../../src/lib/keychain.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,eAAe,QAAqB,CAAC;AAElD,KAAK,YAAY,GAAG;IAClB,WAAW,IAAI,MAAM,GAAG,IAAI,CAAC;IAC7B,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,cAAc,IAAI,OAAO,CAAC;CAC3B,CAAC;AACF,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,YAAY,CAAC;AAMhF,6EAA6E;AAC7E,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAEnF;AAYD,yFAAyF;AACzF,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAK7E;AAED,kGAAkG;AAClG,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAQzE;AAgBD,uFAAuF;AACvF,wBAAsB,aAAa,CACjC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,GAAG,SAAa,GACf,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CA2B5B;AAED,8EAA8E;AAC9E,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,UAAU,EACf,GAAG,SAAa,GACf,OAAO,CAAC,OAAO,CAAC,CAclB;AAED,6FAA6F;AAC7F,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAItE"}
@@ -0,0 +1,124 @@
1
+ import { createHash } from "node:crypto";
2
+ /**
3
+ * The unlocked project key, remembered in the OS keychain (macOS Keychain,
4
+ * Windows Credential Manager, Linux Secret Service) for a few hours so `run`
5
+ * on an open context does not ask for the Vault password every time.
6
+ * Never the Vault password itself.
7
+ */
8
+ const SERVICE = "getmyenv";
9
+ export const KEYCHAIN_TTL_MS = 8 * 60 * 60 * 1000;
10
+ let factoryOverride;
11
+ /** Tests swap in an in-memory keyring. `null` means no keyring available. */
12
+ export function setKeyringForTests(factory) {
13
+ factoryOverride = factory;
14
+ }
15
+ async function loadFactory() {
16
+ if (factoryOverride !== undefined)
17
+ return factoryOverride;
18
+ try {
19
+ const { Entry } = await import("@napi-rs/keyring");
20
+ return (service, account) => new Entry(service, account);
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ /** Off with `GETMYENV_KEYCHAIN=0` or in CI (`CI` set to anything but `false` or `0`). */
27
+ export function keychainEnabled(env = process.env) {
28
+ if (env.GETMYENV_KEYCHAIN === "0")
29
+ return false;
30
+ const ci = env.CI?.trim().toLowerCase();
31
+ if (ci && ci !== "false" && ci !== "0")
32
+ return false;
33
+ return true;
34
+ }
35
+ /** One keychain entry per server origin and project, so staging and production keys never mix. */
36
+ export function keychainAccount(apiUrl, projectId) {
37
+ let origin = apiUrl;
38
+ try {
39
+ origin = new URL(apiUrl).origin;
40
+ }
41
+ catch {
42
+ /* keep as given */
43
+ }
44
+ return `${origin}|project:${projectId}`;
45
+ }
46
+ function hashWrapped(wrappedRaw) {
47
+ return createHash("sha256").update(wrappedRaw).digest("hex");
48
+ }
49
+ async function entryFor(account) {
50
+ const factory = await loadFactory();
51
+ if (!factory)
52
+ return null;
53
+ try {
54
+ return factory(SERVICE, account);
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ /** The cached key, only if it has not expired and matches the server's wrapped key. */
61
+ export async function readCachedPek(account, wrappedRaw, now = Date.now()) {
62
+ const entry = await entryFor(account);
63
+ if (!entry)
64
+ return null;
65
+ let raw;
66
+ try {
67
+ raw = entry.getPassword();
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ if (!raw)
73
+ return null;
74
+ let stored;
75
+ try {
76
+ stored = JSON.parse(raw);
77
+ }
78
+ catch {
79
+ safeDelete(entry);
80
+ return null;
81
+ }
82
+ if (typeof stored.pek !== "string" ||
83
+ stored.wrappedHash !== hashWrapped(wrappedRaw) ||
84
+ typeof stored.expiresAt !== "number" ||
85
+ stored.expiresAt <= now) {
86
+ safeDelete(entry);
87
+ return null;
88
+ }
89
+ return new Uint8Array(Buffer.from(stored.pek, "base64"));
90
+ }
91
+ /** Returns false when no keychain is available; the CLI then keeps asking. */
92
+ export async function storeCachedPek(account, wrappedRaw, pek, now = Date.now()) {
93
+ const entry = await entryFor(account);
94
+ if (!entry)
95
+ return false;
96
+ const stored = {
97
+ pek: Buffer.from(pek).toString("base64"),
98
+ wrappedHash: hashWrapped(wrappedRaw),
99
+ expiresAt: now + KEYCHAIN_TTL_MS,
100
+ };
101
+ try {
102
+ entry.setPassword(JSON.stringify(stored));
103
+ return true;
104
+ }
105
+ catch {
106
+ return false;
107
+ }
108
+ }
109
+ /** True when an entry was removed. False when there was none or no keychain is available. */
110
+ export async function clearCachedPek(account) {
111
+ const entry = await entryFor(account);
112
+ if (!entry)
113
+ return false;
114
+ return safeDelete(entry);
115
+ }
116
+ function safeDelete(entry) {
117
+ try {
118
+ return entry.deletePassword();
119
+ }
120
+ catch {
121
+ return false;
122
+ }
123
+ }
124
+ //# sourceMappingURL=keychain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/lib/keychain.ts"],"names":[],"mappings":"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"}
package/dist/lib/pek.d.ts CHANGED
@@ -1,36 +1,27 @@
1
- import type { CliScope } from "./credentials.js";
2
- export declare function wrappedKeyPath(cwd?: string): string;
3
- /** Remove cached wrapped PEK for this folder (getmyenv delete). */
4
- export declare function clearWrappedKey(cwd?: string): boolean;
5
- /** True when `.getmyenv/wrapped-key.json` exists (development cache). */
6
- export declare function hasLocalWrappedKey(cwd?: string): boolean;
7
- /** Write development wrapped-key cache (guest + push). */
8
- export declare function writeCachedWrappedKey(wrappedRaw: string, cwd?: string): void;
9
1
  /**
10
- * Load / unwrap PEK.
11
- * - Development: may read/write `.getmyenv/wrapped-key.json`
12
- * - Production: never reads or writes the cache; always uses password + provided wrapped key
2
+ * `.getmyenv/key.json` (gitignored): the wrapped project key, cached for open
3
+ * contexts. It is useless without the Vault password. Locked reads never
4
+ * read or write it.
5
+ */
6
+ export declare function keyFilePath(cwd?: string): string;
7
+ export declare function clearCachedKey(cwd?: string): boolean;
8
+ export declare function hasCachedKey(cwd?: string): boolean;
9
+ export declare function writeCachedKey(wrappedRaw: string, cwd?: string): void;
10
+ /**
11
+ * Unwrap the project key.
12
+ * - `wrapped` from the server wins over the cache (it may have been rewrapped).
13
+ * - `cache: true` (open contexts) reads and refreshes key.json.
14
+ * - `allowCreate` makes a new project key when none exists yet.
13
15
  */
14
16
  export declare function loadPek(opts: {
15
17
  password: string;
16
- scope: CliScope;
17
- /** Server or previously known wrapped key (required for production). */
18
+ cache: boolean;
18
19
  wrapped?: unknown;
19
- /** Allow creating a new wrapped key when none exists (push / first upload). */
20
20
  allowCreate?: boolean;
21
21
  cwd?: string;
22
22
  }): Promise<{
23
23
  pek: Uint8Array;
24
24
  wrappedRaw: string;
25
+ created: boolean;
25
26
  }>;
26
- /**
27
- * Unwrap a known wrapped key (e.g. from export / grant).
28
- * Writes development cache only; production never caches.
29
- */
30
- export declare function unwrapPek(opts: {
31
- password: string;
32
- scope: CliScope;
33
- wrapped: unknown;
34
- cwd?: string;
35
- }): Promise<Uint8Array>;
36
27
  //# sourceMappingURL=pek.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pek.d.ts","sourceRoot":"","sources":["../../src/lib/pek.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,wBAAgB,cAAc,CAAC,GAAG,SAAgB,GAAG,MAAM,CAE1D;AAED,mEAAmE;AACnE,wBAAgB,eAAe,CAAC,GAAG,SAAgB,GAAG,OAAO,CAK5D;AAQD,yEAAyE;AACzE,wBAAgB,kBAAkB,CAAC,GAAG,SAAgB,GAAG,OAAO,CAE/D;AAQD,0DAA0D;AAC1D,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,GAAG,SAAgB,GAClB,IAAI,CAEN;AAOD;;;;GAIG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC;IAChB,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAC,CAyCnD;AAED;;;GAGG;AACH,wBAAsB,SAAS,CAAC,IAAI,EAAE;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,UAAU,CAAC,CAStB"}
1
+ {"version":3,"file":"pek.d.ts","sourceRoot":"","sources":["../../src/lib/pek.ts"],"names":[],"mappings":"AAUA;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,GAAG,SAAgB,GAAG,MAAM,CAEvD;AAED,wBAAgB,cAAc,CAAC,GAAG,SAAgB,GAAG,OAAO,CAK3D;AAQD,wBAAgB,YAAY,CAAC,GAAG,SAAgB,GAAG,OAAO,CAEzD;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,SAAgB,GAAG,IAAI,CAI5E;AAOD;;;;;GAKG;AACH,wBAAsB,OAAO,CAAC,IAAI,EAAE;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC;IAAE,GAAG,EAAE,UAAU,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,CAoBrE"}
package/dist/lib/pek.js CHANGED
@@ -2,88 +2,64 @@ import fs from "node:fs";
2
2
  import path from "node:path";
3
3
  import { createWrappedProjectKey, parseWrappedKey, serializeWrappedKey, unwrapProjectKey, } from "@getmyenv/crypto";
4
4
  import { getGetenvDir } from "./fs.js";
5
- export function wrappedKeyPath(cwd = process.cwd()) {
6
- return path.join(getGetenvDir(cwd), "wrapped-key.json");
5
+ /**
6
+ * `.getmyenv/key.json` (gitignored): the wrapped project key, cached for open
7
+ * contexts. It is useless without the Vault password. Locked reads never
8
+ * read or write it.
9
+ */
10
+ export function keyFilePath(cwd = process.cwd()) {
11
+ return path.join(getGetenvDir(cwd), "key.json");
7
12
  }
8
- /** Remove cached wrapped PEK for this folder (getmyenv delete). */
9
- export function clearWrappedKey(cwd = process.cwd()) {
10
- const file = wrappedKeyPath(cwd);
13
+ export function clearCachedKey(cwd = process.cwd()) {
14
+ const file = keyFilePath(cwd);
11
15
  if (!fs.existsSync(file))
12
16
  return false;
13
17
  fs.unlinkSync(file);
14
18
  return true;
15
19
  }
16
- function readCachedWrapped(cwd) {
17
- const file = wrappedKeyPath(cwd);
20
+ function readCachedKey(cwd) {
21
+ const file = keyFilePath(cwd);
18
22
  if (!fs.existsSync(file))
19
23
  return null;
20
24
  return fs.readFileSync(file, "utf8");
21
25
  }
22
- /** True when `.getmyenv/wrapped-key.json` exists (development cache). */
23
- export function hasLocalWrappedKey(cwd = process.cwd()) {
24
- return fs.existsSync(wrappedKeyPath(cwd));
26
+ export function hasCachedKey(cwd = process.cwd()) {
27
+ return fs.existsSync(keyFilePath(cwd));
25
28
  }
26
- function writeCachedWrapped(wrappedRaw, cwd) {
27
- const file = wrappedKeyPath(cwd);
28
- fs.mkdirSync(path.dirname(file), { recursive: true });
29
+ export function writeCachedKey(wrappedRaw, cwd = process.cwd()) {
30
+ const file = keyFilePath(cwd);
31
+ fs.mkdirSync(path.dirname(file), { recursive: true, mode: 0o700 });
29
32
  fs.writeFileSync(file, wrappedRaw, { mode: 0o600 });
30
33
  }
31
- /** Write development wrapped-key cache (guest + push). */
32
- export function writeCachedWrappedKey(wrappedRaw, cwd = process.cwd()) {
33
- writeCachedWrapped(wrappedRaw, cwd);
34
- }
35
34
  function normalizeWrappedRaw(wrapped) {
36
35
  if (typeof wrapped === "string")
37
36
  return wrapped;
38
37
  return JSON.stringify(wrapped);
39
38
  }
40
39
  /**
41
- * Load / unwrap PEK.
42
- * - Development: may read/write `.getmyenv/wrapped-key.json`
43
- * - Production: never reads or writes the cache; always uses password + provided wrapped key
40
+ * Unwrap the project key.
41
+ * - `wrapped` from the server wins over the cache (it may have been rewrapped).
42
+ * - `cache: true` (open contexts) reads and refreshes key.json.
43
+ * - `allowCreate` makes a new project key when none exists yet.
44
44
  */
45
45
  export async function loadPek(opts) {
46
46
  const cwd = opts.cwd ?? process.cwd();
47
- const isProd = opts.scope === "production";
48
- let wrappedRaw = null;
49
- if (!isProd) {
50
- wrappedRaw = readCachedWrapped(cwd);
51
- }
52
- if (!wrappedRaw && opts.wrapped != null) {
53
- wrappedRaw = normalizeWrappedRaw(opts.wrapped);
54
- }
47
+ let wrappedRaw = opts.wrapped != null ? normalizeWrappedRaw(opts.wrapped) : null;
48
+ if (!wrappedRaw && opts.cache)
49
+ wrappedRaw = readCachedKey(cwd);
55
50
  if (!wrappedRaw) {
56
51
  if (!opts.allowCreate) {
57
- throw new Error(isProd
58
- ? "No project key available. Pull or push once after unlocking with your vault password."
59
- : "No local wrapped key. Push secrets first, or pass the server key.");
52
+ throw new Error("This project has no key yet. Set a value first: npx getmyenv set KEY");
60
53
  }
61
54
  const created = await createWrappedProjectKey(opts.password);
62
55
  wrappedRaw = serializeWrappedKey(created.wrapped);
63
- if (!isProd) {
64
- writeCachedWrapped(wrappedRaw, cwd);
65
- }
66
- return { pek: created.pek, wrappedRaw };
56
+ if (opts.cache)
57
+ writeCachedKey(wrappedRaw, cwd);
58
+ return { pek: created.pek, wrappedRaw, created: true };
67
59
  }
68
60
  const pek = await unwrapProjectKey(opts.password, parseWrappedKey(wrappedRaw));
69
- // Cache only for development after a successful unwrap from remote.
70
- if (!isProd && opts.wrapped != null) {
71
- writeCachedWrapped(wrappedRaw, cwd);
72
- }
73
- return { pek, wrappedRaw };
74
- }
75
- /**
76
- * Unwrap a known wrapped key (e.g. from export / grant).
77
- * Writes development cache only; production never caches.
78
- */
79
- export async function unwrapPek(opts) {
80
- const { pek } = await loadPek({
81
- password: opts.password,
82
- scope: opts.scope,
83
- wrapped: opts.wrapped,
84
- allowCreate: false,
85
- cwd: opts.cwd,
86
- });
87
- return pek;
61
+ if (opts.cache)
62
+ writeCachedKey(wrappedRaw, cwd);
63
+ return { pek, wrappedRaw, created: false };
88
64
  }
89
65
  //# sourceMappingURL=pek.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"pek.js","sourceRoot":"","sources":["../../src/lib/pek.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,uBAAuB,EACvB,eAAe,EACf,mBAAmB,EACnB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAGvC,MAAM,UAAU,cAAc,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAChD,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,EAAE,kBAAkB,CAAC,CAAC;AAC1D,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,eAAe,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACjD,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACpB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AACvC,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,kBAAkB,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IACpD,OAAO,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,kBAAkB,CAAC,UAAkB,EAAE,GAAW;IACzD,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACjC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,0DAA0D;AAC1D,MAAM,UAAU,qBAAqB,CACnC,UAAkB,EAClB,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE;IAEnB,kBAAkB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAgB;IAC3C,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC;IAChD,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAQ7B;IACC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,KAAK,YAAY,CAAC;IAE3C,IAAI,UAAU,GAAkB,IAAI,CAAC;IAErC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,UAAU,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;QACxC,UAAU,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACjD,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,MAAM,IAAI,KAAK,CACb,MAAM;gBACJ,CAAC,CAAC,uFAAuF;gBACzF,CAAC,CAAC,mEAAmE,CACxE,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,uBAAuB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7D,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,kBAAkB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACtC,CAAC;QACD,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,UAAU,EAAE,CAAC;IAC1C,CAAC;IAED,MAAM,GAAG,GAAG,MAAM,gBAAgB,CAChC,IAAI,CAAC,QAAQ,EACb,eAAe,CAAC,UAAU,CAAC,CAC5B,CAAC;IAEF,oEAAoE;IACpE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC;QACpC,kBAAkB,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;IACtC,CAAC;IAED,OAAO,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAK/B;IACC,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,OAAO,CAAC;QAC5B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,WAAW,EAAE,KAAK;QAClB,GAAG,EAAE,IAAI,CAAC,GAAG;KACd,CAAC,CAAC;IACH,OAAO,GAAG,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"pek.js","sourceRoot":"","sources":["../../src/lib/pek.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Pure pieces of `getmyenv run`: validate and merge. Names only in any output.
3
+ */
4
+ export type MissingKey = {
5
+ name: string;
6
+ reason: "missing" | "expired";
7
+ };
8
+ export type ParentEnv = Record<string, string | undefined>;
9
+ export type Origin = "context" | "context-overrides-parent" | "parent-kept" | "parent-fills-missing" | "missing";
10
+ export type ExplainEntry = {
11
+ name: string;
12
+ origin: Origin;
13
+ reason?: MissingKey["reason"];
14
+ };
15
+ export type MergeResult = {
16
+ env: ParentEnv;
17
+ /** Names set from the context. */
18
+ applied: string[];
19
+ /** Names the context replaced in the parent env. */
20
+ overridden: string[];
21
+ /** Names the parent env kept because of --keep-existing. */
22
+ kept: string[];
23
+ /** Keys missing in the context but present in the parent env. */
24
+ filledByParent: string[];
25
+ /** Keys missing in the context and absent from the parent env. */
26
+ unresolved: MissingKey[];
27
+ entries: ExplainEntry[];
28
+ };
29
+ /** The child never sees the CLI's own settings (token, API URL, config dir). */
30
+ export declare function withoutOwnEnv(parent: ParentEnv): ParentEnv;
31
+ /**
32
+ * Merge context values into the parent env.
33
+ * The context wins unless keepExisting is set. A key missing in the context is
34
+ * satisfied when the parent env already has it (for example from `op run`).
35
+ */
36
+ export declare function mergeEnv(parent: ParentEnv, values: Record<string, string>, missing: MissingKey[], keepExisting: boolean): MergeResult;
37
+ /** Error text when keys are unresolved and --allow-missing is not set. Null when fine. */
38
+ export declare function validationError(result: Pick<MergeResult, "unresolved">, contextSlug: string, allowMissing: boolean): string | null;
39
+ /**
40
+ * One cmd.exe command line from argv. Windows needs the shell to find `npm.cmd`
41
+ * and friends, and Node does not quote args passed alongside `shell: true`.
42
+ * cmd expands %VAR% even inside quotes, so each % is closed out of the quotes
43
+ * and escaped with ^.
44
+ */
45
+ export declare function windowsCommandLine(args: string[]): string;
46
+ /** Exit code for a child that ended by signal: 128 + signal number, like a shell. */
47
+ export declare function signalExitCode(signal: NodeJS.Signals, numbers: Record<string, number>): number;
48
+ /** `--explain` output. Names and origins only, never values. */
49
+ export declare function explainLines(result: MergeResult, contextSlug: string): string[];
50
+ //# sourceMappingURL=run-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-env.d.ts","sourceRoot":"","sources":["../../src/lib/run-env.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAAA;CAAE,CAAC;AAEzE,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;AAE3D,MAAM,MAAM,MAAM,GACd,SAAS,GACT,0BAA0B,GAC1B,aAAa,GACb,sBAAsB,GACtB,SAAS,CAAC;AAEd,MAAM,MAAM,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAA;CAAE,CAAC;AAE3F,MAAM,MAAM,WAAW,GAAG;IACxB,GAAG,EAAE,SAAS,CAAC;IACf,kCAAkC;IAClC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oDAAoD;IACpD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,4DAA4D;IAC5D,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,iEAAiE;IACjE,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kEAAkE;IAClE,UAAU,EAAE,UAAU,EAAE,CAAC;IACzB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,SAAS,CAM1D;AAOD;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,EAAE,UAAU,EAAE,EACrB,YAAY,EAAE,OAAO,GACpB,WAAW,CAyCb;AAED,0FAA0F;AAC1F,wBAAgB,eAAe,CAC7B,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,EACvC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,OAAO,GACpB,MAAM,GAAG,IAAI,CAWf;AAWD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CASzD;AAED,qFAAqF;AACrF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAG9F;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAU/E"}