K0KEYZERO

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

  1. Open Keychain Access from Spotlight or /Applications/Utilities/
  2. Select login keychain in the sidebar
  3. Click the + button to create a new password item
  4. Set Keychain Item Name to your service name (e.g., keyzero:myapp:openai-key)
  5. Set Account Name to keyzero
  6. 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 .env files 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.