Credential Vault
The Credential Vault is Fishnet’s encrypted storage system for API keys and secrets. Your AI agent never sees the real credentials — only Fishnet can decrypt them.How It Works
Master Password
On first launch, you set a master password. This password is used to derive an encryption key that protects all stored credentials.Key Derivation
Fishnet uses Argon2id (the state-of-the-art key derivation function) to derive a 256-bit encryption key from your master password. Fromvault.rs:394-411:
- Memory cost: 256 MB — Makes brute-force attacks expensive
- Time cost: 3 iterations — Balances security and speed
- Algorithm: Argon2id — Resistant to GPU/ASIC attacks
Encryption
Credentials are encrypted using XSalsa20-Poly1305 (libsodium’scrypto_secretbox) with:
- 256-bit key derived from your master password
- 192-bit nonce generated randomly per credential
- 128-bit authentication tag to detect tampering
vault.rs:318-336:
Decryption
When the proxy needs a credential, it:- Retrieves the ciphertext and nonce from SQLite
- Decrypts using the master key
- Returns the plaintext API key (in memory only)
- The key is automatically zeroized when dropped
vault.rs:532-569:
Decrypted keys are stored in
Zeroizing<String>, which overwrites memory with zeros when the value is dropped, preventing sensitive data from lingering in RAM.Database Schema
Credentials are stored invault.db with this schema:
Vault Metadata
Two special metadata entries are stored:| Key | Purpose |
|---|---|
salt | Random 16-byte salt for Argon2id |
canary | Encrypted test value to validate master password |
Password Validation
The canary is a known plaintext ("fishnet-vault-canary-v1") encrypted with your derived key.
When you unlock the vault:
- Fishnet decrypts the canary
- If decryption fails or plaintext doesn’t match, password is invalid
- If it matches, your password is correct and vault is unlocked
vault.rs:414-446:
Memory Protection
Fishnet usesmlock(2) to pin sensitive memory pages to RAM, preventing them from being swapped to disk.
From vault.rs:77-88:
mlock requires elevated privileges on some systems. If it fails, Fishnet logs a warning but continues (you can set FISHNET_VAULT_REQUIRE_MLOCK=1 to make it mandatory).Storage Location
The vault database is stored at:- Linux:
/var/lib/fishnet/vault.db - macOS:
/Library/Application Support/Fishnet/vault.db - Custom: Set
FISHNET_DATA_DIRenvironment variable
Adding Credentials
Via Dashboard
- Navigate to Settings → Credentials
- Click Add Credential
- Enter:
- Service (e.g.,
openai,anthropic,custom.github) - Name (e.g.,
production,backup) - API Key
- Service (e.g.,
Via API
Fromvault.rs:680-710:
Credential Lookup
When the proxy handles a request to/proxy/openai/..., it looks up the credential by service name:
From vault.rs:532-569:
- Most recently created credential for that service
- If multiple credentials exist, you can query by
(service, name)
Security Guarantees
Encryption at Rest
Encryption at Rest
All credentials are encrypted with XSalsa20-Poly1305 before touching disk. The SQLite database contains only ciphertext.
Memory Protection
Memory Protection
- Derived keys are locked with
mlock(2)to prevent swapping - Decrypted credentials use
Zeroizing<String>to overwrite memory on drop - Sensitive types like
DecryptedCredentialare!Copy,!Clone,!Debug,!Serialize
No Plaintext Storage
No Plaintext Storage
The master password is never stored. The SQLite database contains:
- Encrypted credentials
- Random nonces
- Metadata (salt, canary)
Tamper Detection
Tamper Detection
Each credential includes a Poly1305 MAC. Any modification to the ciphertext will cause decryption to fail.
Recovery
If you lose your master password, there is no recovery mechanism. This is by design. Best practices:- Store your master password in a password manager
- Keep encrypted backups of
vault.db(useless without the password) - Use environment variables for non-production keys during testing
Keychain Integration
Fishnet does not currently integrate with OS keychains (macOS Keychain, Windows Credential Manager, Linux Secret Service). This is a planned feature.
Performance
- Vault unlock (Argon2id derivation): ~100-300ms (intentionally slow)
- Credential retrieval: < 5ms (cached key, SQLite lookup)
- Encryption/Decryption: < 1ms per credential
Next Steps
Spend Limits
Learn how Fishnet enforces daily budgets
Rate Limiting
See how request throttling protects against runaway agents