How do you install the CLI?
The command-line tool is a single-file program for macOS (Apple Silicon and Intel) and Linux (x64 and arm64); it doesn't need Node.js. The easiest way is Homebrew:
brew install keyzula/tap/keyzula
keyzula --versionOn Linux machines without Homebrew (for example servers and CI runners), download it and unpack it into /usr/local/bin:
# x64
curl -fsSL https://github.com/KeyZula/homebrew-tap/releases/download/v1.2.1/keyzula-1.2.1-linux-x64.tar.gz | sudo tar -xz -C /usr/local/bin keyzula
# arm64
curl -fsSL https://github.com/KeyZula/homebrew-tap/releases/download/v1.2.1/keyzula-1.2.1-linux-arm64.tar.gz | sudo tar -xz -C /usr/local/bin keyzulaOn Windows (x64), download keyzula.exe with PowerShell and add it to your PATH (then open a new terminal):
$dir = "$env:LOCALAPPDATA\Programs\KeyZula"
Invoke-WebRequest https://github.com/KeyZula/homebrew-tap/releases/download/v1.2.1/keyzula-1.2.1-windows-x64.zip -OutFile "$env:TEMP\keyzula.zip"
Expand-Archive -Force "$env:TEMP\keyzula.zip" $dir
[Environment]::SetEnvironmentVariable("Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";$dir", "User")To update:
brew update && brew upgrade keyzulaThe archives and a SHA256SUMS file are published in the homebrew-tap releases.
Sign in and basics
keyzula login asks for your email address and master password, and for a code if two-step verification is on. The master password is hidden as you type and never written to disk.
keyzula login
keyzula status
keyzula list github
keyzula get password GitHub
keyzula get username GitHub
keyzula get totp GitHubget prints the password, username or totp field of an item by name or ID; 2FA codes are computed on your computer. list and status have --json output for scripts. If the SSH agent is running and unlocked, these commands don't ask for your password.
The default server is https://app.keyzula.com. For another server, use the --server flag or the KEYZULA_SERVER environment variable:
keyzula login --server https://vault.example.comAccounts that sign in with SSO or passwordless (trusted device) sign-in aren't supported in the command line yet.
How do you start the SSH agent?
The built-in SSH agent offers the SSH key items in your personal vault and in the collections you can access to ssh and git. Private keys live only in the agent process's memory; they never touch the disk and are wiped when the agent locks.
keyzula ssh-agent --daemon
keyzula ssh add-config--daemon runs the agent in the background (log: ~/.config/keyzula/ssh-agent.log; it only contains key names, fingerprints and times). The agent refreshes the vault every 5 minutes, so keys you add to the vault show up on their own.
- Supported keys: Ed25519, RSA (rsa-sha2-256/512) and ECDSA P-256/384/521; OpenSSH and PEM/PKCS#8 formats, including passphrase-protected keys (the item's passphrase field is used).
- Hardware keys (
sk-*) and DSA aren't supported. - Keys shared with the "can't see the password" permission aren't added to the agent.
- Add and remove requests from
ssh-addare refused; manage keys in the vault.
ssh configuration
keyzula ssh add-config prints the configuration snippet for your system. To use the keys in your vault for all hosts, add it to ~/.ssh/config:
# ~/.ssh/config
Host *
IdentityAgent "~/.config/keyzula/ssh-agent.sock"For the current terminal session only, use the SSH_AUTH_SOCK variable:
export SSH_AUTH_SOCK="$HOME/.config/keyzula/ssh-agent.sock"
ssh-add -L
ssh -T git@github.comOn macOS and Linux the socket is created with permissions only you can access (0600). If XDG_CONFIG_HOME is set, the path changes accordingly; ssh add-config always shows the right one.
On Windows the agent uses a named pipe with a name unique to your user instead of a socket, and works with the OpenSSH client built into Windows. Add the IdentityAgent line from ssh add-config to %USERPROFILE%\.ssh\config. Git for Windows ships its own ssh, so point Git at the Windows one; ssh add-config also prints the commit signing commands:
keyzula ssh-agent --daemon
keyzula ssh add-config
git config --global core.sshCommand "C:/Windows/System32/OpenSSH/ssh.exe"Signature confirmation and auto-lock
keyzula ssh-agent --confirm
keyzula ssh-agent --daemon --lock-after 2h
keyzula lock
keyzula unlock--confirm: asks for confirmation (y/N) on the agent's terminal before every signature. Because it needs a terminal, it can't be combined with--daemon; run the agent in the foreground in a separate terminal tab.--lock-after: locks the agent after this much inactivity (default12h;0= never). Write durations like30mor2h.keyzula lockwipes the keys from memory;keyzula unlockasks for your master password and opens the agent again.
How do you sign Git commits?
You can sign git commits with an SSH key from your vault. With the agent running:
git config --global gpg.format ssh
git config --global user.signingkey "key::$(ssh-add -L | head -n1)"
git config --global commit.gpgsign truessh-add -L lists the public keys in the agent; if you have more than one, pick the right line instead of head -n1. Add the same public key to your GitHub or GitLab account as a signing key.
Secrets: read, run and inject
Instead of writing passwords into scripts and configuration files, write a reference that points to the value in your vault:
kz://<collection>/<item>/<field>- Collection and item: a name (case-insensitive) or an ID.
~is your personal vault (signed-in users only). - Field:
password,username,totp(the current code),notes,url,private_key,public_key,passphrase,number,codeor the label of a custom field. - Write a
/inside a name as%2F, and always quote references in the shell.
keyzula read "kz://Production/Postgres/password"
keyzula read -n "kz://~/GitHub/totp"The run command resolves the kz:// values in the environment and in the files given with --env-file, then starts the command with that environment. Resolved values are concealed in the command's output by default; use --no-masking for interactive programs.
# .env
DB_PASSWORD=kz://Production/Postgres/password
STRIPE_KEY="kz://Production/Stripe/API key"
keyzula run --env-file .env -- ./deploy.shThe inject command fills in the {{ kz://… }} placeholders in a template. The output file is written with permissions only you can read (0600), and an existing file is only replaced with --force.
# config.yml.tpl
database:
password: "{{ kz://Production/Postgres/password }}"
keyzula inject -i config.yml.tpl -o config.ymlAll references are resolved before anything runs; if a single one fails, nothing is started or written.
What are service accounts for?
A service account is a machine identity that lets servers, CI jobs and AI agents read the secrets in selected collections of an organization, read-only. An owner or admin creates one in the web vault under Organization → Service accounts, picks the collections and creates an access token. The token is shown only once.
export KEYZULA_SERVICE_TOKEN='kzsa_1_…'
keyzula read "kz://Production/Postgres/password"- Zero knowledge: the token and its keys are created in the admin's browser. The server never sees the token itself; the command-line tool decrypts items locally.
- Read-only: a service account can only read the collections it was given; it can't add or change items.
- Revocation: each token can be revoked on its own and can have an expiry date. Revoking a token deletes its keys from the server.
- Audit: every read is written to the organization's audit log with the time, IP address and collection.
Without KEYZULA_SERVICE_TOKEN, the same commands run as the signed-in user.
GitHub Actions example
Add the token to your repository's secrets as KEYZULA_SERVICE_TOKEN. In the workflow, download the Linux build and pass secrets to a step's environment as kz:// references:
jobs:
deploy:
runs-on: ubuntu-latest
env:
KEYZULA_SERVICE_TOKEN: ${{ secrets.KEYZULA_SERVICE_TOKEN }}
steps:
- uses: actions/checkout@v4
- name: Install KeyZula CLI
run: curl -fsSL https://github.com/KeyZula/homebrew-tap/releases/download/v1.2.1/keyzula-1.2.1-linux-x64.tar.gz | sudo tar -xz -C /usr/local/bin keyzula
- name: Deploy
env:
DB_PASSWORD: kz://Production/Postgres/password
run: keyzula run -- ./scripts/deploy.sh
- name: Render config
run: keyzula inject -i deploy/app.yml.tpl -o deploy/app.ymlThe run command removes KEYZULA_SERVICE_TOKEN from the child process's environment, forwards signals and passes the exit code through. Use one token per repository or environment, give it an expiry date and revoke it when it's no longer needed.
Give AI agents their own service account too, one that sees only the collection they need. API keys then reach only the process environment, never the prompt or the repository:
KEYZULA_SERVICE_TOKEN=kzsa_1_… \
OPENAI_API_KEY="kz://AI agents/OpenAI/API key" \
keyzula run -- python agent.pyAI assistants (MCP)
keyzula mcp connects Claude, Cursor, VS Code and other MCP-compatible AI assistants to your vault. The assistant finds items by name, website or username and uses secrets through kz:// references without seeing them: values go into the environment of a command it runs (and are concealed in the output) or into a file only you can read.
keyzula login
keyzula ssh-agent --daemon
claude mcp add keyzula -- keyzula mcpFor Claude Desktop, Cursor and other clients, add it to the MCP configuration. Desktop apps may not see your terminal's PATH, so use the full path from which keyzula. Step-by-step setup for each assistant is on the AI assistants page.
{
"mcpServers": {
"keyzula": { "command": "/opt/homebrew/bin/keyzula", "args": ["mcp"] }
}
}search_itemsreturns names, locations, usernames, websites and references; never passwords.run_commandruns a program with secrets in its environment and returns its output with the values concealed.inject_templatefills a{{ kz://… }}template and writes a file only you can read (0600); only the file path goes back to the assistant.read_secret, which shows a value such as a password or a 2FA code, is off by default. Turn it on with--allow-reveal: every request then needs your approval in a KeyZula window on your computer, which the assistant cannot click.
The MCP server reads only from the unlocked agent and never asks for your master password. With --confirm it asks you before every use of a secret. Every use appears in the access log as "Used by an AI assistant". For teams, start it with a service account token so the assistant sees only the collections you choose.
Security notes
- Only the server URL, email, session token and the encrypted keys returned by the server are written to
~/.config/keyzula(0700;config.json, 0600). - The master password, derived keys, the decrypted vault and private SSH keys never touch the disk; they live only in the agent process's memory and are wiped on lock.
- With a service token, the tool writes nothing to its configuration directory. No secret is written to disk except the
inject -ooutput you explicitly ask for. - Reads with
getand keys the agent uses for signing are recorded in the access log like in the other apps (only the item ID, the action and the time; never the name or contents). - Never put the token in a repository, a Docker image or a prompt; keep it in your CI's secrets.
For architecture details, see the Security page.
Frequently asked questions
Which systems does the command-line tool run on?
It's a single-file program for macOS (Apple Silicon and Intel) and Linux (x64 and arm64); it doesn't need Node.js. The easiest way to install it is Homebrew. On Windows (x64), it's a single keyzula.exe file.
Are my SSH keys written to disk?
No. Private keys live only in the agent process's memory and are wiped when the agent locks. Only the server URL, email, session token and the encrypted keys returned by the server are written to the configuration directory.
Which SSH key types are supported?
Ed25519, RSA (rsa-sha2-256/512) and ECDSA P-256/384/521, in OpenSSH and PEM/PKCS#8 formats, including passphrase-protected keys. Hardware keys (sk-*) and DSA aren't supported.
How do I give secrets to CI and AI agents?
Create a service account in the web vault, select only the collections it needs and add its access token to your CI's secrets. The run command resolves kz:// references in the environment at runtime, so values never end up in your repository or a prompt.
Can AI assistants like Claude or Cursor use my vault?
Yes, through the keyzula mcp server. The assistant searches your items and uses secrets through kz:// references without seeing them; showing a value is off by default and, when turned on, needs your approval for every request. Every use is recorded in the access log.
Can accounts that sign in with SSO use the command line?
Not yet: accounts that sign in with SSO or passwordless (trusted device) login aren't supported on the command line. For servers and CI, use a service account in your organization.