1Password
Integrate with 1Password to retrieve secrets from your vaults using the 1Password CLI.
Quick Start
bash
# 1. Install 1Password CLI
brew install 1password-cli
# 2. Create service account and get token
# (via 1Password web interface)
# 3. Store token (bootstrap with age)
fnox set OP_SERVICE_ACCOUNT_TOKEN "ops_YOUR_TOKEN" --provider age
# 4. Configure 1Password provider
cat >> fnox.toml << 'EOF'
[providers]
onepass = { type = "1password", vault = "Development" }
EOF
# 5. Add secrets to 1Password (via app or CLI)
op item create --category=login \
--title="Database" \
--vault="Development" \
password="super-secret-password"
# 6. Reference in fnox
cat >> fnox.toml << 'EOF'
[secrets]
DATABASE_PASSWORD = { provider = "onepass", value = "Database" }
EOF
# 7. Use it
export OP_SERVICE_ACCOUNT_TOKEN=$(fnox get OP_SERVICE_ACCOUNT_TOKEN)
fnox get DATABASE_PASSWORDPrerequisites
- 1Password account
- 1Password CLI installed
Installation
bash
# macOS
brew install 1password-cli
# Linux
curl -sS https://downloads.1password.com/linux/keys/1password.asc | \
sudo gpg --dearmor --output /usr/share/keyrings/1password-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/1password-archive-keyring.gpg] https://downloads.1password.com/linux/debian/$(dpkg --print-architecture) stable main" | \
sudo tee /etc/apt/sources.list.d/1password.list
sudo apt update && sudo apt install 1password-cli
# Windows (via Scoop)
scoop install 1password-cliSetup
1. Create a Service Account
- Go to your 1Password account
- Navigate to Settings → Integrations → Service Accounts
- Click "Create Service Account"
- Give it a name (e.g., "fnox-dev")
- Grant access to your vault
- Copy the
OP_SERVICE_ACCOUNT_TOKEN(starts withops_)
2. Store the Token (Bootstrap)
Use age encryption to store the token:
bash
# First, set up age provider (if not already done)
cat >> fnox.toml << 'EOF'
[providers]
age = { type = "age", recipients = ["age1..."] }
EOF
# Store the 1Password token encrypted in fnox
fnox set OP_SERVICE_ACCOUNT_TOKEN "ops_YOUR_TOKEN_HERE" --provider ageNow you can bootstrap the token:
bash
export OP_SERVICE_ACCOUNT_TOKEN=$(fnox get OP_SERVICE_ACCOUNT_TOKEN)3. Configure 1Password Provider
toml
[providers]
onepass = { type = "1password", vault = "Development", account = "my.1password.com" } # account is optionalAdding Secrets to 1Password
Via 1Password App
- Open 1Password app
- Select your vault (e.g., "Development")
- Click + to create new item
- Choose category (Login, Password, etc.)
- Fill in details
- Save
Via 1Password CLI
bash
# Export token first
export OP_SERVICE_ACCOUNT_TOKEN=$(fnox get OP_SERVICE_ACCOUNT_TOKEN)
# Create a login item
op item create --category=login \
--title="Database" \
--vault="Development" \
username="admin" \
password="super-secret-password"
# Create an API credential
op item create --category=password \
--title="Stripe API Key" \
--vault="Development" \
password="sk_live_abc123xyz789"
# Create with custom fields
op item create --category=login \
--title="AWS Credentials" \
--vault="Development" \
"Access Key=AKIAIOSFODNN7EXAMPLE" \
"Secret Key=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"Referencing Secrets
Add references to fnox.toml:
toml
[secrets]
DATABASE_PASSWORD = { provider = "onepass", value = "Database" } # Item name (fetches 'password' field)
DB_USERNAME = { provider = "onepass", value = "Database/username" } # Specific field
API_KEY = { provider = "onepass", value = "op://Development/API Keys/credential" } # Full op:// URIReference Formats
fnox supports multiple ways to reference 1Password items:
1. Item Name (Gets Password Field)
toml
[secrets]
MY_SECRET = { provider = "onepass", value = "My Item" } # → Gets the 'password' field2. Item Name + Field
toml
[secrets]
USERNAME = { provider = "onepass", value = "Database/username" } # → Gets 'username' field
PASSWORD = { provider = "onepass", value = "Database/password" } # → Gets 'password' fieldCommon fields: username, password, url, notes
3. Full op:// URI
toml
[secrets]
API_KEY = { provider = "onepass", value = "op://Development/API Keys/credential" }Format: op://VAULT/ITEM/FIELD
Usage
bash
# Export token (once per session)
export OP_SERVICE_ACCOUNT_TOKEN=$(fnox get OP_SERVICE_ACCOUNT_TOKEN)
# Get secrets
fnox get DATABASE_PASSWORD
fnox get DB_USERNAME
# Run commands
fnox exec -- npm startMulti-Environment Example
toml
# Bootstrap token (encrypted in git)
[providers]
age = { type = "age", recipients = ["age1..."] }
onepass = { type = "1password", vault = "Development" }
[secrets]
OP_SERVICE_ACCOUNT_TOKEN = { provider = "age", value = "encrypted-token..." }
DATABASE_URL = { provider = "onepass", value = "Dev Database" }
# Production: Different 1Password vault
[profiles.production.providers]
onepass = { type = "1password", vault = "Production" }
[profiles.production.secrets]
DATABASE_URL = { provider = "onepass", value = "Prod Database" }CI/CD Example
GitHub Actions
yaml
name: Deploy
on: [push]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v3
- name: Setup fnox age key
env:
FNOX_AGE_KEY: ${{ secrets.FNOX_AGE_KEY }}
run: echo "Age key configured"
- name: Deploy with 1Password secrets
run: |
# Bootstrap 1Password token from fnox
export OP_SERVICE_ACCOUNT_TOKEN=$(fnox get OP_SERVICE_ACCOUNT_TOKEN)
# Now we can access 1Password secrets
fnox exec --profile production -- ./deploy.shTeam Workflow
- Admin creates service account in 1Password
- Admin stores token encrypted in fnox:bash
fnox set OP_SERVICE_ACCOUNT_TOKEN "ops_..." --provider age git add fnox.toml && git commit -m "Add 1Password token" - Admin creates items in 1Password vault
- Admin adds references to fnox.toml:toml
[secrets] DATABASE_URL = { provider = "onepass", value = "Database" } - Team members pull and use:bash
git pull export FNOX_AGE_KEY=... export OP_SERVICE_ACCOUNT_TOKEN=$(fnox get OP_SERVICE_ACCOUNT_TOKEN) fnox exec -- npm start
Service Account vs Personal Token
Service Account (Recommended)
- ✅ Designed for CI/CD and automation
- ✅ Doesn't expire
- ✅ No MFA required
- ✅ Scoped access to specific vaults
bash
# Use service account token
export OP_SERVICE_ACCOUNT_TOKEN="ops_..."Personal Token (Not Recommended)
- ❌ Requires interactive login
- ❌ Subject to MFA
- ❌ Session expires
bash
# Personal login (interactive)
op signin
eval $(op signin)WARNING
Always use service accounts for fnox, not personal tokens.
Pros
- ✅ Beautiful UI and mobile apps
- ✅ Excellent audit logs and access control
- ✅ No encryption key management
- ✅ Team-friendly
- ✅ Multi-factor authentication
- ✅ Service accounts for CI/CD
Cons
- ❌ Requires 1Password subscription
- ❌ Requires network access
- ❌ Service account token management
- ❌ Not free (starts at $7.99/user/month for teams)
Troubleshooting
"Authentication required"
Set the token:
bash
export OP_SERVICE_ACCOUNT_TOKEN=$(fnox get OP_SERVICE_ACCOUNT_TOKEN)"Item not found"
Check:
- Vault name is correct in fnox.toml
- Item exists in that vault
- Service account has access to the vault
bash
# List items in vault
op item list --vault "Development"
# Get item details
op item get "Database" --vault "Development""Vault not found"
Verify vault name:
bash
# List all vaults
op vault listBest Practices
- Use service accounts - Not personal tokens
- One service account per environment - Separate dev, staging, prod
- Grant minimal access - Only vaults the service account needs
- Store token encrypted - Use age provider to encrypt
OP_SERVICE_ACCOUNT_TOKEN - Rotate tokens periodically - Create new service account, update fnox.toml
- Use descriptive item names - Makes referencing easier
Next Steps
- Bitwarden - Open source alternative
- Real-World Example - Complete setup
- Profiles - Multi-environment configuration