Skip to main content

Security architecture

Virtual keys are hashed

Only a SHA-256 digest is stored. The plaintext exists once, at reveal time. Key rotation or master-key rotation never invalidates them.

No master API key

There is no all-powerful bearer token on the gateway. Admin actions happen in the portal behind Entra ID SSO and role-based access control.

Provider secrets

Provider API keys are either:

  • AES-256-GCM encrypted at rest with ZEALLM_ENCRYPTION_KEY (format iv:tag:ciphertext, each base64), or
  • Azure Key Vault references (akv:<secret-name>) resolved at runtime with DefaultAzureCredential. Vault-referenced keys rotate by publishing a new secret version — no redeploy.

Invite-only portal

Sign-in is rejected unless the email is in ZEALLM_ADMIN_EMAILS or was invited under Users. All emails must match ZEALLM_ALLOWED_DOMAIN. Suspended users are rejected at sign-in.

Production hardening

  • AUTH_DEV_BYPASS must be false
  • TLS-terminate in front of :3000 and :8080
  • Do not publish Postgres on a host port
  • Keep Redis on the internal network (compose Redis has no password)
  • Portal mutation rate limits are in-memory — add Redis/edge limits before running multiple portal replicas

Encryption key

Never rotate ZEALLM_ENCRYPTION_KEY after credentials are stored except via the rotation runbook.