OS Keychain
Store secrets in your operating system's native secure storage.
Supported Platforms
- macOS: Keychain Access (built-in)
- Windows: Credential Manager (built-in)
- Linux: Secret Service (via libsecret - GNOME Keyring, KWallet)
Quick Start
# 1. Linux only: Install libsecret
sudo apt-get install libsecret-1-0 libsecret-1-dev # Ubuntu/Debian
# 2. Configure provider
cat >> fnox.toml << 'EOF'
[providers.keychain]
type = "keychain"
service = "fnox"
EOF
# 3. Store a secret in OS keychain
fnox set DATABASE_URL "postgresql://localhost/mydb" --provider keychain
# 4. Retrieve from keychain
fnox get DATABASE_URLLinux Setup
On Linux, you need libsecret installed:
sudo apt-get install libsecret-1-0 libsecret-1-devsudo dnf install libsecret libsecret-develsudo pacman -S libsecretmacOS and Windows have built-in support—no installation needed.
Configuration
[providers.keychain]
type = "keychain"
service = "fnox" # Namespace for fnox secrets
prefix = "myapp/" # Optional prefix for secret namesService Name
The service acts as a namespace to isolate fnox secrets from other applications:
[providers.keychain]
service = "fnox" # All fnox secrets under "fnox" service
# Or use project-specific service
service = "myapp" # All secrets under "myapp" servicePrefix
Optional prefix prepended to secret names:
[providers.keychain]
service = "fnox"
prefix = "myapp/" # "database-url" becomes "myapp/database-url"How It Works
- Storage: Secrets are stored in the OS credential manager (encrypted by OS)
- Config:
fnox.tomlcontains only the secret name, not the value - Retrieval: fnox queries the OS keychain API
- Service: Acts as a namespace (isolates fnox secrets from other apps)
- Prefix: Additional namespacing within the service
Usage
Store a Secret
fnox set DATABASE_URL "postgresql://localhost/mydb" --provider keychainYour fnox.toml:
[secrets.DATABASE_URL]
provider = "keychain"
value = "database-url" # ← Keychain entry name, not the actual secretThe actual secret is stored in the OS keychain, encrypted.
Retrieve a Secret
fnox get DATABASE_URLRun Commands
fnox exec -- npm run devBootstrap Pattern
A common pattern is to store provider tokens in the keychain:
[providers.keychain]
type = "keychain"
service = "fnox"
[providers.age]
type = "age"
recipients = ["age1..."]
# Store 1Password token in keychain
[secrets.OP_SERVICE_ACCOUNT_TOKEN]
provider = "keychain"
value = "op-token"
# Other secrets encrypted with age
[secrets.DATABASE_URL]
provider = "age"
value = "encrypted..."Then bootstrap:
export OP_SERVICE_ACCOUNT_TOKEN=$(fnox get OP_SERVICE_ACCOUNT_TOKEN)
# Now can access 1Password secrets
fnox exec -- ./start.shExample Configurations
Personal Project
[providers.keychain]
type = "keychain"
service = "myapp"
[secrets.DATABASE_URL]
provider = "keychain"
value = "database-url"
[secrets.API_KEY]
provider = "keychain"
value = "api-key"Bootstrap Tokens
[providers.keychain]
type = "keychain"
service = "fnox-tokens"
[secrets.GITHUB_TOKEN]
provider = "keychain"
value = "github"
[secrets.NPM_TOKEN]
provider = "keychain"
value = "npm"Machine-Specific Secrets
# fnox.local.toml (gitignored)
[providers.keychain]
type = "keychain"
service = "fnox-local"
[secrets.LAPTOP_DB_URL]
provider = "keychain"
value = "laptop-db"Platform Details
macOS Keychain
Secrets stored in:
- Login Keychain (default)
- System Keychain (requires admin)
View in Keychain Access app:
- Open Keychain Access
- Search for service name (e.g., "fnox")
- Double-click to view/edit
Windows Credential Manager
Secrets stored in Windows Credential Manager.
View in Control Panel:
- Control Panel → User Accounts → Credential Manager
- Windows Credentials
- Look for fnox entries
Linux Secret Service
Secrets stored in:
- GNOME Keyring (GNOME desktop)
- KWallet (KDE desktop)
- Other Secret Service implementations
View with Seahorse (GNOME):
sudo apt install seahorse
seahorsePros
- ✅ OS-managed encryption
- ✅ Cross-platform (macOS, Windows, Linux)
- ✅ No external dependencies
- ✅ Free
- ✅ Built into operating system
- ✅ Secure by default
Cons
- ❌ Requires GUI/interactive session (doesn't work in headless CI)
- ❌ Not suitable for teams (secrets are per-machine)
- ❌ Keyring must be unlocked
- ❌ No audit logs
- ❌ No centralized management
Limitations
Headless Environments
Keychain provider requires a GUI session and doesn't work in:
- CI/CD (GitHub Actions, GitLab CI, etc.)
- Docker containers (without X11/Wayland)
- SSH sessions (without forwarding)
- Headless servers
For CI/CD, use age encryption or cloud providers instead.
Tests Auto-Skip in CI
fnox's keychain tests automatically skip in CI environments:
# Runs locally
mise run test:bats
# Skips keychain tests in CI
# GitHub Actions, GitLab CI, etc.Security
- Encryption: OS handles encryption (typically AES-256)
- Access control: OS enforces access (user/session isolation)
- Keyring unlock: May require password entry on first access
- Memory protection: OS manages secure memory handling
Troubleshooting
"Keyring is locked"
Unlock your keyring:
macOS:
- Keyring unlocks automatically on login
Linux (GNOME):
# Unlock manually
gnome-keyring-daemon --unlockWindows:
- Credential Manager unlocks on login
"Access denied"
Check that the process has access:
- macOS: May prompt for Keychain Access permission
- Linux: Ensure Secret Service is running
- Windows: Check User Account Control settings
"Service not available" (Linux)
Install and start Secret Service:
# Ubuntu/Debian
sudo apt-get install gnome-keyring
gnome-keyring-daemon --start
# Or use KWallet
sudo apt-get install kwalletmanagerBest Practices
- Use for local development only - Not for teams or CI
- Bootstrap provider tokens - Store 1Password/AWS tokens
- Machine-specific overrides - Use in
fnox.local.toml - Descriptive service names - Use project-specific services
- Keep keyring unlocked - Unlock on login for convenience
Next Steps
- Age Encryption - Team-friendly alternative
- Local Overrides - Per-machine configuration
- 1Password - Team password manager