scrt4 — secret manager for coding agents

Key principle

Claude Code can use your secrets without ever seeing them. The AI writes commands with $env[NAME] placeholders; the real values are substituted at runtime inside an isolated subprocess and scrubbed from stdout before anything returns to the model.

scrt4 is a single daemon + CLI that holds your .env values in a hardware-bound encrypted vault. The master key is derived from your FIDO2 authenticator (YubiKey, passkey, phone, Touch ID, Windows Hello) via the WebAuthn PRF extension — no passwords, no TOTP. The key is re-derived every session and never leaves the device.

Runs the same way on macOS, Linux, and WSL. AGPL-3.0. Under 10 MB end-to-end.

claude-code
✓ Claude sees: scrt4 run 'curl -H "Authorization: Bearer $env[API_KEY]" api.example.com' ✗ Claude sees NOT: the actual bearer token

Install

One command. Auto-detects OS and architecture, pulls SHA256-verified binaries from GitHub Releases, and installs a systemd user unit (Linux) or launchd plist (macOS). No Docker required.

install
$ curl -fsSL https://install.llmsecrets.com/native | sh
Don't pipe to sh blindly?

Full per-OS instructions, checksums, and a two-hosts-one-hash verify step live at llmsecrets.com/downloads. The same scrt4-native.sh.sha256 is served from install.llmsecrets.com/native.sha256 and committed to the public repo on main. Both must match.

Supported authenticators

AuthenticatorStatus
YubiKey 5 series (firmware 5.2.3+)✅ Supported
YubiKey 4 / NEO❌ Does not support hmac-secret
Trezor Safe 3 / Safe 5 / Model T (recent firmware)✅ Supported
OnlyKey✅ Supported
Phone passkeys via caBLE (iPhone, Android)✅ Supported
Apple passkeys, Bitwarden, 1Password, Google Password Manager✅ Any PRF-capable software authenticator
Touch ID / Windows Hello✅ Supported

First unlock

1

scrt4 setup

One-time FIDO2 enrollment. Registers a WebAuthn passkey tied to your hardware authenticator. This is the hardware root of trust — don't skip it.

2

scrt4 unlock

Opens a session. Default TTL is 20 hours; pass a different value like scrt4 unlock 3600 for a one-hour window. Every command below requires an active session.

3

scrt4 status

Confirms the session is live. Shows time remaining, vault location, and loaded modules.

Back it up before you add anything

Losing the hardware authenticator without a backup = losing the vault. Jump to Encrypted Drive backup or Recovery before you store anything important.

Your first secret

Two ways to add secrets: type them one by one, or import an existing .env file.

add one at a time
$ scrt4 add STRIPE_SECRET_KEY=sk_live_... ✓ added STRIPE_SECRET_KEY $ scrt4 list STRIPE_SECRET_KEY

scrt4 list only ever shows secret names. Values are never printed on stdout — the only way to see a value is scrt4 view, which opens a GUI dialog so values render in the OS window system where a CLI agent cannot read them.

Using with Claude Code

Write commands with $env[NAME] placeholders. scrt4 substitutes the real values at runtime inside the subprocess environment. The substituted text is never returned to the model.

Syntax matters

The placeholder is literally $env[NAME]. Not $NAME, not ${NAME}. Only $env[NAME] triggers injection.

Example: deploy a smart contract

forge deploy
$ scrt4 run 'forge script Deploy.s.sol \ --rpc-url $env[ALCHEMY_RPC_URL] \ --private-key $env[PRIVATE_KEY] \ --broadcast'

Example: call an API

curl
$ scrt4 run 'curl -H "Authorization: Bearer $env[API_KEY]" https://api.example.com'

Example: push to GitHub

git push
$ scrt4 run 'git push https://$env[GITHUB_PAT]@github.com/user/repo.git'

Discovering what's available

scrt4 llm emits an llms.txt-style dump of every secret name in the vault, every loaded module with its capabilities, current session status, and recommended next steps. Prefer this over stale docs — it reflects the live vault.

scrt4 llm
$ scrt4 llm # scrt4 capability map secrets: GITHUB_PAT, STRIPE_SECRET_KEY, ALCHEMY_RPC_URL, ... modules: cloud-crypt, encrypt-folder, import-env session: unlocked (18h 42m remaining) ...

Importing existing .env files

If you already have project .env files on disk, their secrets belong in scrt4, not in plaintext. The import module parses export KEY=value forms, surrounding quotes, and # comments.

import
$ scrt4 import path/to/.env ✓ imported 7 secrets from path/to/.env

