What fidelius Protects Against.
In normal use your keys aren't in files or shell history, and when Claude Code or Codex runs a command through accio, a key that gets printed by accident is masked on a best-effort basis. It isn't a sandbox: anything running as you can still ask for a key.
What it protects against
Keys sitting in plain-text files
A .env in every project, exports in ~/.zshrc, a keys file in your home folder. Any agent, script, backup tool or git add . can pick those up. With fidelius the keys are in your Keychain, and accio myproject npm run dev hands them to that command as environment variables. Key files such as .p8 and .pem arrive as a path to a temporary file that is deleted when the command ends. You can still export a .env when a tool insists on one; fidelius asks for Touch ID first.
An agent opening your keys by accident
When you choose Setup > Add to My Agents Automatically, fidelius adds a short section to the global instructions of Claude Code, Codex, and Gemini CLI and Antigravity, and shows you the change first. It tells the agent to run commands through accio, to list key names with accio list, and not to print values or search files for them. An agent that follows it has no reason to open a key.
Your own program printing a key while an agent debugs it
This is the leak we could reproduce. In a small pilot on October 7, we gave Claude Code (Sonnet 5.5) and Codex (GPT-6 Sol) small apps whose own output contains their fake keys: a crash log that prints the config, a request URL with the key in it, a setup script that prints the environment. Three tasks, each run without rules and again with instructions not to print keys in AGENTS.md and CLAUDE.md (plus a Read deny rule and ignore files for Claude Code), with approvals off, in Docker. In 11 of 12 runs the keys ended up in the agent's context and its saved transcript. Neither agent repeated a key in its answer. In an earlier round, where the keys sat only in a .env, no full key reached a transcript: without rules, both agents opened the file but redacted the values themselves.
What masking does
When Claude Code or Codex runs a command through accio and the output goes to a pipe or a file (how agents read it), a key in the output is replaced with <concealed by fidelius: NAME> before the agent reads it, and accio says it did. We ran the three programs from the pilot through accio with their fake keys, once with Claude Code's marker (CLAUDECODE=1) and once with Codex's, and each fake key in their output came out concealed. It also catches the value itself in base64, hex, URL and JSON escaping. We've confirmed agent detection with Claude Code and codex exec. Other agents can set FIDELIUS_MASK=1. What agents see
Losing a key
Deleted keys go to Recently Deleted until you remove them. Backups, when you turn them on, are encrypted with a key derived from a password only you know. Before fidelius changes one of your files, such as an agent's instructions file, it shows you the change, and you can undo it later.
What it doesn't protect against
An agent that decides to get a value
Running a command with accio doesn't ask for Touch ID. Touch ID (or your Mac password) guards Reveal, Copy and Export .env in the app, but any program running as you can run accio, agents included. An agent that ignores its instructions can pass --no-mask, unset the marker that tells accio an agent is running, run accio under a pseudo-terminal, write a value to a file and read it back, or send it over the network from inside the command without printing it. Treat accio access like shell access to your keys. What stops a rogue command is your agent's own permission settings: keep approval on for commands that pass --no-mask, print the environment or send data out.
What masking misses
- Values shorter than 6 bytes (3 if you turn on Hide in agent output for that key), and keys with Hide in agent output turned off.
- A value that was changed on the way: reversed, split, compressed, encrypted, or part of a larger encoded string, such as an HTTP Basic auth header.
- A key your program writes to a log or a file, which the agent reads later without accio.
- Binary output (detected by a heuristic), and the output of MCP servers.
- Output that goes straight to your terminal, unless you set FIDELIUS_MASK=1.
Masking catches accidents, like a test printing a key. It is a second line, behind the instructions.
Everything the command starts
accio myproject cmd gives every key in that project to the command and to everything it starts: npm scripts, dependencies, child processes, an error tracker that records the environment. Split keys into separate projects when a command doesn't need all of them.
Other programs running as you
Other apps can't read fidelius's Keychain items directly: macOS limits them to apps from the same developer. But any program running as you can run accio and get a project's keys in its environment. Keys are readable once your Mac has been unlocked after a restart, so accio keeps working while the screen is locked.
Things it isn't for
- Production and CI secrets. fidelius is for the keys on your own Macs.
- Sharing keys with a team. There is no team sharing.
- A forgotten backup password. Nobody can open the backups without it, including us. Your live keys in the Keychain are not affected.
- Backups in iCloud Drive are encrypted by fidelius, but iCloud Drive itself is end-to-end encrypted only with Advanced Data Protection, and the file names show the date and the Mac.
Where your keys go
- Into your iCloud Keychain, in an access group only fidelius can use. Apple says iCloud Keychain is end-to-end encrypted. With iCloud Keychain off, they stay on this Mac.
- fidelius has no server and no account. We never receive your keys.
- The app goes online for two things: the license check with Polar, only if you buy Pro, and Sparkle's update check. The app has no analytics or crash reporting. (This website counts page views without cookies; see Privacy.)
Compared with other ways
| Where the key sits | Your program prints a key while an agent runs it | An agent that tries to get a value | |
|---|---|---|---|
| .env file | Plain-text file | The agent sees it | Reads the file |
| .env plus instructions, deny rules and ignore files | Plain-text file | The agent sees it (in our pilot, 5 of 6 runs) | Reads it through the shell, unless the shell is sandboxed |
| 1Password op run | 1Password vault | Masked by default | Can run op with --no-masking, after you authorize the session (Touch ID, Apple Watch or your password) if it isn't already authorized |
| dotenvx | Encrypted file, key in your keychain by default | Masked with --redact or an Envfile setting | Gets it once a decrypt is allowed; Armor can require approval for each one |
| fidelius | Your Keychain | Masked when Claude Code or Codex runs accio, best effort | Can run accio with --no-mask, with no prompt |
If you already pay for 1Password, op run is a good answer, and its session approval is something fidelius doesn't have. fidelius is $24 once with no account, keeps keys in iCloud Keychain, and sets up Claude Code, Codex and Gemini CLI for you.
Found a problem?
Please don't open a public issue. Use private vulnerability reporting on GitHub, or write to maria@blisslabs.dev.