Integration
KeyZero with macOS Keychain
Secret management with macOS Keychain and KeyZero -- zero-config local storage, shell hooks, and a smooth upgrade path to team backends.
The macOS Keychain is the simplest backend KeyZero supports. It requires no external services, no cloud accounts, and no additional CLI tools. Secrets are stored in the system Keychain that ships with every Mac, and KeyZero resolves them at runtime just like any other backend.
This makes it the ideal starting point for local development, personal projects, and solo developers who want secure secret management without infrastructure overhead.
How It Works
KeyZero uses the macOS Security framework to read generic password items from the default Keychain. When you run kz run, it looks up each configured secret by its service name and account, retrieves the password value, and injects it as an environment variable.
No daemon, no sidecar, no network calls. Resolution happens locally against the Keychain database that macOS already manages and encrypts at rest.
Storing Secrets in the Keychain
You can add secrets using the security command-line tool or through the Keychain Access GUI.
Via the Command Line
# Add a secret
security add-generic-password \
-s "keyzero:myapp:openai-key" \
-a "keyzero" \
-w "sk-proj-abc123..." \
-T "" \
-U
# Verify it was stored
security find-generic-password \
-s "keyzero:myapp:openai-key" \
-a "keyzero" \
-w
The -s flag sets the service name (which KeyZero uses as the lookup key), -a sets the account, -w sets the password value, -T "" prevents automatic access by other apps, and -U updates the entry if it already exists.
Via Keychain Access
- Open Keychain Access from Spotlight or
/Applications/Utilities/ - Select login keychain in the sidebar
- Click the + button to create a new password item
- Set Keychain Item Name to your service name (e.g.,
keyzero:myapp:openai-key) - Set Account Name to
keyzero - Enter the secret value as the password
Bundle Configuration
Define a Keychain backend and reference secrets by their service name:
backends:
local:
type: keychain
resolvers:
- name: openai-key
mode: direct
backend: local
path: "keyzero:myapp:openai-key"
field: password
account: keyzero
- name: db-password
mode: direct
backend: local
path: "keyzero:myapp:db-password"
field: password
account: keyzero
- name: github-token
mode: direct
backend: local
path: "keyzero:myapp:github-token"
field: password
account: keyzero
The path corresponds to the service name in the Keychain. The account field identifies which account entry to use. The field should be password to retrieve the stored password value.
Running with Keychain Secrets
# Secrets resolve from macOS Keychain
kz run -- npm start
# Works with blind mode too
kz run --blind -- python agent.py
On first access, macOS may prompt you to allow KeyZero to read from the Keychain. Click Always Allow to avoid repeated prompts.
Shell Hooks for Automatic Resolution
KeyZero's shell hook integration is especially useful with the Keychain backend. Add the hook to your shell profile:
# In ~/.zshrc or ~/.bashrc
eval "$(kz shell hook)"
Now, when you cd into a directory containing a KeyZero bundle, secrets are resolved from the Keychain and exported automatically:
cd ~/projects/myapp
# OPENAI_API_KEY, DB_PASSWORD, GITHUB_TOKEN are now set
echo $OPENAI_API_KEY # Resolved from Keychain
No source .env, no export statements, no wrapper scripts. Leave the directory and the variables are cleaned up. This approach is part of the shift from hardcoded secrets to zero-knowledge workflows, replacing static files with runtime secret resolution.
Ideal Use Cases
The Keychain backend fits best in these scenarios:
- Local development: Store API keys, database passwords, and service tokens without
.envfiles that risk accidental commits - Personal projects: Full secret management without provisioning Vault, AWS, or 1Password
- Solo developers: Secure storage backed by the OS-level encryption macOS already provides
- Getting started with KeyZero: Learn the bundle configuration format with zero infrastructure dependencies before adopting a team backend
Upgrading to a Team Backend
The most practical advantage of using the Keychain backend is that your bundle configuration translates directly to any other backend. When you move from solo development to a team, you change the backend definition and leave the resolvers untouched:
# Before -- local Keychain
backends:
local:
type: keychain
# After -- 1Password for the team
backends:
local:
type: onepassword_cli
vault: Engineering
The resolver names, environment variable mappings, and application code stay the same. You adjust the path and field values to match the new backend's naming convention, and the rest of the bundle works as-is.
This also means you can use the Keychain locally while CI resolves from AWS Secrets Manager or Vault. Same bundle structure, different backend per environment.
Security Characteristics
The macOS Keychain encrypts entries at rest using the user's login password. Access control is per-application: macOS prompts the user when a new process first reads a Keychain item. Secrets are never written to disk in plaintext by KeyZero -- they exist only in the process environment during kz run, and KeyZero's blind mode can further restrict exposure by replacing real values with opaque tokens before they reach the consuming process.
For production deployments, team collaboration, and CI pipelines, consider upgrading to 1Password, HashiCorp Vault, or AWS Secrets Manager. The Keychain backend is designed for local development, and its security model is tied to the macOS user account.