GUIDE · COMPARISON 10 min ·

Bitwarden Secrets Manager for AI coding agentsWhat bws run protects, and what it doesn't

Bitwarden Secrets Manager now has an agent-native on-ramp, and the bws run model is a real improvement over a plaintext .env. The catch is where the bootstrap token lives and what the agent can do with the secrets after they land in its environment.

TL;DR· the answer, in twenty seconds

What: Bitwarden Secrets Manager ships a bws CLI with a bws run command that injects secrets as environment variables, authenticated by a machine-account access token. On May 22, 2026, Nous Research wired it into Hermes Agent so a self-hosted agent pulls its keys at startup instead of reading a .env file.

Pick: Good fit if you already use Bitwarden, want read-only per-project machine accounts, and can pay the Teams tier for audit logs. The free tier gives you three machine accounts and no audit trail. Self-hosting is Enterprise-only.

Lesson: The model moves secret-zero from a .env file to a single access token in the agent's environment. That is a smaller blast radius, not zero. Once bws run injects the values, the agent can still read them, write them, and pass them in a tool call.

On May 22, 2026, Nous Research shipped Bitwarden Secrets Manager support in Hermes Agent, so a self-hosted coding agent pulls its API keys from a vault at startup instead of reading them out of a .env file. Nous posted the integration that day, and Bitwarden replied "Here's to Security for All, agents included." That makes Bitwarden the latest secrets manager to get an agent-native on-ramp, and it raises a fair question: is Bitwarden Secrets Manager a good fit for an AI coding agent, and where does it leave you exposed?

The short version: the bws run model is a real improvement over ambient .env files, the machine-account primitive gives you better scoping than a single flat API token, and the whole thing still rests on one bootstrap credential that lives in the agent's environment.

What bws actually does

Bitwarden Secrets Manager is a separate product from the password manager, with its own CLI called bws. You install it from the sdk-sm releases page or run it from a container with docker run --rm -it ghcr.io/bitwarden/bws. The data model has three nouns: secrets (key/value pairs), projects (folders that group secrets), and machine accounts (non-human identities that hold scoped access).

A machine account authenticates with an access token. The token format starts with 0. and carries a client identifier and an encryption key. Bitwarden does not store the token in its database, so once you create it you cannot retrieve it. You either save it or regenerate it.

The token reaches the CLI two ways:

# As an environment variable
export BWS_ACCESS_TOKEN=0.48c78342-1635-48a6-accd-afbe01336365.C0tMmQqHnAp1h0gL8bngprlPOYutt0:B3h5D+YgLvFiQhWkIq6Bow==

# Or inline per command
bws secret list --access-token 0.48c78342-...

The command that matters for agents is bws run. It pulls every secret the machine account can read and injects them as environment variables into a child process:

bws run --project-id 7b006643-89c1-4202-a5ca-90510f566030 -- node server.js

By default the secret's name becomes the variable name. Pass --uuids-as-keynames if you want POSIX-safe identifiers instead. The --project-id flag scopes the pull to one project, which is the lever you use to keep an agent from receiving secrets it has no business touching. This is the same surface shape as doppler run, infisical run, and op run. The injection mechanics converged years ago. The differences are in the auth model behind the command.

How the Hermes integration wires up

Hermes does not call a Bitwarden API directly. It shells out to bws. At startup, after ~/.hermes/.env loads, Hermes runs bws secret list <project_id> and sets the returned keys into the process environment. The setup is a short wizard:

hermes secrets bitwarden setup   # prompts for token, region, project
hermes secrets bitwarden status  # confirms the integration is live

The wizard writes config into config.yaml:

secrets:
  bitwarden:
    enabled: true
    project_id: 7b006643-89c1-4202-a5ca-90510f566030
    access_token_env: BWS_ACCESS_TOKEN
    override_existing: true

The bootstrap access token lives in ~/.hermes/.env under the key named by access_token_env. With override_existing: true, Bitwarden is the source of truth: rotate a key once in the web app and every Hermes process picks up the new value on its next start. Set it to false and a local .env value wins over the vault.

The payoff is real. One bootstrap token in ~/.hermes/.env replaces the pile of provider keys that used to sit there in plaintext: OPENROUTER_API_KEY, ANTHROPIC_API_KEY, and the rest move into the vault, and rotation becomes one edit in the web app instead of a sweep across every machine. For a fleet of self-hosted agents, that is a meaningful drop in the number of places a live key sits at rest.

