@wlfi-agent/cli 1.4.13 → 1.4.14

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 (289) hide show
  1. package/Cargo.lock +3968 -0
  2. package/Cargo.toml +50 -0
  3. package/README.md +426 -6
  4. package/crates/vault-cli-admin/Cargo.toml +26 -0
  5. package/crates/vault-cli-admin/src/io_utils.rs +500 -0
  6. package/crates/vault-cli-admin/src/main.rs +3990 -0
  7. package/crates/vault-cli-admin/src/shared_config.rs +624 -0
  8. package/crates/vault-cli-admin/src/tui/amounts.rs +180 -0
  9. package/crates/vault-cli-admin/src/tui/token_rpc.rs +250 -0
  10. package/crates/vault-cli-admin/src/tui/utils.rs +82 -0
  11. package/crates/vault-cli-admin/src/tui.rs +3410 -0
  12. package/crates/vault-cli-agent/Cargo.toml +24 -0
  13. package/crates/vault-cli-agent/src/io_utils.rs +576 -0
  14. package/crates/vault-cli-agent/src/main.rs +833 -0
  15. package/crates/vault-cli-daemon/Cargo.toml +28 -0
  16. package/crates/vault-cli-daemon/src/bin/wlfi-agent-system-keychain.rs +216 -0
  17. package/crates/vault-cli-daemon/src/main.rs +644 -0
  18. package/crates/vault-cli-daemon/src/relay_sync.rs +894 -0
  19. package/crates/vault-cli-daemon/tests/system_keychain_helper_acl.rs +167 -0
  20. package/crates/vault-daemon/Cargo.toml +32 -0
  21. package/crates/vault-daemon/src/daemon_parts/api_impl_and_utils.rs +1041 -0
  22. package/crates/vault-daemon/src/daemon_parts/core_helpers.rs +1256 -0
  23. package/crates/vault-daemon/src/daemon_parts/types_api_rpc.rs +622 -0
  24. package/crates/vault-daemon/src/lib.rs +54 -0
  25. package/crates/vault-daemon/src/persistence.rs +441 -0
  26. package/crates/vault-daemon/src/tests.rs +237 -0
  27. package/crates/vault-daemon/src/tests_parts/part1.rs +1224 -0
  28. package/crates/vault-daemon/src/tests_parts/part2.rs +1021 -0
  29. package/crates/vault-daemon/src/tests_parts/part3.rs +835 -0
  30. package/crates/vault-daemon/src/tests_parts/part4.rs +604 -0
  31. package/crates/vault-domain/Cargo.toml +20 -0
  32. package/crates/vault-domain/src/action.rs +849 -0
  33. package/crates/vault-domain/src/address.rs +51 -0
  34. package/crates/vault-domain/src/approval.rs +90 -0
  35. package/crates/vault-domain/src/constants.rs +4 -0
  36. package/crates/vault-domain/src/error.rs +54 -0
  37. package/crates/vault-domain/src/keys.rs +71 -0
  38. package/crates/vault-domain/src/lib.rs +42 -0
  39. package/crates/vault-domain/src/nonce.rs +102 -0
  40. package/crates/vault-domain/src/policy.rs +172 -0
  41. package/crates/vault-domain/src/request.rs +53 -0
  42. package/crates/vault-domain/src/scope.rs +24 -0
  43. package/crates/vault-domain/src/session.rs +50 -0
  44. package/crates/vault-domain/src/signature.rs +34 -0
  45. package/crates/vault-domain/src/tests.rs +651 -0
  46. package/crates/vault-domain/src/u128_as_decimal_string.rs +44 -0
  47. package/crates/vault-policy/Cargo.toml +17 -0
  48. package/crates/vault-policy/src/engine.rs +301 -0
  49. package/crates/vault-policy/src/error.rs +81 -0
  50. package/crates/vault-policy/src/lib.rs +17 -0
  51. package/crates/vault-policy/src/report.rs +34 -0
  52. package/crates/vault-policy/src/tests.rs +891 -0
  53. package/crates/vault-policy/src/tests_explain.rs +78 -0
  54. package/crates/vault-sdk-agent/Cargo.toml +21 -0
  55. package/crates/vault-sdk-agent/src/lib.rs +711 -0
  56. package/crates/vault-signer/Cargo.toml +25 -0
  57. package/crates/vault-signer/src/lib.rs +731 -0
  58. package/crates/vault-signer/tests/secure_enclave_acl.rs +54 -0
  59. package/crates/vault-transport-unix/Cargo.toml +24 -0
  60. package/crates/vault-transport-unix/src/lib.rs +1640 -0
  61. package/crates/vault-transport-xpc/Cargo.toml +25 -0
  62. package/crates/vault-transport-xpc/src/client_codec_api.rs +635 -0
  63. package/crates/vault-transport-xpc/src/lib.rs +680 -0
  64. package/crates/vault-transport-xpc/src/tests.rs +818 -0
  65. package/crates/vault-transport-xpc/tests/e2e_flow.rs +773 -0
  66. package/dist/cli.cjs +35088 -0
  67. package/dist/cli.cjs.map +1 -0
  68. package/package.json +49 -43
  69. package/packages/cache/.turbo/turbo-build.log +52 -0
  70. package/packages/cache/dist/chunk-2QFWMUXT.cjs +43 -0
  71. package/packages/cache/dist/chunk-2QFWMUXT.cjs.map +1 -0
  72. package/packages/cache/dist/chunk-4U63TZTQ.js +43 -0
  73. package/packages/cache/dist/chunk-4U63TZTQ.js.map +1 -0
  74. package/packages/cache/dist/chunk-ALQ6H7KG.cjs +404 -0
  75. package/packages/cache/dist/chunk-ALQ6H7KG.cjs.map +1 -0
  76. package/packages/cache/dist/chunk-FGJEEF5N.js +404 -0
  77. package/packages/cache/dist/chunk-FGJEEF5N.js.map +1 -0
  78. package/packages/cache/dist/chunk-UYNEHZHB.cjs +45 -0
  79. package/packages/cache/dist/chunk-UYNEHZHB.cjs.map +1 -0
  80. package/packages/cache/dist/chunk-VXVMPG3W.js +45 -0
  81. package/packages/cache/dist/chunk-VXVMPG3W.js.map +1 -0
  82. package/packages/cache/dist/client/index.cjs +11 -0
  83. package/packages/cache/dist/client/index.cjs.map +1 -0
  84. package/packages/cache/dist/client/index.d.cts +15 -0
  85. package/packages/cache/dist/client/index.d.ts +15 -0
  86. package/packages/cache/dist/client/index.js +11 -0
  87. package/packages/cache/dist/client/index.js.map +1 -0
  88. package/packages/cache/dist/errors/index.cjs +11 -0
  89. package/packages/cache/dist/errors/index.cjs.map +1 -0
  90. package/packages/cache/dist/errors/index.d.cts +26 -0
  91. package/packages/cache/dist/errors/index.d.ts +26 -0
  92. package/packages/cache/dist/errors/index.js +11 -0
  93. package/packages/cache/dist/errors/index.js.map +1 -0
  94. package/packages/cache/dist/index.cjs +29 -0
  95. package/packages/cache/dist/index.cjs.map +1 -0
  96. package/packages/cache/dist/index.d.cts +4 -0
  97. package/packages/cache/dist/index.d.ts +4 -0
  98. package/packages/cache/dist/index.js +29 -0
  99. package/packages/cache/dist/index.js.map +1 -0
  100. package/packages/cache/dist/service/index.cjs +15 -0
  101. package/packages/cache/dist/service/index.cjs.map +1 -0
  102. package/packages/cache/dist/service/index.d.cts +184 -0
  103. package/packages/cache/dist/service/index.d.ts +184 -0
  104. package/packages/cache/dist/service/index.js +15 -0
  105. package/packages/cache/dist/service/index.js.map +1 -0
  106. package/packages/cache/node_modules/.bin/jiti +17 -0
  107. package/packages/cache/node_modules/.bin/tsc +17 -0
  108. package/packages/cache/node_modules/.bin/tsserver +17 -0
  109. package/packages/cache/node_modules/.bin/tsup +17 -0
  110. package/packages/cache/node_modules/.bin/tsup-node +17 -0
  111. package/packages/cache/node_modules/.bin/tsx +17 -0
  112. package/packages/cache/node_modules/.bin/vitest +17 -0
  113. package/packages/cache/package.json +48 -0
  114. package/packages/cache/src/client/index.ts +56 -0
  115. package/packages/cache/src/errors/index.ts +53 -0
  116. package/packages/cache/src/index.ts +3 -0
  117. package/packages/cache/src/service/index.test.ts +263 -0
  118. package/packages/cache/src/service/index.ts +678 -0
  119. package/packages/cache/tsconfig.json +13 -0
  120. package/packages/cache/tsup.config.ts +13 -0
  121. package/packages/cache/vitest.config.ts +16 -0
  122. package/packages/config/.turbo/turbo-build.log +18 -0
  123. package/packages/config/dist/index.cjs +1037 -0
  124. package/packages/config/dist/index.cjs.map +1 -0
  125. package/packages/config/dist/index.d.ts +131 -0
  126. package/packages/config/node_modules/.bin/jiti +17 -0
  127. package/packages/config/node_modules/.bin/tsc +17 -0
  128. package/packages/config/node_modules/.bin/tsserver +17 -0
  129. package/packages/config/node_modules/.bin/tsup +17 -0
  130. package/packages/config/node_modules/.bin/tsup-node +17 -0
  131. package/packages/config/node_modules/.bin/tsx +17 -0
  132. package/packages/config/package.json +21 -0
  133. package/packages/config/src/index.js +1 -0
  134. package/packages/config/src/index.ts +1282 -0
  135. package/packages/config/tsconfig.json +4 -0
  136. package/packages/rpc/.turbo/turbo-build.log +32 -0
  137. package/packages/rpc/dist/_esm-BCLXDO2R.cjs +3660 -0
  138. package/packages/rpc/dist/_esm-BCLXDO2R.cjs.map +1 -0
  139. package/packages/rpc/dist/ccip-OWJLAW55.cjs +16 -0
  140. package/packages/rpc/dist/ccip-OWJLAW55.cjs.map +1 -0
  141. package/packages/rpc/dist/chunk-APQIFZ3B.cjs +6247 -0
  142. package/packages/rpc/dist/chunk-APQIFZ3B.cjs.map +1 -0
  143. package/packages/rpc/dist/chunk-CDO2GWRD.cjs +410 -0
  144. package/packages/rpc/dist/chunk-CDO2GWRD.cjs.map +1 -0
  145. package/packages/rpc/dist/chunk-QGTNTFJ7.cjs +2249 -0
  146. package/packages/rpc/dist/chunk-QGTNTFJ7.cjs.map +1 -0
  147. package/packages/rpc/dist/chunk-TZDTAHWR.cjs +44 -0
  148. package/packages/rpc/dist/chunk-TZDTAHWR.cjs.map +1 -0
  149. package/packages/rpc/dist/index.cjs +7342 -0
  150. package/packages/rpc/dist/index.cjs.map +1 -0
  151. package/packages/rpc/dist/index.d.ts +3857 -0
  152. package/packages/rpc/dist/secp256k1-WCNM675D.cjs +18 -0
  153. package/packages/rpc/dist/secp256k1-WCNM675D.cjs.map +1 -0
  154. package/packages/rpc/node_modules/.bin/jiti +17 -0
  155. package/packages/rpc/node_modules/.bin/tsc +17 -0
  156. package/packages/rpc/node_modules/.bin/tsserver +17 -0
  157. package/packages/rpc/node_modules/.bin/tsup +17 -0
  158. package/packages/rpc/node_modules/.bin/tsup-node +17 -0
  159. package/packages/rpc/node_modules/.bin/tsx +17 -0
  160. package/packages/rpc/package.json +25 -0
  161. package/packages/rpc/src/index.ts +206 -0
  162. package/packages/rpc/tsconfig.json +4 -0
  163. package/packages/typescript/base.json +36 -0
  164. package/packages/typescript/nextjs.json +17 -0
  165. package/packages/typescript/package.json +10 -0
  166. package/packages/ui/.turbo/turbo-build.log +44 -0
  167. package/packages/ui/dist/chunk-MOAFBKSA.js +11 -0
  168. package/packages/ui/dist/chunk-MOAFBKSA.js.map +1 -0
  169. package/packages/ui/dist/components/badge.d.ts +12 -0
  170. package/packages/ui/dist/components/badge.js +31 -0
  171. package/packages/ui/dist/components/badge.js.map +1 -0
  172. package/packages/ui/dist/components/button.d.ts +13 -0
  173. package/packages/ui/dist/components/button.js +40 -0
  174. package/packages/ui/dist/components/button.js.map +1 -0
  175. package/packages/ui/dist/components/card.d.ts +10 -0
  176. package/packages/ui/dist/components/card.js +39 -0
  177. package/packages/ui/dist/components/card.js.map +1 -0
  178. package/packages/ui/dist/components/input.d.ts +5 -0
  179. package/packages/ui/dist/components/input.js +28 -0
  180. package/packages/ui/dist/components/input.js.map +1 -0
  181. package/packages/ui/dist/components/label.d.ts +5 -0
  182. package/packages/ui/dist/components/label.js +13 -0
  183. package/packages/ui/dist/components/label.js.map +1 -0
  184. package/packages/ui/dist/components/separator.d.ts +5 -0
  185. package/packages/ui/dist/components/separator.js +13 -0
  186. package/packages/ui/dist/components/separator.js.map +1 -0
  187. package/packages/ui/dist/components/textarea.d.ts +5 -0
  188. package/packages/ui/dist/components/textarea.js +27 -0
  189. package/packages/ui/dist/components/textarea.js.map +1 -0
  190. package/packages/ui/dist/tailwind.d.ts +56 -0
  191. package/packages/ui/dist/tailwind.js +60 -0
  192. package/packages/ui/dist/tailwind.js.map +1 -0
  193. package/packages/ui/dist/utils/cn.d.ts +5 -0
  194. package/packages/ui/dist/utils/cn.js +7 -0
  195. package/packages/ui/dist/utils/cn.js.map +1 -0
  196. package/packages/ui/node_modules/.bin/jiti +17 -0
  197. package/packages/ui/node_modules/.bin/tsc +17 -0
  198. package/packages/ui/node_modules/.bin/tsserver +17 -0
  199. package/packages/ui/node_modules/.bin/tsup +17 -0
  200. package/packages/ui/node_modules/.bin/tsup-node +17 -0
  201. package/packages/ui/node_modules/.bin/tsx +17 -0
  202. package/packages/ui/package.json +69 -0
  203. package/packages/ui/src/components/badge.tsx +27 -0
  204. package/packages/ui/src/components/button.tsx +40 -0
  205. package/packages/ui/src/components/card.tsx +31 -0
  206. package/packages/ui/src/components/input.tsx +21 -0
  207. package/packages/ui/src/components/label.tsx +6 -0
  208. package/packages/ui/src/components/separator.tsx +6 -0
  209. package/packages/ui/src/components/textarea.tsx +20 -0
  210. package/packages/ui/src/globals.css +70 -0
  211. package/packages/ui/src/tailwind.ts +56 -0
  212. package/packages/ui/src/utils/cn.ts +6 -0
  213. package/packages/ui/tsconfig.json +20 -0
  214. package/packages/ui/tsup.config.ts +20 -0
  215. package/pnpm-workspace.yaml +4 -0
  216. package/scripts/install-rust-binaries.mjs +84 -0
  217. package/scripts/launchd/install-user-daemon.sh +358 -0
  218. package/scripts/launchd/run-vault-daemon.sh +5 -0
  219. package/scripts/launchd/run-wlfi-agent-daemon.sh +73 -0
  220. package/scripts/launchd/uninstall-user-daemon.sh +103 -0
  221. package/src/cli.ts +2121 -0
  222. package/src/lib/admin-guard.js +1 -0
  223. package/src/lib/admin-guard.ts +185 -0
  224. package/src/lib/admin-passthrough.ts +33 -0
  225. package/src/lib/admin-reset.ts +751 -0
  226. package/src/lib/admin-setup.ts +1612 -0
  227. package/src/lib/agent-auth-clear.js +1 -0
  228. package/src/lib/agent-auth-clear.ts +58 -0
  229. package/src/lib/agent-auth-forwarding.js +1 -0
  230. package/src/lib/agent-auth-forwarding.ts +149 -0
  231. package/src/lib/agent-auth-migrate.js +1 -0
  232. package/src/lib/agent-auth-migrate.ts +150 -0
  233. package/src/lib/agent-auth-revoke.ts +103 -0
  234. package/src/lib/agent-auth-rotate.ts +107 -0
  235. package/src/lib/agent-auth-token.js +1 -0
  236. package/src/lib/agent-auth-token.ts +25 -0
  237. package/src/lib/agent-auth.ts +89 -0
  238. package/src/lib/asset-broadcast.js +1 -0
  239. package/src/lib/asset-broadcast.ts +285 -0
  240. package/src/lib/bootstrap-artifacts.js +1 -0
  241. package/src/lib/bootstrap-artifacts.ts +205 -0
  242. package/src/lib/bootstrap-credentials.js +1 -0
  243. package/src/lib/bootstrap-credentials.ts +832 -0
  244. package/src/lib/config-amounts.js +1 -0
  245. package/src/lib/config-amounts.ts +189 -0
  246. package/src/lib/config-mutation.ts +27 -0
  247. package/src/lib/fs-trust.js +1 -0
  248. package/src/lib/fs-trust.ts +537 -0
  249. package/src/lib/keychain.js +1 -0
  250. package/src/lib/keychain.ts +225 -0
  251. package/src/lib/local-admin-access.ts +106 -0
  252. package/src/lib/network-selection.js +1 -0
  253. package/src/lib/network-selection.ts +71 -0
  254. package/src/lib/passthrough-security.js +1 -0
  255. package/src/lib/passthrough-security.ts +114 -0
  256. package/src/lib/rpc-guard.js +1 -0
  257. package/src/lib/rpc-guard.ts +7 -0
  258. package/src/lib/rust-spawn-options.js +1 -0
  259. package/src/lib/rust-spawn-options.ts +98 -0
  260. package/src/lib/rust.js +1 -0
  261. package/src/lib/rust.ts +143 -0
  262. package/src/lib/signed-tx.js +1 -0
  263. package/src/lib/signed-tx.ts +116 -0
  264. package/src/lib/status-repair-cli.ts +116 -0
  265. package/src/lib/sudo.js +1 -0
  266. package/src/lib/sudo.ts +172 -0
  267. package/src/lib/vault-password-forwarding.js +1 -0
  268. package/src/lib/vault-password-forwarding.ts +155 -0
  269. package/src/lib/wallet-profile.js +1 -0
  270. package/src/lib/wallet-profile.ts +332 -0
  271. package/src/lib/wallet-repair.js +1 -0
  272. package/src/lib/wallet-repair.ts +304 -0
  273. package/src/lib/wallet-setup.js +1 -0
  274. package/src/lib/wallet-setup.ts +1466 -0
  275. package/src/lib/wallet-status.js +1 -0
  276. package/src/lib/wallet-status.ts +640 -0
  277. package/tsconfig.base.json +17 -0
  278. package/tsconfig.json +10 -0
  279. package/tsup.config.ts +25 -0
  280. package/turbo.json +41 -0
  281. package/LICENSE.md +0 -1
  282. package/dist/wlfa/index.cjs +0 -250
  283. package/dist/wlfa/index.d.cts +0 -1
  284. package/dist/wlfa/index.d.ts +0 -1
  285. package/dist/wlfa/index.js +0 -250
  286. package/dist/wlfc/index.cjs +0 -1839
  287. package/dist/wlfc/index.d.cts +0 -1
  288. package/dist/wlfc/index.d.ts +0 -1
  289. package/dist/wlfc/index.js +0 -1839
