.env and on the service — but they fit different moments.
Option 1 — capy edit (interactive TUI)
capy edit opens a single-column TUI for the current project and branch, with a detail inspector that opens inline beneath the selected row:
- Inspect with
Enter(orSpace) — opens a detail panel inline, under the selected row, showing the key, its status, when the value last changed, and the value.Esccloses it. - Reveal with
r— values display asabc...xyzsnippets by default; pressingropens the inspector with the selected row’s full value revealed (pressragain to hide). Pan a long value with←/→. - Edit with
e— type the new value,Enterto buffer,Escto cancel. - Commit with
c— encrypts, updateskeep.lock, pushes to the service, and writes back to.envin one step. - Quit with
q— if you have uncommitted edits, you’ll be prompted to commit & push, discard, or keep working.
- See what’s currently set without opening your editor.
- Rotate one value with no risk of pasting plaintext into the wrong line.
- Avoid running a separate
capystep to encrypt and push.
capy edit reference page.
Option 2 — Edit .env directly
You can also just open .env in your editor, replace any capy:… snippet (or add a new line) with plaintext, save, and run capy:
capy picks up that DATABASE_URL and NEW_FLAG are now plaintext, encrypts them with the project key, updates keep.lock, and rewrites the file with capy:… snippets again. Plaintext values disappear from .env automatically on the next sync — they don’t linger on disk.
Reach for this when you want to:
- Add a brand-new variable.
- Rotate several values at once alongside code changes.
- Stay in the editor you already have open.
capy opens the conflict resolver so you can pick a side. See Syncing secrets.
Which one should I use?
There’s no wrong answer — they encrypt the same way and land at the same place. A rough split:What ends up on disk
In both flows:.envalways carriescapy:{resourceId}:…values after the operation completes — never the full plaintext. Capy splices a short cosmetic preview of the value (a few leading and trailing characters) around the ciphertext so the lines stay recognizable.keep.lockadvances to a new pinned hash for the branch, and Capy commits the rewrittenkeep.lockto git for you (chore(capy): pin <branch> secrets) unless you setCAPY_NO_AUTOCOMMIT=1.- The service receives the new ciphertext and the updated
keep.lock. On a local-only profile there is no service, so the local writes are the commit. - Capy caches the encrypted blob in its global directory, so later
capy,capy status, andcapy editruns can diff without refetching from the service.
capy run doesn’t use that cache — it decrypts the values in .env directly, and on a cloud or BYOC profile it resolves the project key through the service on every run.
What’s next
capy edit (CLI reference)
Every key the TUI listens to.
Syncing secrets
The conflict resolver and three-way diff.