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.
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.
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.
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.
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.
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 →
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. |