Security

This page details the technical and organizational measures in place to protect your data. It complements the Privacy Policy and the Data Processing Agreement (DPA).

Architecture

Multi-tenant isolation

Each customer company (tenant) is strictly isolated from the others at the database level:

  • PostgreSQL Row Level Security enabled on every table containing tenant_id. Policies use a current_tenant_id() function that reads a session variable.
  • Every server-side query goes through a withTenant(tenantId, ...) helper that opens a transaction and sets the session variable BEFORE the query. No cross-tenant query is possible.
  • The API helpers (withTenantApi) combine session check + role check + tenant scope. It's the mandatory pattern for every business route.

Authentication

  • NextAuth.js v5 with Google SSO and single-use magic links for invited new hires.
  • No standard Prisma adapter, because our multi-tenant model requires a tenant_id + email resolution (email alone is not unique across tenants).
  • Signed JWT tokens, 30-day rotation.
  • Soft delete: a deleted user is anonymized and can no longer sign in, across all auth paths (SSO, Credentials, magic link).

Encryption

In transit

  • TLS 1.3 mandatory on all HTTPS connections.
  • Strict HSTS.

At rest

  • AES-256 native on Supabase and Vercel (disk).

Application level (AI conversations)

Messages exchanged with the AI Companion assistant are encrypted at the application level before being stored in the database:

  • AES-256-GCM algorithm with a random 12-byte IV and a 16-byte authentication tag.
  • Per-tenant key derived via HKDF-SHA256 from a master key (environment variable, never committed).
  • Stored format: base64 of a [version | iv | authTag | ciphertext] payload. The version byte allows future rotation without a table migration.
  • Rolling read: older unencrypted (legacy) messages are read as-is until the full backfill is complete.
  • Important consequence: losing the master key makes encrypted conversations unrecoverable. That is the strong confidentiality guarantee we provide to our customers.

Audit log

An immutable audit_logs table traces 14 sensitive actions:

  • New-hire creation / modification / deletion
  • Alert resolution
  • AI persona modification
  • Journey publishing / modification
  • Tenant settings modification
  • Badge creation / deletion
  • 360° feedback submission
  • Offboarding start
  • GDPR export (Art. 20) with per-section counters
  • GDPR deletion (Art. 17) with an email/role snapshot BEFORE anonymization

Each entry captures: action, entity type, ID, minimal payload, IP, user-agent, timestamp.

Rate limiting

  • AI chat: rate-limited per user and per hour (sliding window over the chat_messages table). No external Redis — the database naturally enforces the limit with a (conversation_id, created_at) index.
  • AI journey generation: limited by the plan's Premium quota.

Backups and recovery

  • PITR (Point-In-Time Recovery) on Supabase: 7 days.
  • Daily snapshots.
  • Restore tested quarterly.

GDPR

  • Article 15 (access) and Article 20 (portability): full JSON export in one click via the HR interface.
  • Article 17 (erasure): soft delete + immediate anonymization of PII. Neighboring data (chat, audit) becomes anonymous by derivation. No recovery possible — this is compliant and intentional.
  • Article 33 (breach notification): contractual commitment to notify within 72 hours (see DPA § 6.5).
  • Exhaustive list of subprocessors with their DPAs: /en/legal/sous-traitants.

Hosting

  • Database: Supabase, EU Central 1 (Frankfurt, Germany) region.
  • Web application: Vercel, EU West (Frankfurt) region.
  • Transactional emails: Resend (US transit).
  • Transfers to AI providers (Anthropic, OpenAI — United States) are governed by Standard Contractual Clauses and our additional clauses.

Reporting and contact

To report a vulnerability: security@weloom.ai. We commit to acknowledging receipt within 48 business hours and coordinating responsible disclosure.

For any security or GDPR question: dpo@weloom.ai.