Architecture
Fishnet is a local-first security proxy that sits between your AI agent and the outside world, enforcing security policies without ever sending your credentials or data to external servers.Core Design Principles
Local-First
Everything runs on your machine:- Single Rust Binary — No cloud dependencies, no external API calls for policy enforcement
- SQLite Storage — All data (audit logs, credentials, spend tracking) stored locally
- No Telemetry — Nothing leaves your machine unless your agent explicitly requests it
Proxy Model
Fishnet acts as a man-in-the-middle between your AI agent and external services:http://localhost:8473/proxy/openai/....
Request Flow
1. Agent Makes Request
The agent calls Fishnet’s localhost endpoint instead of the real service:2. Policy Enforcement
Fishnet intercepts the request and applies security policies:3. Credential Injection
If the request passes all checks, Fishnet:- Retrieves encrypted credentials from the vault
- Decrypts using the master password-derived key
- Injects the real API key into the request headers
- Forwards to the upstream service
vault.rs:560-568:
4. Audit Logging
Every decision (approved or denied) is logged in a tamper-proof Merkle tree:5. Response
The upstream response flows back through Fishnet to the agent, unchanged.Routing Architecture
Fishnet’s Axum router handles three types of routes (fromlib.rs:36-101):
Public Routes
Protected Routes
Proxy Routes
Data Flow Diagram
Storage Architecture
Fishnet uses SQLite databases for all persistent state:| Database | Purpose | Key Features |
|---|---|---|
vault.db | Encrypted credentials | AES-256-GCM encryption, Argon2id key derivation |
spend.db | Cost tracking, budgets | Daily/monthly limits, per-service tracking |
audit.db | Tamper-proof logs | Merkle tree, cryptographic hashes |
auth.db | User authentication | Bcrypt password hashing |
All databases are stored in
/var/lib/fishnet (Linux) or ~/Library/Application Support/Fishnet (macOS) by default.Security Boundaries
Trust Zones
Untrusted Zone (Your AI Agent)- Has no access to real credentials
- Can only call localhost proxy endpoints
- Cannot bypass Fishnet’s policies
- Holds encrypted credentials in memory
- Enforces all security policies
- Logs every decision
- Receives only approved requests
- Never sees Fishnet’s internal state
- Cannot influence policy decisions
Threat Model
Fishnet protects against:- Runaway agent loops — Spend caps prevent unlimited API usage
- Credential theft — Agent never sees real keys
- Policy bypass — All requests go through a single enforced choke point
- Log tampering — Merkle tree makes modifications detectable
- Compromised host OS — If your machine is compromised, Fishnet cannot help
- Malicious policy configuration — You must configure sane limits
- Physical access — Local SQLite files are encrypted at rest only if you use disk encryption
Performance Characteristics
Fishnet adds minimal latency to requests:
- Policy checks: < 1ms
- Credential decryption: < 5ms
- Audit logging: < 10ms (async)
Next Steps
Credential Vault
Learn how credentials are encrypted and stored
Spend Limits
Understand budget enforcement and cost tracking
Rate Limiting
See how request throttling works
Audit Trail
Explore tamper-proof logging with Merkle trees