I built this because I kept wiring up AI agents to APIs and realizing the credential story was always the same: dump a key in an .env file and hope for the best.
The existing tools (pass, sops, git-crypt) are close but they assume a single human identity. When you have multiple agents that each need scoped access to different sets of secrets, and you need to grant/revoke per agent, the model breaks down.
agent-vault gives each agent its own age keypair. Secrets are multi-recipient encrypted and committed to a Git repo as ciphertext. The Git provider is untrusted storage. Grant and revoke access per agent, and affected secrets are re-encrypted automatically.
The recovery model uses key escrow: each agent's private key is encrypted with the owner's public key and stored in the repo. If a machine dies, the owner decrypts the escrow and restores the agent's key. The entire system is self-contained in the repo.
Design decisions worth discussing:
- age over GPG. Simpler, auditable, handles multi-recipient natively, no web of trust complexity.
- Git as the persistence layer. Not a database, just an encrypted blob store with versioning and collaboration built in. Each secret is its own .enc file so merge conflicts are nearly impossible.
- Key escrow rather than Shamir's or threshold schemes. The repo owner already provisioned the agents and their credentials, so giving them recovery capability doesn't expand the trust boundary. Keeps v1 simple.
- Agents are read-only. They can pull and decrypt but can't write back to the vault. Credential rotation is a human/CI operation. This was a deliberate trust boundary choice.
Written in Rust (using the rage crate for age encryption). Ships with Python and Node.js SDKs and an MCP server so MCP-compatible agents can request credentials through tool-use without touching key material.
ewimsatt•1h ago
The existing tools (pass, sops, git-crypt) are close but they assume a single human identity. When you have multiple agents that each need scoped access to different sets of secrets, and you need to grant/revoke per agent, the model breaks down.
agent-vault gives each agent its own age keypair. Secrets are multi-recipient encrypted and committed to a Git repo as ciphertext. The Git provider is untrusted storage. Grant and revoke access per agent, and affected secrets are re-encrypted automatically.
The recovery model uses key escrow: each agent's private key is encrypted with the owner's public key and stored in the repo. If a machine dies, the owner decrypts the escrow and restores the agent's key. The entire system is self-contained in the repo.
Design decisions worth discussing: - age over GPG. Simpler, auditable, handles multi-recipient natively, no web of trust complexity. - Git as the persistence layer. Not a database, just an encrypted blob store with versioning and collaboration built in. Each secret is its own .enc file so merge conflicts are nearly impossible. - Key escrow rather than Shamir's or threshold schemes. The repo owner already provisioned the agents and their credentials, so giving them recovery capability doesn't expand the trust boundary. Keeps v1 simple. - Agents are read-only. They can pull and decrypt but can't write back to the vault. Credential rotation is a human/CI operation. This was a deliberate trust boundary choice.
Written in Rust (using the rage crate for age encryption). Ships with Python and Node.js SDKs and an MCP server so MCP-compatible agents can request credentials through tool-use without touching key material.