After import, delete the plaintext file — some tooling still reads .env directly, so confirm your app uses the new injection flow before removing it. A Claude Code session with scrt4 unlocked can help find .env files under your project directories with find ~/projects -name '.env' 2>/dev/null and walk through them one at a time.

Encrypted Google Drive backup (cloud-crypt)

Why this matters

No authenticator + no backup = no recovery, by design. There is no server-side reset because there is no server-side anything. The recommended backup path is client-side encrypted upload to your own Google Drive: AES-256-GCM runs locally before upload, so Drive only ever receives .scrt4 ciphertext. Google cannot decrypt it.

The cloud-crypt module ships with the native installer by default. Setup has three steps: Drive-scoped OAuth, save the master key, push the vault.

1. Give cloud-crypt Drive access

Three setup paths — pick whichever matches what you already have:

scrt4 cloud-crypt auth setup --from-gws Runs the Google Workspace CLI (gws) consent flow. Easiest if you don't already have an OAuth blob.
scrt4 cloud-crypt auth setup --from-secret personal_google_workspace Reuses an OAuth blob already in the vault. Nothing is copied — cloud-crypt reads it through the daemon.
scrt4 cloud-crypt auth setup --paste Interactive paste of an existing OAuth blob. For users who manage their own Google OAuth.
verify
$ scrt4 cloud-crypt auth status active source: vault secret SCRT4_GDRIVE_OAUTH scope: drive.file (cloud-crypt can only touch files it creates)

2. Save your master key somewhere durable

The Drive ciphertext is useless without the master key. Save it password-protected to a USB stick, a password manager, or both.

backup-key
$ scrt4 backup-key --save /media/usb ✓ wrote /media/usb/scrt4-backup-YYYY-MM-DD.enc (password-protected; store this file, not the raw key)
Don't leave it on the desktop

Move the exported backup file to a location you actually trust — a hardware key, a USB stick, or your password manager's attachment slot. Desktop = convenient for you = convenient for anything else that can read your disk.

3. Push the encrypted vault to Drive

encrypt-and-push
$ scrt4 cloud-crypt encrypt-and-push ~/.scrt4/vault.enc encrypting locally with AES-256-GCM... uploading to Drive folder 'claude-crypt'... ✓ pushed vault.enc.scrt4 (driveId: 1AbC...) $ scrt4 cloud-crypt list vault.enc.scrt4 2.4 KB 1AbC...

Everything encrypted by cloud-crypt lives in a single Drive folder named claude-crypt, auto-created on first push. You can rename or move the folder later — the module tracks archives by ID, not path. Filenames and sizes are not encrypted.