Where secret-zero moves

It does not disappear. It moves.

Before the integration, the agent's ~/.hermes/.env held N provider keys in plaintext. After it, the same file holds one BWS_ACCESS_TOKEN. That token unlocks every secret the machine account can read. If an agent can read ~/.hermes/.env, run printenv, or cat a dotenv file, it can read the token, and the token is the key to the vault project.

This is the failure mode Bitwarden itself documents. Their April 2026 post, your coding agent can read your .env file, walks through an agent that hits an auth error and reasons its way to cat .env, printenv, or grep -r "API_KEY" to fix itself. Their words: "the dev environment is saturated with secrets, and any sufficiently capable agent operating in that environment has access to them." Moving the provider keys into the vault shrinks that saturation. It does not remove the one credential that the agent still needs in its environment to talk to the vault.

The mitigation Bitwarden recommends is the right one, and it is not the default: create an individual machine account per project, grant it read-only, and set an expiration date on the token. A read-only, project-scoped token is a smaller prize than a flat DOPPLER_TOKEN that unlocks an entire config. It is still an ambient credential with a lifetime measured in days or weeks, not in the duration of a single bws run.

Audit, tiers, and what the free plan omits

Pricing moves, so treat these as calibration rather than a quote. As of writing, the Secrets Manager plans split into three tiers. The Free plan gives you unlimited secrets but caps you at two users, three projects, three machine accounts, and no audit log. Teams runs around $6 a seat and adds unlimited projects, 20 machine accounts, and the audit log. Enterprise runs around $12 a seat and adds 50 machine accounts, self-hosting, event logs, SSO, and SCIM.

The audit log is the line that should drive the decision for any team doing this for compliance reasons. It records secret access, logins, and administrative changes with timestamps, and exports to CSV or a SIEM. It is a Teams-tier feature. On the free plan you get scoped access and no record of who read what. For a solo developer that is acceptable. For anyone who needs to answer "did the agent pull the production key on Tuesday," the free tier cannot.

Self-hosting is Enterprise-only. You can run Secrets Manager alongside an existing self-hosted Bitwarden install, but the entry price is the Enterprise plan. That contrasts with Infisical, where the MIT-licensed core self-hosts from the public repo, and with HashiCorp Vault and its OpenBao fork, where self-hosting is the default deployment.

License: source-available, not open source

Bitwarden's password manager clients are GPLv3. People assume the rest of the company follows, and for Secrets Manager that assumption is wrong. The Secrets Manager server code and the SDK that bws builds on live in the bitwarden_license directory of the public repos. That code is covered by the Bitwarden License Agreement, not the GPL. You can read it and audit it. You cannot fork it and run a competing service, and you cannot self-host it outside the terms of a paid Enterprise plan.

For a tool that sits on your most sensitive data, the distinction is worth reading before you commit. Source-available means you can inspect the code path that touches your secrets, which is more than 1Password or Doppler offer. It does not give you the fork-and-run escape hatch that an OSI-approved license would if Bitwarden changed its pricing or got acquired. If that escape hatch is a hard requirement, Infisical's MIT core or a Vault/OpenBao deployment fits better.

The matrix

Feature Bitwarden SM Doppler Infisical hasp
Install Release binary / Docker brew / curl brew / curl curl install script
Secret-zero Machine-account access token DOPPLER_TOKEN Machine identity / token Local passphrase (Argon2id)
Run command bws run doppler run infisical run hasp run
Injection Env var (project-scoped) Env var (full config) Env var (full config) Env var or temp file (0600)
Per-agent scoping Read-only per project Config-level Secret-level RBAC (paid) Per-profile, per-session
Audit log Teams tier and up Paid tier Paid or self-hosted Local HMAC-chained
Self-host Enterprise only No Yes (MIT core) N/A (no server)
Offline No No Partial (self-hosted) Yes
Cost (free tier) 3 machine accounts, no audit Free tier, basic Free tier Free
License Bitwarden License (source-available) Proprietary MIT core + commercial FCL-1.0

How it fails AI agents specifically

The marketing does not write this section, so here it is.

