Bitwarden
Integrate with Bitwarden (or self-hosted Vaultwarden) to retrieve secrets from your vault.
Quick start
Install the Bitwarden CLI, sign in, and unlock the vault:
bw login
export BW_SESSION="$(bw unlock --raw)"Create a login item named Database in the Bitwarden app, or use an existing item. Add its reference to fnox.toml:
[providers.bitwarden]
type = "bitwarden"
[secrets]
DATABASE_PASSWORD = { provider = "bitwarden", value = "Database/password" }fnox provider test bitwarden
fnox exec -- npm startThis is the password manager integration. For Bitwarden Secrets Manager and machine-account tokens, use bitwarden-sm.
Prerequisites
- Bitwarden account (or self-hosted Vaultwarden)
- Bitwarden CLI (
bw)
Installation
Install the Bitwarden CLI:
# macOS
brew install bitwarden-cli
# Linux
npm install -g @bitwarden/cli
# Windows
choco install bitwarden-cliSetup
1. Login to Bitwarden
# Cloud Bitwarden
bw login
# Self-hosted Vaultwarden
bw config server https://vault.example.com
bw login2. Unlock and get session token
# Unlock vault
export BW_SESSION=$(bw unlock --raw)
# Or if already unlocked
bw unlock
# Copy the session token from output3. Store session token (bootstrap)
Optionally, store the session encrypted for easy bootstrap:
# Store token encrypted with age
bw unlock --raw | fnox set BW_SESSION --provider age
# Next time, bootstrap from fnox:
export BW_SESSION=$(fnox get BW_SESSION)4. Configure Bitwarden provider
[providers]
bitwarden = { type = "bitwarden", collection = "my-collection-id", organization_id = "my-org-id" } # both optionalAdding secrets to Bitwarden
Via Bitwarden web Vault
- Go to vault.bitwarden.com
- Click + Add Item
- Choose type (Login, Card, Identity, Secure Note)
- Fill in details
- Save
Via Bitwarden CLI
bw create item accepts an encoded JSON item, rather than --name and --password flags. Follow the Bitwarden CLI creation instructions for the current item schema.
Referencing secrets
Add references to fnox.toml:
[secrets]
DATABASE_PASSWORD = { provider = "bitwarden", value = "Database" } # Item name (fetches 'password' field)
DB_USERNAME = { provider = "bitwarden", value = "Database/username" } # Specific field
API_KEY = { provider = "bitwarden", value = "API Key" }Reference formats
1. Item name (gets password field)
[secrets]
MY_SECRET = { provider = "bitwarden", value = "My Item" } # → Gets the 'password' field2. Item name + field
[secrets]
USERNAME = { provider = "bitwarden", value = "Database/username" }
PASSWORD = { provider = "bitwarden", value = "Database/password" }
TOTP = { provider = "bitwarden", value = "Database/totp" }
API_KEY = { provider = "bitwarden", value = "Database/API Key" }Supported standard fields are username, password, notes, uri (or url), and totp. Any other field name is resolved as a custom field. Custom field names may contain / and are case-sensitive when using the default bw backend.
Usage
# Unlock Bitwarden (once per session)
export BW_SESSION=$(bw unlock --raw)
# Or bootstrap: export BW_SESSION=$(fnox get BW_SESSION)
# Get secrets
fnox get DATABASE_PASSWORD
# Run commands
fnox exec -- npm startMulti-environment example
# Bootstrap session token (encrypted in git)
[providers]
age = { type = "age", recipients = ["age1..."] }
bitwarden = { type = "bitwarden" }
[secrets]
BW_SESSION = { provider = "age", value = "encrypted-session..." }
DATABASE_URL = { provider = "bitwarden", value = "Dev Database" }
# Production: Different Bitwarden organization
[profiles.production.providers]
bitwarden = { type = "bitwarden", organization_id = "prod-org-id" }
[profiles.production.secrets]
DATABASE_URL = { provider = "bitwarden", value = "Prod Database" }Multi-profile example
bw supports multiple accounts, as per the official documentation. fnox can access secrets in a specific profile by supplying an optional profile attribute to the provider:
default_provider = "bitwarden"
[providers.bitwarden]
type = "bitwarden"
profile = "Business"
[providers.bitwarden-perso]
type = "bitwarden"
profile = "Personal"rbw support
rbw is a stateful alternative to bw.
fnox supports rbw via an experimental backend.
default_provider = "bitwarden"
[providers.bitwarden]
type = "bitwarden"
backend = "rbw"
auth_command = "rbw unlock"The auth_command override ensures fnox prompts with rbw unlock instead of the default bw login when authentication fails.
NB: you must have set up the rbw CLI independently from fnox using rbw login.
Self-hosted Vaultwarden
Vaultwarden is a lightweight, open-source Bitwarden-compatible server:
# Configure Bitwarden CLI to use Vaultwarden
bw config server https://vault.example.com
# Login
bw login
# Unlock
export BW_SESSION=$(bw unlock --raw)
# Use normally with fnox
fnox get DATABASE_PASSWORDCI/CD example
GitHub Actions
name: Test
on: [push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jdx/mise-action@v4
- name: Setup Bitwarden session
env:
FNOX_AGE_KEY: ${{ secrets.FNOX_AGE_KEY }}
run: |
# Bootstrap session from fnox (if stored)
export BW_SESSION=$(fnox get BW_SESSION)
- name: Run tests
env:
BW_SESSION: ${{ secrets.BW_SESSION }} # Or set directly from GitHub Secrets
run: |
fnox exec -- npm testSession token management
The BW_SESSION value represents an unlocked vault session. If the session is no longer valid, unlock again and update the environment variable.
Option 1: unlock each time
#!/bin/bash
export BW_SESSION=$(bw unlock --raw)
fnox exec -- npm startOption 2: store encrypted (bootstrap)
# Store once
bw unlock --raw | fnox set BW_SESSION --provider age
# Use repeatedly
export BW_SESSION=$(fnox get BW_SESSION)
fnox exec -- npm startRefresh an unavailable session
If the vault is locked or the session is no longer usable, unlock it again:
export BW_SESSION=$(bw unlock --raw)Collections and organizations
Filter secrets by collection or organization:
[providers]
bitwarden = { type = "bitwarden", collection = "abc123-collection-id", organization_id = "org-id" }NB: This feature is supported only by the bw backend.
Get collection ID:
bw list collections | jq '.[] | {name, id}'Get organization ID:
bw list organizations | jq '.[] | {name, id}'Testing with Vaultwarden
For local development without a Bitwarden account:
# Start local vaultwarden server
source ./test/setup-bitwarden-test.sh
# Follow on-screen instructions:
# Create account at https://localhost:8080 (accept self-signed certificate)
# Login: export NODE_TLS_REJECT_UNAUTHORIZED=0 && bw login
# Unlock: export BW_SESSION=$(bw unlock --raw)
# Run tests
mise run test:bats -- test/bitwarden.batsSee the local testing guide for details.
Usage notes
The bw backend needs an unlocked vault session. A self-hosted Vaultwarden server uses the same reference formats. For machine credentials in Bitwarden Secrets Manager, use the separate bitwarden-sm provider.
Troubleshooting
"You are not logged in"
bw login"Vault is locked"
export BW_SESSION=$(bw unlock --raw)"Item not found"
Check the item exists:
bw list items | jq '.[] | {name, id}'"Session token expired"
Re-unlock:
export BW_SESSION=$(bw unlock --raw)Next steps
- 1Password - Commercial alternative
- OS Keychain - Local alternative
- Real-World Example - Complete setup