Skip to main content

Documentation Index

Fetch the complete documentation index at: https://theseventeen-2abbdf80.mintlify.app/llms.txt

Use this file to discover all available pages before exploring further.

On Linux, keychain-auth listens on a Unix domain socket and uses the SO_PEERCRED socket option to retrieve the verified PID, UID, and GID of every connecting process directly from the kernel. It reads /proc/[PID]/exe to resolve the binary path, computes a SHA-256 hash, and checks it against your approved policy before forwarding requests to GNOME Keyring or KWallet over D-Bus.

The problem: D-Bus has no process verification

Linux’s standard Secret Service API (org.freedesktop.secrets) is accessible to every process running under your user session — with no identity checks and no prompts. Any script, build tool, or compromised package dependency (an npm post-install hook, a pip package, a cargo crate) can call SearchItems and GetSecret over D-Bus to silently harvest every credential stored in GNOME Keyring: AWS keys, API tokens, database passwords, SSH passphrases. keychain-auth closes this gap. It sits in front of D-Bus and acts as the sole process that queries the Secret Service. Your applications talk to keychain-auth over a socket; keychain-auth verifies their identity at the kernel level before deciding whether to fulfill the request.

Socket path

The daemon binds a Unix domain socket with 0600 permissions so no other user account can reach it. The path is based on $XDG_RUNTIME_DIR:
$XDG_RUNTIME_DIR/keychain-auth/agent.sock
If XDG_RUNTIME_DIR is not set, the daemon falls back to:
~/.cache/keychain-auth/agent.sock

Kernel-level process verification

When a client connects, the daemon calls SO_PEERCRED on the Unix domain socket. The kernel fills in a ucred struct with the verified pid, uid, and gid of the caller — values the client process cannot forge. With the verified PID, the daemon reads the /proc/[PID]/exe symlink to get the absolute path of the running executable on disk. It then reads the binary file and computes a SHA-256 hash. Linux prevents running executables from being modified in place (the ETXTBSY error), so the hash of a live process reliably identifies exactly what you approved.

GNOME Keyring and KWallet backend

On a desktop session with a running D-Bus, the daemon stores and retrieves secrets through the FreeDesktop.org Secret Service API (org.freedesktop.secrets). Both GNOME Keyring and KWallet implement this interface. The daemon manages all D-Bus calls on your behalf — you interact only through the keychain-auth socket protocol. Because all keychain traffic is routed through the daemon, unregistered processes can never reach the Secret Service directly through keychain-auth. They can still call D-Bus themselves — see the note below.
keychain-auth controls access to secrets it manages. If you store sensitive credentials in GNOME Keyring under a different service namespace (i.e. not through keychain-auth), those items remain directly accessible over D-Bus to any process in your session. For full protection, store all credentials through keychain-auth.

Headless Linux and WSL fallback

If $DISPLAY is not set or the WSL_DISTRO_NAME environment variable is present, no D-Bus session is available. The daemon automatically switches to a file-based keyring backend:
~/.keychain-auth/keyring.json
The file is created with 0600 permissions. Secrets are stored base64-encoded. The switch is fully automatic — you do not need to change any configuration.
The file backend is not protected by a hardware-backed key the way GNOME Keyring or a TPM-backed store would be. On headless servers handling production credentials, consider a dedicated secrets manager. The file backend is primarily intended for local development environments and WSL workflows.
The switch is fully automatic. The daemon checks for WSL_DISTRO_NAME environment variable and whether a $DISPLAY is set. If neither is available, it falls back to the file backend without any user intervention.

The O_CLOEXEC requirement

If your application forks a child process after connecting to the daemon, the child inherits all open file descriptors — including the live, already-authenticated socket. The child could then send requests to the daemon as your trusted application. Prevent this by opening the socket with SOCK_CLOEXEC:
fd, err := syscall.Socket(syscall.AF_UNIX, syscall.SOCK_STREAM|syscall.SOCK_CLOEXEC, 0)
The kernel will automatically close the descriptor on any exec() call. The official keychain-auth SDK sets this flag for you.

Quick-start

# Start the daemon
keychain-auth start

# Register your CLI tool once during setup
keychain-auth register $(which your-cli-tool)

# Inspect the pending approval queue
keychain-auth list-pending

# Approve a binary by its SHA-256 hash
keychain-auth approve sha256:<hash>
The audit log is written to ~/.local/share/keychain-auth/audit.log. Every approved and denied request is recorded with the binary path, hash, PID, and target names. Plaintext secret values are never written to the log.