Mellow LogoMellow

Data Protection

How Mellow encrypts and stores your data.

Data protection

Encryption at rest

Sensitive fields are encrypted per field before they are written to the database:

  • Algorithm: AES-256-GCM (16-byte IV, 16-byte authentication tag).
  • Key derivation: PBKDF2-HMAC-SHA512, 10,000 iterations, 32-byte key, from ENCRYPTION_KEY and each salt in ENCRYPTION_SALT_LIST (default salt mellow-encryption-salt).
  • Key rotation: multiple salts can be listed; writes use the first key, reads try every derived key, so an old salt can be kept for decryption while a new one takes over writes.
  • Stored format: base64(iv):16:base64(tag):base64(ciphertext).
  • Layered payloads: decryption unwraps up to five nested layers, in case a value was encrypted more than once during a migration.

If ENCRYPTION_KEY is unset, encryption is disabled and values are stored as plain text - only appropriate for local development.

Encrypted fields

  • ConversationHistory.content
  • MoodCheckIn.note, MoodCheckIn.activity, MoodCheckIn.mood
  • GhostLetter.content
  • JournalEntry.content
  • GratitudeEntry.item
  • CopingPlan.plan
  • CrisisEvent.details
  • Feedback.message, Report.message (and their reply tables' message)

Non-sensitive fields (IDs, timestamps, enum values, counts, settings) are stored in the clear so the app can query them.

In transit

  • Discord gateway and REST: TLS.
  • Anthropic API: TLS.
  • Database: set sslmode=require in DATABASE_URL for a remote database (disable is only for a local socket).
  • HTTP API: terminate TLS at your reverse proxy or platform.

Storage

  • PostgreSQL via pgx/pgxpool.
  • Schema is managed with versioned migrations (golang-migrate), embedded in the binary and applied on startup. Migrations are guarded so they are safe to run against an existing database.
  • Queries are generated with sqlc; there is no ORM.

What Mellow does not collect

  • No real names, addresses, or phone numbers.
  • No payment or financial data.
  • No biometric data.
  • No precise location. Timezone is stored only if you set it, and only to adjust tone and reminder timing.

Access

  • User data is returned only to the user who created it.
  • Per-guild settings and logs are visible only to that server's administrators.
  • Owner-only commands (mellow, user, guild, debug, tools, feedback-manage, report-manage, changelog) are registered to PRIVATE_GUILD_ID and gated to the IDs in OWNER_IDS.

Reporting a vulnerability

Email [email protected] or open a private advisory on the GitHub repository. Please do not open a public issue for security problems.

On this page