4. Restore on a new machine

  1. Install scrt4 on the new machine (curl -fsSL https://install.llmsecrets.com/native | sh).
  2. Run scrt4 setup to enroll a new authenticator.
  3. Unlock, then run scrt4 recover /path/to/backup-file.enc — this restores the original master key from the password-protected export you saved in step 2.
  4. Authenticate cloud-crypt (scrt4 cloud-crypt auth setup ...) and scrt4 cloud-crypt pull-and-decrypt <driveId> to pull the encrypted vault back down and decrypt it.
cloud-crypt command reference

list, where, status, push, pull, encrypt-and-push, pull-and-decrypt, auth setup/status/guide, ui — run scrt4 cloud-crypt help for the full surface area. Every read command supports --json for script consumption.

Encrypt a folder

The encrypt-folder module produces a standalone .scrt4 archive using the same vault key. Useful for backing up source trees, ops notebooks, or anything else you'd rather not leave in plaintext.

encrypt-folder
$ scrt4 encrypt-folder ~/notes ✓ wrote ~/notes.scrt4 $ scrt4 decrypt-folder ~/notes.scrt4 ✓ restored ~/notes

Pair with cloud-crypt push ~/notes.scrt4 to ship the archive to Drive without a second round of encryption — the archive is already ciphertext.

Recovery

Three recovery paths, in order of preference:

PathWhat you needWhat it restores
Drive backup Password-protected master-key file + Drive access Full vault
Local backup Copy of ~/.scrt4/vault.enc + master key Full vault
Emergency key Raw base64 master key (scrt4 recover-key) Full vault — bypasses FIDO2, use only if hardware is gone
No server, no reset

scrt4 has no server-side state — no account, no password reset, no customer-success ticket that can rescue a lost vault. If both the authenticator and the backup are gone, the vault is permanently unrecoverable. This is the security model, not a bug.

How the key works

Your vault key is derived from the FIDO2 authenticator via the WebAuthn PRF extension — CTAP2's hmac-secret under the hood. Each scrt4 unlock triggers a tap/touch/biometric check on the authenticator, which returns a device-bound HMAC. scrt4 uses that HMAC as input to the vault KDF. The key is re-derived every session and never leaves the device.

This is why scrt4 doesn't need a password, doesn't need TOTP, and doesn't need cloud state: the hardware authenticator IS the key. Steal the vault file alone and you have nothing; steal the authenticator alone and you have nothing. You need both.

Vault encryption

Daemon & TCB split

scrt4 is split into a small trusted computing base (TCB) and a larger set of modules:

See ARCHITECTURE.md for the full module/TCB split and SECURITY.md for the threat model.

What the AI sees (and doesn't)

Claude CAN seeClaude CANNOT see
Secret names (GITHUB_PAT, STRIPE_SECRET_KEY, ...)Secret values — ever
Command structure and exit codesPrivate keys, passwords, tokens
stdout from scrt4 run (with stored values redacted)The master key
Session status, vault metadata, loaded modulesAnything shown in scrt4 view (GUI-only)

Commands reference

scrt4 setupOne-time FIDO2 enrollment
scrt4 unlock [ttl]Start a session (default 20 h)
scrt4 statusSession info, TTL remaining
scrt4 extend [ttl]Reset the session timer
scrt4 logoutLock the session
scrt4 list [--tags]List secret names
scrt4 add K=vAdd secrets
scrt4 import FILEImport an existing .env
scrt4 view [--cli]View/edit in GUI (or terminal)
scrt4 run 'cmd $env[K]'Run with secret injection
scrt4 rotateRotate the vault master key
scrt4 backup-vaultTar the vault directory
scrt4 backup-key --save DIRExport password-protected master key
scrt4 recover FILERestore from an encrypted backup
scrt4 recover-key KEYEmergency restore from raw key
scrt4 share [--all] [NAME...]Share secrets via Magic Wormhole
scrt4 receive [--code CODE]Receive shared secrets
scrt4 verify-selfCheck binary against published SHA256SUMS
scrt4 llm [--json]Emit capability dump for AI agents
scrt4 helpFull command reference

Run scrt4 help locally for the canonical list — this page drifts, the binary doesn't.

Modules

Modules extend scrt4 without expanding the trusted computing base. The native installer ships three by default; the rest are explicit opt-in via --module NAME.

ModuleDefault?What it does
cloud-cryptClient-side encrypted Google Drive backup. AES-256-GCM runs locally before upload.
encrypt-folderEncrypt any directory to a standalone .scrt4 archive using the vault key.
import-envParse an existing .env (including export K=v, quoted values, # comments) into the vault.
github, gcp, stripe, dns, ...Opt-inWhitelisted in modules-whitelist.json and SHA256-verified at install time.

Run scrt4 modules list to see what's loaded in your install.

Trust & verification

AI-assisted audit

Don't want to read 2,000 lines of Rust yourself? DeepWiki indexes the public repo and answers questions like "Does the daemon ever write secret values to disk?" or "How is the master key derived?" against the actual source.

Uninstall

uninstall
$ curl -fsSL https://install.llmsecrets.com/uninstall | sh

Removes the daemon, CLI, and session data. The encrypted vault at ~/.scrt4/ stays on disk until you delete it — that's deliberate, so a reinstall can pick up where the old one left off.

Troubleshooting

"Secret not found"

The name may differ from what the command expects. Run scrt4 list to see exactly what's stored.

"Session locked"

Run scrt4 unlock. Check scrt4 status for TTL. Sessions can be extended with scrt4 extend.

"hmac-secret not supported"

Your authenticator doesn't support the WebAuthn PRF extension. YubiKey 4 and NEO are the common culprits — YubiKey 5 firmware 5.2.3+ is required. Check firmware with ykman info.

cloud-crypt: gcloud not found

cloud-crypt uses the Google Cloud SDK to mint OAuth tokens. Install it from cloud.google.com/sdk or use auth setup --from-secret / --paste to bring your own OAuth blob.

Need a new secret?

scrt4 add NAME=value or scrt4 import FILE. Both work mid-session.

Still stuck?

File an issue at llmsecrets/llm-secrets, or email security@llmsecrets.com for anything sensitive.

Looking for the pre-scrt4 docs?

The Windows-Hello CLI, Electron desktop app, and WSL2 alpha guides live on the archive page. New installs should use scrt4.