The bootstrap token is an ambient credential. bws run and the Hermes integration both need BWS_ACCESS_TOKEN present in the environment before they can talk to the vault. That token sits in ~/.hermes/.env or in the shell, in the same place the agent already knows how to look. You have replaced many secrets with one secret, which is progress, but the one that remains is the one that unlocks the rest.

Injection ends at the process boundary, and the agent lives inside it. After bws run exports the project's secrets, they are plain environment variables in a process the agent controls. The agent can printenv them, write them to a file, or hand them to a tool call. Project scoping limits which secrets land in the environment. It does not constrain what happens to them once they do. This is the same shape that produced the Knostic disclosures earlier in 2026, where agent state files captured environment data from sessions.

Token lifetime is coarse. You can set an expiration date on a machine-account token, and you should. What you cannot do is mint a token that is valid for exactly one bws run invocation and dies when the child process exits. The expiry is measured in calendar time, so a leaked token stays live until the date you picked, regardless of whether the agent session that used it ended hours ago.

The audit log answers the wrong granularity. Teams-tier logging records that the machine account pulled secrets at 14:32. It does not record which subprocess inside a long-running agent session consumed which value, or what the agent did with it afterward. For a forensic question about an agent that spawned forty subprocesses over six hours, the log gives you one line: the machine account read the project. The rest is gone.

override_existing: true trusts the vault as the source of truth, which is correct for rotation and a small attack surface if the vault project is ever poisoned. Anyone who can write to the project can change a value that every agent then loads on next start. Read-only machine accounts for the agents handle the read side. Lock down who holds write access to the project with the same care.

Who should actually use it

Already on Bitwarden, solo or small team: the free tier with three machine accounts and project scoping is a clean upgrade from a .env, and one vault now covers your passwords and your agent's secrets. Accept that there is no audit log at this tier.

Team that needs an audit trail: budget for Teams at roughly $6 a seat. The audit log is the feature you are paying for, and it is the one a compliance reviewer will ask about.

Team that needs self-hosting: Enterprise, or look at Infisical's MIT core or an OpenBao deployment instead. Bitwarden gates self-hosting behind the top tier and the Bitwarden License.

Running unattended agents like Hermes: scope a read-only machine account per project, set a token expiration date, and keep the bootstrap token out of the dotenv the agent already reads. None of that is on by default, and none of it changes the fact that the token in the agent's environment is the credential an attacker wants.

What this means for your stack

The minimum action is to stop letting an agent inherit a .env full of live keys. Moving provider secrets into a vault and injecting them at startup with a scoped, read-only machine account is a genuine reduction in how many credentials sit at rest in your dev environment. Any of the run-style tools does this, and Bitwarden's per-project machine account is a better scoping primitive than a single flat token.

The pattern that fixes the category is per-session credential brokering: a credential that is scoped to one process tree, expires when that process exits, and leaves an audit record tied to the specific invocation rather than to a long-lived machine identity. Bitwarden's access tokens are scoped by project and expire by calendar date, which is closer to that pattern than a static API key but short of process-scoped.

hasp is one working implementation of process-scoped brokering: a local vault with Argon2id encryption, per-profile grants with a 24-hour ceiling, env-var or temp-file injection into a bounded process tree, and an HMAC-chained audit log. Install with the one-line script, run setup, point it at a project, and the next agent session gets a reference instead of a key. Source-available (FCL-1.0), local-first, macOS and Linux, no account.

Bitwarden Secrets Manager is a sound choice if you already live in Bitwarden and you treat the bootstrap token with the seriousness it deserves. The decision between it and an agent-native broker comes down to whether project-scoped, calendar-expiring tokens are tight enough for the way your agents actually run, or whether you need the grant to die with the process that used it.

Sources· cited above, in one place

NEXT STEP~90 seconds

Stop handing the agent your real keys.

hasp keeps secrets in one local encrypted vault, brokers them into the child process at exec, and never lets the agent read the value.

  • Local, encrypted vault — no account, no cloud, no telemetry by default.
  • Brokered run — agent gets a reference, the child process gets the value.
  • Pre-commit + pre-push hooks catch managed values before they ship.
  • Append-only HMAC audit log answers "did the agent touch the prod token?" in seconds.
→ okvault unlocked · binding ./api
→ okgrant once · pid 88421
→ okagent never read

macOS & Linux. Source-available (FCL-1.0, converts to Apache 2.0). No account.

Browse all clusters· eight threads, one index