Human-Only Secret Entry (Do This By Default)
By default, the only “actor” that should ever enter secret values into aivault is a human, manually. Do not ask an AI agent or coding LLM to “set the secret for you” (for example by pasting API keys into a chat). Many agent frameworks log conversations, tool calls, and intermediate context. If you paste a key into an agent chat, assume it may be stored, indexed, or exfiltrated. Recommended workflow:- Human obtains the secret from the provider dashboard.
- Human runs
aivault secrets create ...on the target machine and never shares the secret value with the agent. - Agents only run
aivault invoke ...(capability invocations), neversecrets create.
Security goal (be explicit)
aivault protects secrets best when the untrusted runtime:- cannot read the vault KEK (file/env/passphrase) and
- cannot act as an operator who can create/rotate/delete secrets or loosen capability policy.
Default behavior on Linux
On first run, a canonical install auto-initializes using the file provider:- Vault dir:
~/.aivault/data/vault - KEK file:
~/.aivault/keys/kek.key(outside the vault dir) - Daemon socket (when using
aivaultd):~/.aivault/run/aivaultd.sock
Recommended patterns
Pattern A: Dedicated OS user for aivault (recommended for servers)
Run aivault under a dedicated unix user (for exampleaivault) and run untrusted agents under a different user. This protects the vault because Linux filesystem access is governed by unix permissions: a process running as one user generally cannot read files owned 0600 by another user.
Practical notes:
- Keep the KEK source (file/env/passphrase) available only to the
aivaultuser. - Keep the vault directory readable/writable only by the
aivaultuser. - Do not run untrusted agent code as the
aivaultuser.
Step-by-step tutorial (minimal hardened setup)
- Create two unix users (one for aivault, one for agents):
- Install
aivaultandaivaultdsomewhere root-owned (example):
- Initialize the vault and enter secrets as a human (run as the
aivaultuser). Do this once per provider:
- Verify the key file and vault files are not readable by the
agentuser.
~aivault/.aivault/keys/kek.key
-rw-------):
agent user, this should fail:
Letting agents invoke without exposing keys (shared socket pattern)
The usual goal is:- secrets + KEK live with the
aivaultunix user - agents can invoke capabilities by connecting to
aivaultd - agents still cannot read the KEK source or decrypt secrets
aivault invoke ... should work with zero flags and no environment variables.
Step-by-step (recommended)
- One-time: configure cross-user socket access (run as root):
- Start the shared daemon (operator side):
- Agent usage (agent user):
--shared, no AIVAULTD_SOCKET, no AIVAULTD_AUTOSTART=0.
How it works:
- The
aivaultCLI auto-discovers a shared daemon socket at/var/run/aivault/aivaultd.sock. - When invoking via the shared socket, autostart is suppressed (the agent user cannot and should not try to start its own daemon).
- This works best with registry-backed capabilities. For custom capabilities, prefer invoking via
--request/--request-fileand include--method+--pathexplicitly. - Install
aivaultsystem-wide (or otherwise on the agent user’sPATH). With the thin-client invoke path, the agent does not need local read access to the vault files to invoke via the daemon socket. - If the agent can become
root, it can defeat OS-level isolation. Treat “no root” as a prerequisite.
Pattern B: Passphrase vault (when you can unlock interactively)
If you can tolerate manual unlock after restarts, passphrase mode can reduce unattended exposure:Pattern C: Env provider (only if you have a secure secret source)
The env provider reads a base64-encoded 32-byte KEK from an environment variable. This is only safe if your process supervisor provides the variable securely (and untrusted code cannot read it).Hardening checklist (agent-heavy environments)
- Prefer separate unix users: operator/aivault user vs agent user.
- Keep capabilities tight and add rate limits/size limits:
- Watch the audit log for misuse:
- Treat
AIVAULT_DIRas a foot-gun in shared environments: it changes where the vault (and sometimes daemon socket) lives. Prefer leaving it unset in production unless you have an explicit ops reason.
Running with aivaultd
On Linux, aivault invoke uses aivaultd by default (unix socket).
If you used aivaultd --shared or aivault setup systemd (the recommended cross-user pattern above), autostart is automatically suppressed on the agent account — no env vars needed.
For single-user server deployments where you run the daemon under a process supervisor but not via the shared socket, disable autostart so the CLI doesn’t start a redundant daemon:
aivaultd under your process supervisor and point the CLI at its socket:
Example: Fly.io Machine (Best-Effort Hardening)
Fly Machines are great for running a small Linux VM, but the core rule still applies: keep secret entry human-only, and keep the vault key (KEK) out of any untrusted/agent runtime. This is a practical pattern when you have an app that may run “agent-like” code and you want to reduce the chance that code can ever access the vault key.Goal
aivaultdcan decrypt and inject auth (it has access to the KEK).- Your app/agent process can invoke capabilities, but does not have the KEK in its environment.
Pattern A (preferred): separate users + shared daemon socket
If your Fly Machine image allows multiple unix users, this is the strongest “same machine” pattern:aivaultuser owns the vault + KEK.agentuser runs the app/agent runtime.- The app/agent calls
aivault invoke ...and the CLI auto-discovers the shared daemon socket.
- Create users
aivaultandagentin your image. - Install
aivault+aivaultdinto a root-owned path (e.g./usr/local/bin). - As root at boot, run:
- Start the daemon under the
aivaultuser:
- Run your app/agent runtime as the
agentuser; it can now call:
sudo, use the equivalent user-switching tool it does provide (for example su, runuser, setpriv, or an init supervisor that can run services as a specified user).
Pattern B (fallback): env-provider KEK only for the daemon process
- Store a random KEK as a Fly secret (do this as a human, not via an agent):
- Initialize the vault explicitly to use the env provider (so the KEK is never written to disk):
- Start
aivaultdwith access toAIVAULT_KEY, then start your app withAIVAULT_KEYremoved from its environment:
- This doesn’t magically sandbox your app. It is a “keep the KEK out of the agent runtime” best-effort step.
- On Linux, a process running as the same unix user can often read
/proc/<pid>/environfor sibling processes. If your agent and daemon run as the same user, assume the agent may be able to readAIVAULT_KEYunless you add OS hardening (or separate users/VMs). - If your app can run as root (or escape its sandbox), you still need stronger OS-level isolation.