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

TypeCreationPurpose
UserOn registrationPersonal balance and signatures
ProjectOn project creationMain wallet (Management)
DepartmentOn department creationDepartmental budget

Key Rotation

Encryption keys are rotated periodically. When a key is rotated:

  1. 1. New master key is generated
  2. 2. All wallet keys are re-encrypted
  3. 3. Previous key is invalidated
  4. 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)