AtelyaOS Docs
Security

Encryption

Sensitive fields are encrypted at rest with libsodium authenticated encryption. Transport is TLS 1.2+.

Encryption

libsodium secretbox for sensitive fields at rest. TLS 1.2+ on the wire.

The 30-second version

Sensitive application data — message content, OAuth tokens, integration credentials, MCP client secrets — is encrypted at rest using libsodium secretbox (XSalsa20-Poly1305 authenticated encryption) with a per-record nonce. The encryption key is derived per workspace from a master key supplied via environment variable. Database transport and browser transport both use TLS 1.2+. KMS / Supabase Vault for the master key is on the roadmap.

Why this matters

"At rest encryption" is meaningless if it just means the underlying disk is encrypted by the cloud provider. AtelyaOS does application-level encryption on top of Supabase's infrastructure encryption: the bytes stored in Postgres for sensitive fields are ciphertext, not plaintext. Reading the database row gives an attacker nothing useful unless they also have the workspace's derived key.

This matters most for OAuth tokens (Notion, Google, Slack, Meta) and message content. Both are common attack targets and both are encrypted under our scheme.

How it works

Algorithm

Authenticated encryption with libsodium's secretbox:

  • Cipher: XSalsa20 (256-bit key).
  • MAC: Poly1305 (authentication).
  • Nonce: per record, 24 bytes, from a CSPRNG.

Ciphertext layout: [nonce || box(plaintext, key, nonce)]. This is the construction behind Signal's storage layer — authenticated, side-channel resistant, designed for at-rest use.

Key derivation

Per-record keys are derived from a workspace key, which is derived from a master key:

master_key  → workspace_key  → record_key (HKDF-style derivation)

The workspace derivation uses HMAC-SHA256 over a workspace identifier. Re-derivation is deterministic, so we don't need to store derived keys.

The master key today comes from the ENCRYPTION_MASTER_KEY environment variable. Production deployments rotate the env var separately from application config. Migration to Supabase Vault or an external KMS (AWS KMS / GCP KMS) is on the roadmap.

What's encrypted

Application-level encryption applies to:

DataWhere stored
Message contentmessages.content_encrypted
Notion / Google / Slack tokensintegrations.access_token_encrypted
Custom webhook API keyswebhook_bridges.api_key_encrypted
MCP client credentialsmcp_servers config columns (encrypted)
WhatsApp tokenswhatsapp_accounts token columns
Cross-bot payloadsA2A inbox payload column
Meta OAuth tokensintegrations Meta token columns

Standard database fields that are not high-risk (workroom titles, agent names, role descriptions) are stored as plaintext.

What's not encrypted at the application layer

  • Workroom titles, goals, deliverable labels.
  • Agent names, role descriptions, system prompts.
  • Usernames, workspace name, plan tier.
  • Activity-log entries.

These rely on Supabase disk-level encryption and row-level access control. They are not enciphered with secretbox.

Transport encryption

  • Browser ↔ AtelyaOS: TLS, enforced by the host.
  • AtelyaOS ↔ Supabase: TLS, enforced by Supabase.
  • AtelyaOS ↔ Anthropic / LLM providers: TLS, enforced by the SDK.
  • AtelyaOS ↔ third-party integrations: TLS, enforced by each provider's API.

Minimum supported TLS version is 1.2.

Key rotation

Rotation of the master key is a coordinated operation: re-encrypt affected rows with a derived key from the new master key. The runbook lives in the operational docs (engineering-only). The rotation does not require downtime.

Limitations to be aware of

  • The master key is currently env-managed, not Vault/KMS-managed. This is a stepping-stone implementation; KMS migration is roadmap.
  • PII in plaintext fields: workroom goals can contain client names. If you don't want client names appearing in plaintext fields, redact them in the goal and put specifics in a paste block instead.
  • DSAR exports: include encrypted blobs as ciphertext, not as decrypted plaintext. See data handling.

Common pitfalls

  • Pasting a credential into a workroom goal. Goals are stored plaintext. Don't put API keys, passwords, or PII into the goal field — use the paste blocks (which contain encrypted message content) and only the parts you actually need.
  • Assuming everything is encrypted. Workroom titles, agent names, and audit log entries are not under secretbox. If you need application-level encryption for those, talk to sales (Enterprise tier).
  • Confusing transport encryption with at-rest encryption. TLS doesn't help once data is sitting in the database. The application-level encryption above is what protects rows at rest.
  • Treating env-var key management as KMS-equivalent. It isn't. KMS is on the roadmap; for the strictest threat models, this is a known gap.

What's next

On this page