The problem · secrets in source
A repository is a permanent, replicated, plaintext archive.
Deleting the file does not remove the secret. Rewriting history does not recall the copies. In Git, the ability to clone is the ability to read everything that was ever committed — and rotating the credential is the only remedy that actually finishes.
This page is about the structural problem, not a product tour. If you are mid-incident: rotate first, then read the rest.
Anatomy
Five steps, and only the last one works.
- 01
It gets committed
A config file, a fixture, a debug script. Client-side hooks refuse the patterns someone already described; a credential in a shape nobody has written a rule for goes straight through.
- 02
It gets pushed
The object is now on a server you do not solely control. Content-addressed storage is immutable by design — the history referencing it can be rewritten, but the object was already served.
- 03
It gets cloned
Read access in Git is all-or-nothing. Anyone who can clone can read every byte of every file in every revision, including files deleted years ago, and that read leaves no record.
- 04
It gets replicated
Forks, mirrors, CI caches, backup snapshots, container layers, and each developer's reflog hold independent copies. Nobody maintains that list, so nobody can finish cleaning it.
- 05
You rotate under pressure
Because the copies cannot be recalled, the only complete remedy is to invalidate the credential itself, in every system that trusts it, while production depends on it.
Where each control stops
Every one of these is worth having. None of them moves the read boundary.
The controls teams reach for are prevention and cleanup. They act on the commit, not on who can read the object afterwards.
| Control | What it does | Where it stops |
|---|---|---|
| .gitignore | Keeps a path out of future snapshots. | Says nothing about what is already recorded, and a forced add walks around it. |
| Pre-commit hooks and scanners | Refuse a recognized pattern before it is recorded. | Advisory and client-side. They catch shapes someone has already described, on machines that opted in. |
| Server-side push protection | Rejects a push carrying a known credential pattern. | The same pattern boundary — and the secret already exists in the local history of whoever wrote it. |
| History rewriting | Removes the object from the rewritten history. | Changes commit identity for everyone downstream, and does nothing about copies already taken. |
| A secrets manager | Keeps live credentials out of the repository entirely. This is the correct control for a credential. | It does not help with the source, config, keys, and data that must live in the repository and must not be readable by everyone holding clone access. |
A different primitive
Move the boundary from the push to the object.
TOVIO encrypts protected paths at snapshot time — before the object is written, so plaintext never lands in a tracked tree and key material never enters the synced object store.
- Cloning stops implying reading. Content keys are wrapped for explicitly named recipients. A clone that is not one of them holds the whole repository and reads ciphertext.
- Refusal happens before decryption. An out-of-scope read is refused rather than recorded after the fact.
- Protected reads through TOVIO are recorded. The per-actor audit chain is signed, which makes tampering with the record detectable.
- It works with no server. Tier-0 Solo uses
age/X25519 keys offline — no Key Authority to stand up before you can protect a single path.
What this does not do
- It is not a secrets manager. A live production credential belongs in a managed store with short lifetimes and rotation — not in version control, encrypted or otherwise. A repository is the wrong lifecycle for a rotating secret.
- It does not un-leak an existing Git repository. Anything already committed elsewhere still has to be rotated. An import brings the history with it.
- It protects content, not shape. Which paths exist, when they changed, and who changed them remain part of the collaboration surface.
Read how the permission model actually works.
The documentation is the source of truth for implemented behavior, supported profiles, and specification-only surface.