Key Management
How Polaris protects and manages wallet private keys.
Encrypted Keys
All private keys are stored encrypted with AES-256-GCM in Supabase. Not even the Polaris team can access them without the master key.
Custody Model
Polaris uses a managed custody model where:
- Secure generation
Keys are generated on the server using CSPRNG (Cryptographically Secure Pseudo-Random Number Generator)
- Immediate encryption
The private key is encrypted before touching any persistent storage
- Storage in Supabase
The encrypted key is saved with RLS so only the user/project has access
Storage Flow
// Key storage in Supabase (encrypted)
const encryptedKey = await encrypt(
companyPrivateKey,
POLARIS_MASTER_KEY,
{
algorithm: 'AES-256-GCM',
additionalData: companyId // Associated with company
}
)
// Saved in Supabase with RLS
await supabase.from('company_keys').insert({
company_id: companyId,
encrypted_key: encryptedKey,
key_version: 1,
created_at: new Date()
})Wallet Types
| Type | Creation | Purpose |
|---|---|---|
| User | On registration | Personal balance and signatures |
| Project | On project creation | Main wallet (Management) |
| Department | On department creation | Departmental budget |
Key Rotation
Encryption keys are rotated periodically. When a key is rotated:
- 1. New master key is generated
- 2. All wallet keys are re-encrypted
- 3. Previous key is invalidated
- 4. Rotation event is logged
Additional Security
- Keys are never transmitted in plain text
- TLS 1.3 for all communications
- Access logs with audit trail
- Environment separation (dev/staging/prod)