Enforcement, not cooperation.
The proxy architecture.
Gate V2 governs agent writes if the agent calls the SDK. V3 closes that gap. A forward proxy, credential vault integration, and network-level enforcement that works regardless of whether the agent was written to cooperate.
— The problem with cooperative governance
V2 is opt-in. An agent that doesn't call gate.propose() writes directly to production. A retry loop that doesn't check for duplicate_blocked fires twice. A developer who ships fast skips the integration. Cooperative governance has holes.
V3 puts Gate in the path — not the application layer. The agent's HTTP call hits Gate's proxy first. Gate evaluates policy, holds or passes. The agent doesn't need to call the SDK. There's no path around it.
— Three deployment modes
Mode A — Forward proxy
One environment variable. Agent code unchanged. All outbound HTTP routes through Gate.
# Agent environment — no code change required
export HTTP_PROXY=http://gate.internal:4001
export HTTPS_PROXY=http://gate.internal:4001
# Gate intercepts every outbound call
# Destination host maps to policy via destination registry
# api.sendgrid.com → sendgrid.send → policy: outbound-email
Mode B — Reverse proxy
Gate deployed in front of specific APIs. Agent routes to Gate's URL instead of the destination directly. Works for services that ignore HTTP_PROXY.
# Agent calls Gate's reverse proxy URL
# Gate forwards approved requests to the real destination
POST https://gate.internal/sfdc/services/data/v58.0/sobjects/Contact
# Gate evaluates → approved → forwards to api.salesforce.com
POST https://gate.internal/sg/v3/mail/send
# Gate evaluates → pending → 202 returned, request held
Mode C — Credential vault
Gate holds no credentials itself. Credentials live in 1Password, HashiCorp Vault, or AWS Secrets Manager. Gate fetches them at execution time — after approval, for the approved intent only. The agent never touches production credentials.
# Vault config — Gate's 1Password service account
vault:
provider: 1password
config:
token_env: OP_SERVICE_ACCOUNT_TOKEN # one token for Gate
vault_name: AI-Agents # scoped vault, not all of org
credentials:
sendgrid.send:
ref: "op://AI-Agents/SendGrid/api_key"
inject: header
format: "Bearer {secret}"
salesforce.api:
ref: "op://AI-Agents/Salesforce/access_token"
inject: header
format: "Bearer {secret}"
stripe.charge:
ref: "op://AI-Agents/Stripe/secret_key"
inject: basic_auth # some APIs use basic auth
twilio.sms:
ref: "op://AI-Agents/Twilio/auth_token"
inject: query_param
— 1Password integration — how the auth handshake works
1Password Service Accounts issue JWT tokens scoped to specific vaults. Gate holds a single service account token. That token only has read access to the AI-Agents vault — not every credential in the organization.
── What happens at execution time ─────────────────────────
1. Intent approved (auto or human)
2. Gate looks up destination → "op://AI-Agents/Stripe/secret_key"
3. Gate SDK call → 1Password verifies service account JWT
4. 1Password returns credential (in-memory only, never logged)
5. Gate makes the API call with the credential
6. Credential discarded
── Two audit logs, one chain of custody ─────────────────────
1Password Activity Log:
gate-production accessed Stripe/secret_key at 14:22:11
Gate Audit Log:
execution_succeeded
intentId: int_6e5342…
credential: op://AI-Agents/Stripe (reference only)
executed_at: 14:22:11
Neither log can be forged independently. An attacker who compromises the agent process gets nothing — no credentials in memory, no direct path to 1Password, no way to trigger a Gate execution without an approved intent.
— Credential providers
— Build phases
# Start the proxy (PROXY_API_KEY enables it)
npx zehrava-gate --port 3001 --proxy-port 4001
# Route your agent through Gate — zero code change
export HTTP_PROXY=http://localhost:4001
# 1/ Auto-approved (under threshold) → proxied immediately
curl -x http://localhost:4001 -X POST http://api.sendgrid.com/v3/mail/send ...
→ forwarded to SendGrid
# 2/ Blocked (policy term match) → 403 immediately
curl -x http://localhost:4001 -X POST http://api.sendgrid.com/v3/mail/send -d '{"body":"Refund guaranteed within 24h"}'
→ {"status":"blocked","blockReason":"Payload contains blocked term: "refund guaranteed""}
# 3/ Pending (require_approval: always) → 202 + intentId
curl -x http://localhost:4001 -X POST http://api.stripe.com/v1/refunds -d '{"charge":"ch_xxx","amount":5000}'
→ {"status":"pending_approval","intentId":"int_b209…","retryAfterSeconds":30}
# 4/ After human approves at /dashboard → resend with intent header
curl -x http://localhost:4001 -H "X-Gate-Intent-Id: int_b209…" -X POST http://api.stripe.com/v1/refunds -d '{"charge":"ch_xxx","amount":5000}'
→ forwarded to Stripe (approved)
— What changes between V2 and V3
V2 and V3 share the same policy engine, audit trail, approval dashboard, and SDK. V3 adds the enforcement layer on top. V2 integrations keep working — the SDK is still the right choice for greenfield code where you control the agent. V3 is for everything else.
The one-line version of V3: 1Password handles custody. Gate handles authorization. An agent can't use a production credential without both systems agreeing.