Documentation Index
Fetch the complete documentation index at: https://docs.vane.build/llms.txt
Use this file to discover all available pages before exploring further.
The problem
Each company’s Ed25519 private key is stored in a PostgreSQL database. Without envelope encryption, the private key is stored in plaintext — anyone with database read access can extract it and forge signatures. WithCOUNSEL_MASTER_KEY set, private keys are encrypted with AES-256-GCM before storage. The master key never touches the database.
How it works
At server startup, the master key is derived:COUNSEL_MASTER_KEY so the entropy is already adequate.
When a new company is registered and its key pair is generated, the private key is encrypted:
enc:v1: followed by colon-separated hex: IV, authentication tag, ciphertext. The version prefix enc:v1: allows future format changes.
When the key is loaded:
What this protects
- A database dump or backup will contain only ciphertext — useless without the master key.
- An attacker with read-only database access cannot forge signatures.
- An attacker with both database access AND the master key can forge signatures — this is why the master key must be stored separately from the database (different secret store, different infrastructure access path).
What this does NOT protect
- An attacker who compromises the Vane server process at runtime (the plaintext key is in memory while the server runs).
- Loss of the master key — you cannot decrypt existing private keys without it. Back it up.
- Key rotation — changing
COUNSEL_MASTER_KEYdoes not automatically re-encrypt existing keys. You would need to manually decrypt and re-encrypt each company’s key.
Backward compatibility
If a private key in the database is plaintext (i.e., it does not start withenc:v1:), it is used as-is. A warning is logged:
COUNSEL_MASTER_KEY is not set:
Generating a master key
COUNSEL_MASTER_KEY at runtime. Never commit it to version control.