@@ -0,0 +1 @@
1
+ export * from './agent-auth-clear.ts';
@@ -0,0 +1,58 @@
1
+ import {
2
+ deleteConfigKey,
3
+ redactConfig,
4
+ readConfig,
5
+ type WlfiConfig
6
+ } from '../../packages/config/src/index.js';
7
+ import {
8
+ AGENT_AUTH_TOKEN_KEYCHAIN_SERVICE,
9
+ assertValidAgentKeyId,
10
+ deleteAgentAuthTokenFromKeychain
11
+ } from './keychain.js';
12
+
13
+ export interface ClearAgentAuthTokenResult {
14
+ agentKeyId: string;
15
+ keychain: {
16
+ removed: boolean;
17
+ service: string | null;
18
+ };
19
+ config: Record<string, unknown>;
20
+ }
21
+
22
+ interface ClearAgentAuthTokenDeps {
23
+ platform?: NodeJS.Platform;
24
+ deleteAgentAuthToken?: (agentKeyId: string) => boolean;
25
+ readConfig?: () => WlfiConfig;
26
+ deleteConfigKey?: (key: keyof WlfiConfig) => WlfiConfig;
27
+ }
28
+
29
+ export function clearAgentAuthToken(
30
+ agentKeyId: string,
31
+ deps: ClearAgentAuthTokenDeps = {}
32
+ ): ClearAgentAuthTokenResult {
33
+ const platform = deps.platform ?? process.platform;
34
+ const normalizedAgentKeyId = assertValidAgentKeyId(agentKeyId);
35
+ const removeAgentAuthToken = deps.deleteAgentAuthToken ?? deleteAgentAuthTokenFromKeychain;
36
+ const loadConfig = deps.readConfig ?? readConfig;
37
+ const clearConfigKey = deps.deleteConfigKey ?? deleteConfigKey;
38
+
39
+ const existing = loadConfig();
40
+ const removed = removeAgentAuthToken(normalizedAgentKeyId);
41
+
42
+ let updated = existing;
43
+ if (existing.agentKeyId === normalizedAgentKeyId) {
44
+ updated = clearConfigKey('agentKeyId');
45
+ }
46
+ if (updated.agentAuthToken !== undefined) {
47
+ updated = clearConfigKey('agentAuthToken');
48
+ }
49
+
50
+ return {
51
+ agentKeyId: normalizedAgentKeyId,
52
+ keychain: {
53
+ removed,
54
+ service: platform === 'darwin' ? AGENT_AUTH_TOKEN_KEYCHAIN_SERVICE : null
55
+ },
56
+ config: redactConfig(updated)
57
+ };
58
+ }
@@ -0,0 +1 @@
1
+ export * from './agent-auth-forwarding.ts';
@@ -0,0 +1,149 @@
1
+ import {
2
+ MAX_AGENT_AUTH_TOKEN_BYTES,
3
+ assertValidAgentAuthToken
4
+ } from './agent-auth-token.js';
5
+
6
+ export interface AgentAuthRelayOptions {
7
+ env?: NodeJS.ProcessEnv;
8
+ readFromStdin?: (label: string) => Promise<string>;
9
+ }
10
+
11
+ export interface PreparedAgentAuthRelay {
12
+ args: string[];
13
+ stdin?: string;
14
+ scrubSensitiveEnv: boolean;
15
+ }
16
+
17
+ const HELP_FLAGS = new Set(['-h', '--help', '-V', '--version']);
18
+
19
+ function forwardedArgsPrefix(args: string[]): string[] {
20
+ const terminatorIndex = args.indexOf('--');
21
+ return terminatorIndex >= 0 ? args.slice(0, terminatorIndex) : args;
22
+ }
23
+
24
+ function skipEnvRelayForArgs(args: string[]): boolean {
25
+ const forwarded = forwardedArgsPrefix(args);
26
+ return forwarded[0] === 'help' || forwarded.some((arg) => HELP_FLAGS.has(arg));
27
+ }
28
+
29
+ function resolveInlineAgentAuthTokenArg(args: string[]): {
30
+ index: number;
31
+ value: string;
32
+ } | null {
33
+ let match: { index: number; value: string } | null = null;
34
+
35
+ for (let index = 0; index < forwardedArgsPrefix(args).length; index += 1) {
36
+ const current = args[index];
37
+ let nextMatch: { index: number; value: string } | null = null;
38
+
39
+ if (current === '--agent-auth-token') {
40
+ const value = args[index + 1];
41
+ if (value === undefined) {
42
+ throw new Error('--agent-auth-token requires a value');
43
+ }
44
+ nextMatch = { index, value };
45
+ index += 1;
46
+ } else if (current.startsWith('--agent-auth-token=')) {
47
+ nextMatch = {
48
+ index,
49
+ value: current.slice('--agent-auth-token='.length)
50
+ };
51
+ }
52
+
53
+ if (nextMatch) {
54
+ if (match) {
55
+ throw new Error('--agent-auth-token may only be provided once');
56
+ }
57
+ match = nextMatch;
58
+ }
59
+ }
60
+
61
+ return match;
62
+ }
63
+
64
+ function countAgentAuthTokenStdinFlags(args: string[]): number {
65
+ let matches = 0;
66
+
67
+ for (const current of forwardedArgsPrefix(args)) {
68
+ if (current === '--agent-auth-token-stdin') {
69
+ matches += 1;
70
+ }
71
+ }
72
+
73
+ return matches;
74
+ }
75
+
76
+ function validateSecret(secret: string, label: string): string {
77
+ return assertValidAgentAuthToken(secret, label);
78
+ }
79
+
80
+ function withTrailingNewline(secret: string): string {
81
+ return `${secret}\n`;
82
+ }
83
+
84
+ async function readTrimmedSecretFromProcessStdin(label: string): Promise<string> {
85
+ process.stdin.setEncoding('utf8');
86
+ let raw = '';
87
+ for await (const chunk of process.stdin) {
88
+ raw += chunk;
89
+ if (Buffer.byteLength(raw, 'utf8') > MAX_AGENT_AUTH_TOKEN_BYTES) {
90
+ throw new Error(`${label} must not exceed ${MAX_AGENT_AUTH_TOKEN_BYTES} bytes`);
91
+ }
92
+ }
93
+
94
+ return validateSecret(raw, label);
95
+ }
96
+
97
+ export async function prepareAgentAuthRelay(
98
+ args: string[],
99
+ options: AgentAuthRelayOptions = {}
100
+ ): Promise<PreparedAgentAuthRelay> {
101
+ const env = options.env ?? process.env;
102
+ const readFromStdin = options.readFromStdin ?? readTrimmedSecretFromProcessStdin;
103
+ const inlineArg = resolveInlineAgentAuthTokenArg(args);
104
+ const stdinFlagCount = countAgentAuthTokenStdinFlags(args);
105
+ const usesStdinFlag = stdinFlagCount > 0;
106
+
107
+ if (stdinFlagCount > 1) {
108
+ throw new Error('--agent-auth-token-stdin may only be provided once');
109
+ }
110
+
111
+ if (inlineArg && usesStdinFlag) {
112
+ throw new Error('--agent-auth-token conflicts with --agent-auth-token-stdin');
113
+ }
114
+
115
+ if (inlineArg) {
116
+ validateSecret(inlineArg.value, 'agentAuthToken');
117
+ throw new Error(
118
+ '--agent-auth-token is disabled for security; use --agent-auth-token-stdin or macOS Keychain-backed `wlfi-agent` commands'
119
+ );
120
+ }
121
+
122
+ if (usesStdinFlag) {
123
+ return {
124
+ args: [...args],
125
+ stdin: withTrailingNewline(validateSecret(await readFromStdin('agentAuthToken'), 'agentAuthToken')),
126
+ scrubSensitiveEnv: true
127
+ };
128
+ }
129
+
130
+ if (Object.prototype.hasOwnProperty.call(env, 'WLFI_AGENT_AUTH_TOKEN')) {
131
+ if (skipEnvRelayForArgs(args)) {
132
+ return {
133
+ args: [...args],
134
+ scrubSensitiveEnv: true
135
+ };
136
+ }
137
+
138
+ return {
139
+ args: ['--agent-auth-token-stdin', ...args],
140
+ stdin: withTrailingNewline(validateSecret(env.WLFI_AGENT_AUTH_TOKEN ?? '', 'agentAuthToken')),
141
+ scrubSensitiveEnv: true
142
+ };
143
+ }
144
+
145
+ return {
146
+ args: [...args],
147
+ scrubSensitiveEnv: true
148
+ };
149
+ }
@@ -0,0 +1 @@
1
+ export * from './agent-auth-migrate.ts';
@@ -0,0 +1,150 @@
1
+ import {
2
+ deleteConfigKey,
3
+ readConfig,
4
+ redactConfig,
5
+ writeConfig,
6
+ type WlfiConfig
7
+ } from '../../packages/config/src/index.js';
8
+ import {
9
+ AGENT_AUTH_TOKEN_KEYCHAIN_SERVICE,
10
+ assertValidAgentKeyId,
11
+ readAgentAuthTokenFromKeychain,
12
+ storeAgentAuthTokenInKeychain
13
+ } from './keychain.js';
14
+
15
+ export interface MigrateLegacyAgentAuthInput {
16
+ agentKeyId?: string;
17
+ overwriteKeychain?: boolean;
18
+ }
19
+
20
+ export interface MigrateLegacyAgentAuthResult {
21
+ agentKeyId: string;
22
+ source: 'config';
23
+ keychain: {
24
+ service: string;
25
+ stored: boolean;
26
+ overwritten: boolean;
27
+ alreadyPresent: boolean;
28
+ matchedExisting: boolean;
29
+ };
30
+ config: Record<string, unknown>;
31
+ }
32
+
33
+ interface MigrateLegacyAgentAuthDeps {
34
+ platform?: NodeJS.Platform;
35
+ readConfig?: () => WlfiConfig;
36
+ writeConfig?: (nextConfig: WlfiConfig) => WlfiConfig;
37
+ deleteConfigKey?: (key: keyof WlfiConfig) => WlfiConfig;
38
+ readAgentAuthToken?: (agentKeyId: string) => string | null;
39
+ storeAgentAuthToken?: (agentKeyId: string, token: string) => void;
40
+ }
41
+
42
+ function presentSecret(value: string | undefined): string | null {
43
+ if (typeof value !== 'string') {
44
+ return null;
45
+ }
46
+
47
+ return value.trim().length > 0 ? value : null;
48
+ }
49
+
50
+ function resolveConfiguredAgentKeyId(
51
+ config: WlfiConfig,
52
+ explicitAgentKeyId: string | undefined
53
+ ): string | undefined {
54
+ const configuredAgentKeyId = config.agentKeyId?.trim();
55
+ if (!configuredAgentKeyId) {
56
+ return undefined;
57
+ }
58
+
59
+ try {
60
+ return assertValidAgentKeyId(configuredAgentKeyId);
61
+ } catch (error) {
62
+ if (explicitAgentKeyId) {
63
+ return undefined;
64
+ }
65
+ throw new Error(
66
+ (error instanceof Error ? error.message : String(error)) +
67
+ '; pass --agent-key-id to migrate the legacy config secret explicitly'
68
+ );
69
+ }
70
+ }
71
+
72
+ export function migrateLegacyAgentAuthToken(
73
+ input: MigrateLegacyAgentAuthInput = {},
74
+ deps: MigrateLegacyAgentAuthDeps = {}
75
+ ): MigrateLegacyAgentAuthResult {
76
+ const platform = deps.platform ?? process.platform;
77
+ if (platform !== 'darwin') {
78
+ throw new Error('legacy agent auth migration requires macOS Keychain');
79
+ }
80
+
81
+ const loadConfig = deps.readConfig ?? readConfig;
82
+ const persistConfig = deps.writeConfig ?? writeConfig;
83
+ const clearConfigKey = deps.deleteConfigKey ?? deleteConfigKey;
84
+ const readAgentAuthToken = deps.readAgentAuthToken ?? readAgentAuthTokenFromKeychain;
85
+ const storeAgentAuthToken = deps.storeAgentAuthToken ?? storeAgentAuthTokenInKeychain;
86
+
87
+ const explicitAgentKeyId = input.agentKeyId ? assertValidAgentKeyId(input.agentKeyId) : undefined;
88
+ const config = loadConfig();
89
+ const configuredAgentKeyId = resolveConfiguredAgentKeyId(config, explicitAgentKeyId);
90
+
91
+ if (explicitAgentKeyId && configuredAgentKeyId && explicitAgentKeyId !== configuredAgentKeyId) {
92
+ throw new Error(
93
+ 'explicit --agent-key-id does not match the configured agentKeyId; refuse to bind a legacy config secret to a different agent'
94
+ );
95
+ }
96
+
97
+ const agentKeyId = explicitAgentKeyId ?? configuredAgentKeyId;
98
+ if (!agentKeyId) {
99
+ throw new Error('agentKeyId is required; pass --agent-key-id or configure agentKeyId first');
100
+ }
101
+
102
+ const legacyToken = presentSecret(config.agentAuthToken);
103
+ if (!legacyToken) {
104
+ throw new Error('config.json does not contain a legacy agentAuthToken to migrate');
105
+ }
106
+
107
+ const existingKeychainToken = readAgentAuthToken(agentKeyId);
108
+ const alreadyPresent = existingKeychainToken !== null;
109
+ let matchedExisting = false;
110
+ let stored = false;
111
+ let overwritten = false;
112
+
113
+ if (existingKeychainToken === null) {
114
+ storeAgentAuthToken(agentKeyId, legacyToken);
115
+ stored = true;
116
+ } else if (existingKeychainToken === legacyToken) {
117
+ matchedExisting = true;
118
+ } else {
119
+ if (!input.overwriteKeychain) {
120
+ throw new Error(
121
+ 'macOS Keychain already contains a different agent auth token for this agentKeyId; rerun with --overwrite-keychain after verifying the correct credential'
122
+ );
123
+ }
124
+
125
+ storeAgentAuthToken(agentKeyId, legacyToken);
126
+ stored = true;
127
+ overwritten = true;
128
+ }
129
+
130
+ let updatedConfig = config;
131
+ if (configuredAgentKeyId !== agentKeyId) {
132
+ updatedConfig = persistConfig({ agentKeyId });
133
+ }
134
+ if (updatedConfig.agentAuthToken !== undefined) {
135
+ updatedConfig = clearConfigKey('agentAuthToken');
136
+ }
137
+
138
+ return {
139
+ agentKeyId,
140
+ source: 'config',
141
+ keychain: {
142
+ service: AGENT_AUTH_TOKEN_KEYCHAIN_SERVICE,
143
+ stored,
144
+ overwritten,
145
+ alreadyPresent,
146
+ matchedExisting
147
+ },
148
+ config: redactConfig(updatedConfig)
149
+ };
150
+ }
@@ -0,0 +1,103 @@
1
+ import {
2
+ deleteConfigKey,
3
+ redactConfig,
4
+ readConfig,
5
+ type WlfiConfig,
6
+ writeConfig
7
+ } from '../../packages/config/src/index.js';
8
+ import {
9
+ AGENT_AUTH_TOKEN_KEYCHAIN_SERVICE,
10
+ assertValidAgentKeyId,
11
+ deleteAgentAuthTokenFromKeychain
12
+ } from './keychain.js';
13
+
14
+ export interface RevokeAgentKeyAdminArgsInput {
15
+ agentKeyId: string;
16
+ vaultPassword?: string;
17
+ vaultPasswordStdin?: boolean;
18
+ nonInteractive?: boolean;
19
+ daemonSocket?: string;
20
+ }
21
+
22
+ export interface RevokeAgentKeyAdminOutput {
23
+ agent_key_id: string;
24
+ revoked: boolean;
25
+ }
26
+
27
+ export interface CompleteAgentKeyRevocationResult {
28
+ agentKeyId: string;
29
+ revoked: true;
30
+ keychain: {
31
+ removed: boolean;
32
+ service: string | null;
33
+ };
34
+ config: Record<string, unknown>;
35
+ }
36
+
37
+ interface CompleteAgentKeyRevocationDeps {
38
+ platform?: NodeJS.Platform;
39
+ deleteAgentAuthToken?: (agentKeyId: string) => boolean;
40
+ readConfig?: () => WlfiConfig;
41
+ writeConfig?: (nextConfig: WlfiConfig) => WlfiConfig;
42
+ deleteConfigKey?: (key: keyof WlfiConfig) => WlfiConfig;
43
+ }
44
+
45
+ export function buildRevokeAgentKeyAdminArgs(input: RevokeAgentKeyAdminArgsInput): string[] {
46
+ const args = ['--json', '--quiet'];
47
+
48
+ if (input.vaultPassword) {
49
+ throw new Error(
50
+ 'insecure vaultPassword is disabled; use vaultPasswordStdin or an interactive prompt'
51
+ );
52
+ }
53
+ if (input.vaultPasswordStdin) {
54
+ args.push('--vault-password-stdin');
55
+ }
56
+ if (input.nonInteractive) {
57
+ args.push('--non-interactive');
58
+ }
59
+ if (input.daemonSocket) {
60
+ args.push('--daemon-socket', input.daemonSocket);
61
+ }
62
+
63
+ args.push('revoke-agent-key', '--agent-key-id', assertValidAgentKeyId(input.agentKeyId));
64
+
65
+ return args;
66
+ }
67
+
68
+ export function completeAgentKeyRevocation(
69
+ output: RevokeAgentKeyAdminOutput,
70
+ deps: CompleteAgentKeyRevocationDeps = {}
71
+ ): CompleteAgentKeyRevocationResult {
72
+ const platform = deps.platform ?? process.platform;
73
+ const agentKeyId = assertValidAgentKeyId(output.agent_key_id);
74
+ if (!output.revoked) {
75
+ throw new Error('revoke-agent-key did not confirm revocation');
76
+ }
77
+
78
+ const removeAgentAuthToken = deps.deleteAgentAuthToken ?? deleteAgentAuthTokenFromKeychain;
79
+ const loadConfig = deps.readConfig ?? readConfig;
80
+ const persistConfig = deps.writeConfig ?? writeConfig;
81
+ const clearLegacyConfigKey = deps.deleteConfigKey ?? deleteConfigKey;
82
+
83
+ const existing = loadConfig();
84
+ const removed = removeAgentAuthToken(agentKeyId);
85
+
86
+ let updated = existing;
87
+ if (existing.agentKeyId === agentKeyId) {
88
+ updated = persistConfig({ agentKeyId: undefined });
89
+ if (updated.agentAuthToken !== undefined) {
90
+ updated = clearLegacyConfigKey('agentAuthToken');
91
+ }
92
+ }
93
+
94
+ return {
95
+ agentKeyId,
96
+ revoked: true,
97
+ keychain: {
98
+ removed,
99
+ service: platform === 'darwin' ? AGENT_AUTH_TOKEN_KEYCHAIN_SERVICE : null
100
+ },
101
+ config: redactConfig(updated)
102
+ };
103
+ }
@@ -0,0 +1,107 @@
1
+ import {
2
+ deleteConfigKey,
3
+ redactConfig,
4
+ readConfig,
5
+ type WlfiConfig,
6
+ writeConfig
7
+ } from '../../packages/config/src/index.js';
8
+ import {
9
+ AGENT_AUTH_TOKEN_KEYCHAIN_SERVICE,
10
+ assertValidAgentKeyId,
11
+ storeAgentAuthTokenInKeychain
12
+ } from './keychain.js';
13
+
14
+ export interface RotateAgentAuthTokenAdminArgsInput {
15
+ agentKeyId: string;
16
+ vaultPassword?: string;
17
+ vaultPasswordStdin?: boolean;
18
+ nonInteractive?: boolean;
19
+ daemonSocket?: string;
20
+ }
21
+
22
+ export interface RotateAgentAuthTokenAdminOutput {
23
+ agent_key_id: string;
24
+ agent_auth_token: string;
25
+ agent_auth_token_redacted: boolean;
26
+ }
27
+
28
+ export interface CompleteAgentAuthRotationResult {
29
+ agentKeyId: string;
30
+ keychain: {
31
+ stored: true;
32
+ service: string;
33
+ };
34
+ config: Record<string, unknown>;
35
+ }
36
+
37
+ interface CompleteAgentAuthRotationDeps {
38
+ storeAgentAuthToken?: (agentKeyId: string, token: string) => void;
39
+ readConfig?: () => WlfiConfig;
40
+ writeConfig?: (nextConfig: WlfiConfig) => WlfiConfig;
41
+ deleteConfigKey?: (key: keyof WlfiConfig) => WlfiConfig;
42
+ }
43
+
44
+ export function buildRotateAgentAuthTokenAdminArgs(
45
+ input: RotateAgentAuthTokenAdminArgsInput
46
+ ): string[] {
47
+ const args = ['--json', '--quiet'];
48
+
49
+ if (input.vaultPassword) {
50
+ throw new Error(
51
+ 'insecure vaultPassword is disabled; use vaultPasswordStdin or an interactive prompt'
52
+ );
53
+ }
54
+ if (input.vaultPasswordStdin) {
55
+ args.push('--vault-password-stdin');
56
+ }
57
+ if (input.nonInteractive) {
58
+ args.push('--non-interactive');
59
+ }
60
+ if (input.daemonSocket) {
61
+ args.push('--daemon-socket', input.daemonSocket);
62
+ }
63
+
64
+ args.push(
65
+ 'rotate-agent-auth-token',
66
+ '--agent-key-id',
67
+ assertValidAgentKeyId(input.agentKeyId),
68
+ '--print-agent-auth-token'
69
+ );
70
+
71
+ return args;
72
+ }
73
+
74
+ export function completeAgentAuthRotation(
75
+ output: RotateAgentAuthTokenAdminOutput,
76
+ deps: CompleteAgentAuthRotationDeps = {}
77
+ ): CompleteAgentAuthRotationResult {
78
+ const agentKeyId = assertValidAgentKeyId(output.agent_key_id);
79
+ if (output.agent_auth_token_redacted) {
80
+ throw new Error('rotate-agent-auth-token returned a redacted agent auth token');
81
+ }
82
+ if (!output.agent_auth_token?.trim()) {
83
+ throw new Error('rotate-agent-auth-token returned an empty agent auth token');
84
+ }
85
+
86
+ const storeAgentAuthToken = deps.storeAgentAuthToken ?? storeAgentAuthTokenInKeychain;
87
+ const loadConfig = deps.readConfig ?? readConfig;
88
+ const persistConfig = deps.writeConfig ?? writeConfig;
89
+ const clearLegacyConfigKey = deps.deleteConfigKey ?? deleteConfigKey;
90
+
91
+ loadConfig();
92
+ storeAgentAuthToken(agentKeyId, output.agent_auth_token);
93
+
94
+ let updated = persistConfig({ agentKeyId });
95
+ if (updated.agentAuthToken !== undefined) {
96
+ updated = clearLegacyConfigKey('agentAuthToken');
97
+ }
98
+
99
+ return {
100
+ agentKeyId,
101
+ keychain: {
102
+ stored: true,
103
+ service: AGENT_AUTH_TOKEN_KEYCHAIN_SERVICE
104
+ },
105
+ config: redactConfig(updated)
106
+ };
107
+ }
@@ -0,0 +1 @@
1
+ export * from './agent-auth-token.ts';
@@ -0,0 +1,25 @@
1
+ export const MAX_AGENT_AUTH_TOKEN_BYTES = 16 * 1024;
2
+
3
+ export function assertValidAgentAuthToken(token: string, label = 'agentAuthToken'): string {
4
+ if (Buffer.byteLength(token, 'utf8') > MAX_AGENT_AUTH_TOKEN_BYTES) {
5
+ throw new Error(`${label} must not exceed ${MAX_AGENT_AUTH_TOKEN_BYTES} bytes`);
6
+ }
7
+
8
+ const normalized = token.replace(/[\r\n]+$/u, '');
9
+ if (!normalized.trim()) {
10
+ throw new Error(`${label} is required`);
11
+ }
12
+
13
+ return normalized;
14
+ }
15
+
16
+ export function resolveOptionalAgentAuthToken(
17
+ token: string | null | undefined,
18
+ label = 'agentAuthToken'
19
+ ): string | null {
20
+ if (token === null || token === undefined) {
21
+ return null;
22
+ }
23
+
24
+ return assertValidAgentAuthToken(token, label);
25
+ }
@@ -0,0 +1,89 @@
1
+ import { resolveOptionalAgentAuthToken } from './agent-auth-token.js';
2
+
3
+ export type AgentAuthTokenSource = 'stdin' | 'argv' | 'keychain' | 'config' | 'env';
4
+
5
+ export interface ResolveAgentAuthTokenInput {
6
+ agentKeyId?: string;
7
+ cliToken?: string;
8
+ cliTokenStdin?: boolean;
9
+ keychainToken?: string | null;
10
+ configToken?: string;
11
+ envToken?: string;
12
+ allowLegacySource?: boolean;
13
+ readFromStdin: (label: string) => Promise<string>;
14
+ }
15
+
16
+ export interface ResolvedAgentAuthToken {
17
+ token: string;
18
+ source: AgentAuthTokenSource;
19
+ }
20
+
21
+ function migrationHint(agentKeyId?: string): string {
22
+ const keyPart = agentKeyId ? agentKeyId : '<uuid>';
23
+ return (
24
+ 'migrate it with `wlfi-agent config agent-auth set --agent-key-id ' +
25
+ keyPart +
26
+ ' --agent-auth-token-stdin`'
27
+ );
28
+ }
29
+
30
+ export async function resolveAgentAuthToken(
31
+ input: ResolveAgentAuthTokenInput,
32
+ ): Promise<ResolvedAgentAuthToken> {
33
+ if (input.cliToken && input.cliTokenStdin) {
34
+ throw new Error('--agent-auth-token conflicts with --agent-auth-token-stdin');
35
+ }
36
+
37
+ if (input.cliTokenStdin) {
38
+ return {
39
+ token: resolveOptionalAgentAuthToken(
40
+ await input.readFromStdin('agentAuthToken'),
41
+ 'agentAuthToken',
42
+ ) as string,
43
+ source: 'stdin',
44
+ };
45
+ }
46
+
47
+ const cliToken = resolveOptionalAgentAuthToken(input.cliToken, 'agentAuthToken');
48
+ if (cliToken) {
49
+ if (!input.allowLegacySource) {
50
+ throw new Error(
51
+ '--agent-auth-token is disabled by default for security; use macOS Keychain or --agent-auth-token-stdin, ' +
52
+ migrationHint(input.agentKeyId) +
53
+ ', or pass --allow-legacy-agent-auth-source',
54
+ );
55
+ }
56
+ return { token: cliToken, source: 'argv' };
57
+ }
58
+
59
+ const keychainToken = resolveOptionalAgentAuthToken(input.keychainToken, 'agentAuthToken');
60
+ if (keychainToken) {
61
+ return { token: keychainToken, source: 'keychain' };
62
+ }
63
+
64
+ const configToken = resolveOptionalAgentAuthToken(input.configToken, 'agentAuthToken');
65
+ if (configToken) {
66
+ if (!input.allowLegacySource) {
67
+ throw new Error(
68
+ 'agentAuthToken from config.json is disabled by default for security; use macOS Keychain or --agent-auth-token-stdin, ' +
69
+ migrationHint(input.agentKeyId) +
70
+ ', or pass --allow-legacy-agent-auth-source',
71
+ );
72
+ }
73
+ return { token: configToken, source: 'config' };
74
+ }
75
+
76
+ const envToken = resolveOptionalAgentAuthToken(input.envToken, 'agentAuthToken');
77
+ if (envToken) {
78
+ if (!input.allowLegacySource) {
79
+ throw new Error(
80
+ 'WLFI_AGENT_AUTH_TOKEN is disabled by default for security; use macOS Keychain or --agent-auth-token-stdin, ' +
81
+ migrationHint(input.agentKeyId) +
82
+ ', or pass --allow-legacy-agent-auth-source',
83
+ );
84
+ }
85
+ return { token: envToken, source: 'env' };
86
+ }
87
+
88
+ throw new Error('agentAuthToken is required; use macOS Keychain or --agent-auth-token-stdin');
89
+ }
@@ -0,0 +1 @@
1
+ export * from './asset-broadcast.ts';