CLI for LLM agent secret safety. nopeek loads environment secrets for coding agents without exposing secret values in tool output or chat context. Agents see key names, not key values.
In an LLM coding session, tell the agent to use nopeek:
"run npx nopeek load .env then use $DATABASE_URL to query the users table"
"use npx nopeek load .env --only STRIPE_KEY and then curl the billing API"
"run npx nopeek load .env --only API_KEY,API_SECRET and test the auth endpoint"
The agent runs the command, gets back only the key name, and uses the variable in subsequent commands without seeing the actual value.
Shell command output visible to an LLM coding agent may be sent to a model provider and retained by that provider. nopeek prevents secrets from appearing in that output.
Step 1. Tell your agent to use nopeek. It just needs to run the command; it will self-discover subcommands and flags from the CLI output:
npx nopeek load .env --only DATABASE_URLStep 2. nopeek injects the value into the session environment and prints only the key name:
Loaded 1 key from .env: DATABASE_URL
Step 3. The agent can now use the variable by name without ever seeing the value:
psql $DATABASE_URL -c "SELECT count(*) FROM users"Important: Your agent does not know about nopeek unless you mention it. You do not need to spell out the full command, just mention
{npx,pnpx,bunx} nopeekand the agent can discover the rest.
If you use a harness with persistent system-prompt extensions, add a
small reminder so the model reaches for nopeek automatically instead
of needing the Quick Start text in every prompt. For Pi users, the
@spences10/pi-nopeek extension does this:
pi install npm:@spences10/pi-nopeekmy-pi already includes this
reminder by default. This is optional: nopeek remains harness-agnostic
and still works anywhere when you mention it in the session.
Three modes depending on environment:
| Context | What happens |
|---|---|
| Agent session with env-file injection support | Writes directly to env file, most secure |
| Agent session without env-file injection | Writes to temp file, outputs source command |
| Regular shell | Prints export statements for eval |
No install needed. Your agent runs it directly via npx:
npx nopeek load .env
npx nopeek load .env --only DATABASE_URL
npx nopeek set MY_API_KEY --from-env
npx nopeek statusAll commands are designed to be run inside an LLM coding session. Just
mention nopeek in your prompt. The agent will discover the right
subcommand from the CLI output.
npx nopeek load .env
npx nopeek load .env --only DATABASE_URL,API_KEY
npx nopeek load .env --persist # also save to config for future sessions
npx nopeek load terraform.tfvars --only prod_password
npx nopeek load production.tfvars.json --only db_passwordSupported formats:
| Extension | Format |
|---|---|
.env, .env.* |
KEY=value |
.tfvars |
key = "value" (HCL strings) |
.tfvars.json |
JSON top-level strings |
For .tfvars files, only top-level quoted string values are loaded.
Maps, lists, numbers, and booleans are skipped.
The --persist flag saves keys to ~/.config/nopeek/config.json so a
SessionStart hook can auto-inject them on future sessions.
npx nopeek set MY_API_KEY --from-env # read from current shell env
npx nopeek set MY_API_KEY # interactive prompt (TTY only)Stores to ~/.config/nopeek/config.json with 0600 permissions. This
is plaintext at rest; use set/--persist only for secrets you are
comfortable storing in your user config.
Note:
--valueis rejected inside detected LLM agent sessions. The value would appear in the conversation. Use--from-envinstead.
npx nopeek listShows key names and sources without values.
npx nopeek remove MY_API_KEYnpx nopeek initDetects installed cloud CLIs, checks their auth configuration, and stores profile mappings.
| CLI | Safer pattern | Detection |
|---|---|---|
aws |
Named profiles (AWS_PROFILE) |
~/.aws/credentials + env vars |
hcloud |
Named contexts (HCLOUD_CONTEXT) |
~/.config/hcloud/cli.toml |
gcloud |
Named configurations (CLOUDSDK_ACTIVE_CONFIG_NAME) |
active gcloud account + inline credential env vars |
az |
Azure CLI cached login + active subscription | az account show + inline credential env vars |
npx nopeek statusShows session type, stored keys, CLI profiles, and detected CLIs.
npx nopeek audit
npx nopeek audit ./path/to/dirScans for .env files and reports secrets found using pattern
matching (AWS keys, bearer tokens, API keys, private keys, connection
strings, etc.). Checks .gitignore coverage.
- Key name validation - env key names are validated against
^[a-zA-Z_][a-zA-Z0-9_]*$to prevent shell injection - Secure file permissions - config dir is
0700, config file is0600, temp env files are0600 - Atomic writes - config is written via temp file + rename to prevent corruption
- Key validation before output - invalid env names are rejected before shell exports are printed
- No values in stdout - in detected agent sessions, values are
written to env files or temp files; only
sourcepaths or key names reach stdout - Plaintext config warning - persisted keys are local plaintext secrets protected by file permissions, not encryption
nopeek is the primary defense, but deny rules are a useful safety net in any agent runtime that supports them. Block the agent from reading secret files or embedding credentials inline in commands:
Without these rules, an agent can still read a .tfvars or .env
file directly and hardcode the values into a shell command. nopeek
prevents secrets from appearing in output, but deny rules prevent
the agent from reading the files in the first place.
- Pattern-based secret detection is best-effort. The audit patterns catch known formats but cannot catch every possible secret.
- Agent detection is marker-based. nopeek detects common agent environment markers and env-file injection, but no CLI can guarantee every harness is identified.
- Temp files exist on disk briefly. Written to
/tmp/nopeek/with0600perms, but values are on disk until the file is cleaned up. - Persisted keys are plaintext.
setandload --persiststore values in~/.config/nopeek/config.jsonwith0600permissions. - Output redaction is not comprehensive. Prefer loading secrets as environment variables so values never need to be printed.
MIT
{ "permissions": { "deny": [ // Block reading secret files "Read(.env)", "Read(*.env)", "Read(*.tfvars)", "Read(*credentials*)", "Read(*secret*)", "Read(**/.config/gcloud/**)", "Read(**/.azure/**)", "Read(*service-account*.json)", // Block cat/head on secret files "Bash(cat .env)", "Bash(cat *.env*)", "Bash(cat *tfvars*)", "Bash(cat *credentials*)", "Bash(cat *secret*)", // Block inline credentials in commands "Bash(PGPASSWORD*)", "Bash(*HCLOUD_TOKEN*)", "Bash(hcloud context create*)", "Bash(*GOOGLE_APPLICATION_CREDENTIALS*)", "Bash(*CLOUDSDK_AUTH_ACCESS_TOKEN*)", "Bash(*GOOGLE_OAUTH_ACCESS_TOKEN*)", "Bash(*AZURE_CLIENT_SECRET*)", "Bash(*ARM_CLIENT_SECRET*)", "Bash(*AZURE_PASSWORD*)", "Bash(*AZURE_ACCESS_TOKEN*)", "Bash(*ARM_ACCESS_KEY*)", // Block fetching secret values from cloud providers "Bash(*secretsmanager get-secret-value*)", "Bash(*hetzner*secret*)", "Bash(*hetzner*access_key*)", "Bash(gcloud auth print-access-token*)", "Bash(gcloud auth application-default print-access-token*)", "Bash(az account get-access-token*)", ], }, }