Tablemere — Security overview
Version: 2026-09-19-draft
Factual description of the Service as deployed on this date. Not a contract; the contractual measures are Annex II of the Data Processing Agreement. Questions and vulnerability reports: [security@ address].
DRAFT for lawyer review. See
legal/README.md.
What Tablemere is
A managed Apache Iceberg lakehouse: the Iceberg REST catalog and the S3-compatible object store are one system, run by us on Hetzner servers in Germany. Your data is Iceberg tables and plain objects in open formats; you can take it elsewhere with standard tools at any time.
Who operates it, and where
Everything runs in Germany (Nuremberg for compute and block storage, Falkenstein for backup object storage) on infrastructure from Hetzner Online GmbH. Transactional email is sent through Scaleway SAS in Paris. Our own company mailboxes are at Infomaniak in Switzerland (adequacy decision). No US-controlled company operates any part of the Service or holds your data, and no managed service from a US provider sits in the data path. The open-source software we run (SeaweedFS, Apache Iceberg, Caddy, Rauthy) is operated by us, on our servers, under our control.
Isolation between customers
- Each warehouse is a separate catalog and a separate bucket with its own storage identity.
- The only grant is a bucket policy naming that identity, enforced by the catalog and the object store, not by our application code. A credential for one warehouse cannot list, read or write another.
- Table buckets accept only Iceberg files in the Iceberg layout; anything else goes to the separate blob bucket that accompanies your warehouse.
- Isolation is checked with positive and negative controls in the automated test suite on every deployment, using the same key shape for both (a lesson we learned early and documented).
Credentials
- API keys: 256-bit random secret, shown once, stored only as a SHA-256 hash, compared in constant time. You can list and revoke them (
GET/DELETE /v1/api-keys). - API tokens: RS256 JWTs, 15 minutes.
- Storage credentials: vended by the catalog per table or warehouse, 60 minutes (raised from 15 on 2026-09-19 so Snowflake accepts them), signed with a key we can rotate to revoke every outstanding session at once.
- Sign-in: email one-time code (hashed, 10 minutes, 5 attempts) for signup and key recovery; an optional self-hosted OpenID Connect provider with passkeys. We store no passwords in the control plane.
- Failed credential attempts are rate-limited per key and address; a correct key is never locked out.
Encryption
- In transit: TLS 1.2/1.3 only on every public hostname, Let's Encrypt certificates renewed automatically, HSTS, no version disclosure; S3 requests are additionally SigV4-signed.
- At rest: see "Not yet done". We do not currently claim encryption at rest for customer content or for tenant secrets.
The host
One server. Only ports 80 and 443 are open to the internet; SSH is key-only from a single allow-listed address; every storage, catalog and administration port is internal. Internal control-plane endpoints are not served publicly. Security updates install automatically. An independent read-only audit of the deployment, with every finding and its status, is kept in our repository and re-run after each deploy.
Backups and restore
- Daily at 03:17 UTC: the complete state (data volumes, catalog store, configuration, keys, control-plane database), checksummed.
- 7 copies on the host, 14 copies off-host in Hetzner Object Storage in Falkenstein; every off-host copy is downloaded again and its checksum verified after upload.
- Restore is rehearsed, not assumed: on 2026-09-19 a backup was restored onto a fresh second server and an existing customer key worked against it. The procedure is scripted and re-runnable.
- Consequence for you: a deleted record leaves every backup within 14 days; a catastrophic loss could lose up to one day of writes; we cannot yet restore a single table on request.
Rotation
Every long-lived key has a scripted, rehearsed rotation with measured revocation:
| key | who runs it | what it revokes, measured |
|---|---|---|
| your warehouse key pair | you, POST /v1/warehouses/{id}/rotate |
the old key at once; already-vended sessions expire within 60 min |
| storage administrator key pair | us | old pair refused everywhere within 17 s and absent from disk |
| credential-vending signing key | us | every outstanding vended session, 11 s |
Logging and personal data
The website sets no cookies, loads nothing from third parties and keeps no access log. The API logs requests with the caller's address for operations and abuse prevention; rate-limit counters live in memory for at most an hour. We never read your table or object content. Retention of server logs: 30 days [founder to confirm].
Not yet done — and we say so
- High availability. One host. A host failure means downtime until restore from backup.
- Encryption at rest for tenant secrets. Tenant storage key pairs are in plaintext in a root-only database file; envelope encryption is designed, not built.
- Encryption at rest for customer content. Not verified as enabled; do not rely on it.
- Encrypted backup archives. Protected by credentials and TLS, not by their own encryption.
- Container hardening and log retention automation. Scheduled.
- Certifications. None (no ISO 27001, no SOC 2). This page and the DPA's Annex II are what we offer for your assessment; we will answer questionnaires by email.
- SLA. None yet; comes with paid plans.
Reporting a vulnerability
Email [security@ address]. You may test your own warehouses and credentials; please do not test other customers' or load-test the shared service without asking. We do not act against good-faith research that follows that rule.
Change log
- 2026-09-19-draft — first draft, written from
platform/docs/security.md,platform/deploy/README.mdandplatform/STATE.md. Not published.