← Security overview

Security Practices

Technical and organisational controls that protect platform data and customer workloads at ZelixAI.

🔐
Section 1

Encryption at rest

Sensitive fields stored in the platform database are encrypted using AES-256-GCM before being written to disk.

What How
Account API keys (Anthropic, OpenAI-compat., SMTP) AES-256-GCM, MASTER_ENCRYPTION_KEY
User password hashes bcrypt (cost 12)
IMAP / email channel credentials AES-256-GCM, MASTER_ENCRYPTION_KEY
Database files on disk Sensitive fields are encrypted at the application layer before storage (AES-256-GCM, per-account AAD, keys in HashiCorp Vault).
🟢

The MASTER_ENCRYPTION_KEY is injected via the server environment at boot time and is never written to the codebase or database. Sensitive data is encrypted with AES-256-GCM using per-account additional authenticated data; key rotation requires a re-encryption run.

🔓
Section 2

Encryption in transit

  • All public endpoints served over HTTPS only; HTTP is redirected to HTTPS (Apache HSTS header).
  • Supported TLS versions: TLS 1.2 and 1.3 (TLS 1.0 / 1.1 disabled).
  • Widget widget.js is served with Access-Control-Allow-Origin: * but the chat API endpoints validate widget_key + origin allowlist.
  • Internal service calls (Redis, MySQL on localhost) communicate over the loopback interface. No data leaves the host unencrypted.
💾
Section 3

Backups

The following backup schedule applies to the platform database and account databases:

Item Frequency Retention Location
Platform DB (einstein_saas_platform) Daily, overnight (UTC, automated) 7 days locally; encrypted copy in France for up to 3 weeks Local volume + encrypted offsite replica
Account DBs (einstein_saas_tenant_*) Daily, overnight (UTC, automated) 7 days locally; encrypted copy in France for up to 3 weeks Local volume + encrypted offsite replica
Uploaded files / document store Daily, overnight (UTC, automated) Encrypted copy in France, about one month Local volume + encrypted offsite replica

Backups run per database via mysqldump --single-transaction, are stored compressed and age-encrypted, copied daily, encrypted again, to a datacenter in France, in a different place from our servers, and every run is checked for a non-empty dump and logged with success/failure status.

Backup archives are encrypted at rest with age (X25519 / ChaCha20-Poly1305); the decryption key is held separately from the archives. Fields protected with column-level encryption (AES-256-GCM) stay encrypted inside every archive. Recoverability is verified by an automated monthly restore-test.

👥
Section 4

Access control

4.1 Role-based access control (RBAC)

Every portal user is assigned a role. Roles carry separate permissions per area. The platform checks permissions server-side.

4.2 Two-factor authentication

  • 2FA via an authenticator app (TOTP, RFC 6238 — for example Google Authenticator or Authy) or via a code by email. Each user turns it on in their account settings.
  • When 2FA is on, the platform asks for the second step at every login.
  • There are no recovery codes. Users who choose the code by email do not need a separate app.

4.3 Account isolation

Authentication requires an account context (slug-based login). Session tokens are scoped to a single account. Cross-account resource access is prevented at the application layer by mandatory tenant_id filters in the database queries.

📋
Section 5

Audit logging

Significant actions performed on platform resources are recorded in the audit_log table (platform database). Each entry captures:

  • Actor: user ID, role and tenant ID.
  • Action: verb (create, update, delete, login, export, …).
  • Resource: entity type and ID.
  • Metadata: changed field names and old/new values (sensitive fields redacted).
  • Timestamp: stored in UTC (ISO 8601).
  • IP address: source IP from the request.

Audit log entries are kept for two years and then deleted automatically, also if the account ended earlier. Proof that an erasure request was carried out is deleted automatically after 12 months. The log is append-only at the application level.

Audit entries are written by the application's regular database user. A separate insert-only database user is set up only for the audit log of the reseller API.

🛡
Section 6

Vulnerability management

6.1 CVE monitoring

We check Composer dependencies with composer audit. Critical vulnerabilities in runtime dependencies are handled with priority.

6.2 Patch cycle

  • OS security updates: installed automatically every day (unattended-upgrades).
  • PHP runtime: PHP 8.5, kept up to date with security updates.
  • Web server: Apache 2.4.x — kept up to date with distribution security updates.

6.3 Responsible disclosure

External security researchers are invited to report vulnerabilities under our coordinated disclosure policy. Read the responsible disclosure policy →

🏢
Section 7

Hosting & infrastructure

Component Detail
Hosting region EU — Netherlands (database), France (files and backups)
Web server Apache 2.4 (mod_rewrite, mod_ssl)
Runtime PHP 8.5
Database MySQL / MariaDB (platform + per-tenant)
Cache / sessions Redis (loopback, password-protected)
Cross-border data transfers AI processing can take place outside the EU, for example in the United States, unless EU-only is on (from Plus). We will tell you which AI providers we use on request.

Need a completed security questionnaire?

Do you have a security questionnaire? Send it to our security team.

Contact security team →