Documentation
¶
Overview ¶
Package agent implements a small ssh-agent-style background daemon that caches decrypted private keys in memory for a bounded TTL, so a headless process (like the MCP server Claude Code spawns) can unseal a vault secret without a passphrase prompt or ENVAULT_PASSPHRASE — as long as a human has unlocked that key from a real terminal within the TTL window.
Transport: a Unix domain socket, one JSON request/response pair per connection. Socket and containing directory are owner-only (0600/0700), keeping the same same-user threat model as ENVAULT_PASSPHRASE or a raw keychain blob — this is a convenience trade-off (wider exposure window: a decrypted key lives in memory up to TTL instead of being cleared right after use), never the default, and strictly opt-in via `envault agent unlock`.
Index ¶
- Constants
- func EnsureRunning() error
- func IsRunning() bool
- func Listen() (net.Listener, error)
- func Lock() error
- func Serve(ln net.Listener)
- func SocketPath() (string, error)
- func Stop() error
- func TryGet(id string) ([]byte, bool)
- func Unlock(id string, key []byte, ttl time.Duration) error
- type StatusEntry
Constants ¶
const DefaultTTL = 8 * time.Hour
DefaultTTL is used when the caller doesn't specify one.
Variables ¶
This section is empty.
Functions ¶
func EnsureRunning ¶
func EnsureRunning() error
EnsureRunning starts a detached `envault agent serve-internal` process if none is already reachable, then waits (briefly) for it to start accepting connections. The spawned process is session-detached (no controlling terminal) so it outlives the caller and its terminal.
func IsRunning ¶
func IsRunning() bool
IsRunning reports whether an agent is currently reachable at SocketPath.
func Listen ¶
Listen creates the Unix socket at SocketPath, ready for Serve. Returns an error if another agent is already listening there. A stale socket file left behind by a crashed agent (present on disk but nothing listening) is removed automatically before binding.
func Lock ¶
func Lock() error
Lock clears every cached key. A no-op (not an error) if no agent is running.
func Serve ¶
Serve accepts connections on ln until it is closed (by a "stop" request or by the caller), handling one request/response per connection. Blocks until the listener closes. All cached key bytes are cleared before returning.
func SocketPath ¶
SocketPath returns the fixed, per-user location of the agent socket: ~/.envault/agent.sock (or $ENVAULT_AGENT_SOCKET, if set). Not per-project — one agent serves every vault on the machine, the same way ssh-agent serves every repo.
func Stop ¶
func Stop() error
Stop clears all cached keys and terminates the agent process. A no-op (not an error) if no agent is running.
func TryGet ¶
TryGet asks the agent for the cached plaintext private key for id. Returns (nil, false) whenever the key isn't available for any reason — agent not running, id not cached, expired, or a transport error — so callers can silently fall back to the passphrase-protected keychain path. It never spawns an agent: only Unlock does that, since Get is on the read path used by every command and must stay a no-op when the user never opted in.
Types ¶
type StatusEntry ¶
StatusEntry describes one cached identity.
func Status ¶
func Status() ([]StatusEntry, error)
Status reports every currently-cached identity and its remaining TTL. A nil, non-error result means no agent is running — that is a normal state, not a failure.