This page is a self-attestation, refreshed quarterly. Independent third-party certification (ISO 27001 and SOC 2 Type I) is in preparation, target Q4 2026.
The full attestations bundle (SAFARAPI-ATTEST-v1.0) is referenced by Annex 3 of the DPA and incorporated by reference into the Main Agreement.
At a glance
| Area | Posture |
|---|
| API auth | Bearer (Argon2id-hashed secrets) + HMAC SHA256 on writes, anti-replay timestamp window |
| Console auth | Keycloak OIDC + MFA mandatory for admin and finance roles |
| Transit | TLS 1.3 only, HSTS preload, Let’s Encrypt auto-renewal |
| At rest | AES-256 across R2, B2, LUKS full-disk on K3s nodes |
| Audit log | 7 years WORM (Cloudflare R2 Object Lock) — Bank Al-Maghrib aligned |
| Backups | Dual pipeline (PITR 5 min RPO + daily pg_dump 24 h RPO), restore drilled |
| Pen test | Annual — next scheduled Q3 2026, summary under NDA |
| Patch SLO | Critical CVE 24 h, High 7 d, Medium 30 d |
| PCI scope | None — Safariat never touches card data |
Identity and access
API authentication
- Token format:
sk_<env>_<8-char-prefix>_<random-secret>, where <env> is live or test.
- Secret hashing: Argon2id (m=64 MiB, t=3, p=1). Secrets are not recoverable — only the 8-character prefix is stored in clear for support.
- Write signing: every POST/PUT/DELETE/PATCH must include
X-Timestamp (Unix epoch seconds) and X-Signature (HMAC SHA256 of <timestamp>\n<METHOD>\n<path?query>\n<body> keyed with the secret).
- Anti-replay: timestamp window ±5 minutes, server-side
Clock-aware.
- Environment isolation: a
sk_test_* key cannot access production data and vice-versa — enforced at the authentication filter.
- Rate limiting: per-API-key Bucket4j, default 600 req/min, configurable per partner; 429 with
Retry-After.
- IP allowlist: optional per partner; enforced at the same authentication filter.
Scopes (least privilege)
catalog:read · quote:create · booking:read · booking:write · booking:cancel · settlement:read · webhook:manage
Console
- Keycloak realm
safarapi-partners, mandatory MFA for PARTNER_ADMIN and FINANCE.
- Federated identity (SAML / OIDC bridge to your IdP) available on request.
Cryptography
| Where | Algorithm | Key custody |
|---|
| In transit | TLS 1.3, HSTS preload | Let’s Encrypt via cert-manager |
| R2 object storage | AES-256-GCM | Cloudflare-managed |
| B2 backups | AES-256-CTR + optional client-side AES-256 for pg_dump archives | Provider-managed |
| K3s node disks | LUKS full-disk encryption | Host-managed |
| Kubernetes Secrets | Bitnami Sealed Secrets (RSA-OAEP + AES-256-GCM) | Public key in Git, private key in K3s only |
| Admin secrets | 1Password Business (AES-256, E2EE) | 2FA mandatory |
Pseudonymisation
The customer reference you send us is stored as SHA-256(<partner_id>:<customer_ref>) — scoped per partner, non-reversible. We cannot correlate the same end-customer across two different Partners.
Data residency
| Asset | Region | Provider |
|---|
| Primary PostgreSQL | Germany | Contabo (EU bare-metal) |
| Object storage (public + private) | EU | Cloudflare R2 |
| Physical PITR backups | EU (eu-central-003) | Backblaze B2 |
Logical backups (daily pg_dump) | US (us-east-005), AES-256 client-side encrypted before upload | Backblaze B2 |
| Identity provider | Germany | Self-hosted Keycloak |
| Audit log WORM | EU | Cloudflare R2 Object Lock |
No Personal Data of EU Data Subjects is processed outside the EU except the daily logical-backup tier, which is encrypted client-side with the key held exclusively by Safariat in the EU.
Resilience
- Kubernetes (K3s) — 3 control-plane + at least 1 worker node.
- PostgreSQL CNPG — primary + 1 hot standby with auto-failover.
- Rolling deployments with readiness/liveness probes on
/actuator/health.
- ArgoCD self-heal — declarative GitOps, drift auto-reverted.
- Backup tier 1: Barman + WAL streaming to B2 EU. RPO ≤ 5 min. Restore drill passed 2026-04-17.
- Backup tier 2: daily
pg_dump to B2 US-East (independent account, smaller blast radius). RPO 24h.
- RTO: 4 hours target, validated.
Logging and audit
Every API request lands in partner_api_audit_log (PostgreSQL native monthly partitioning, 12-month rolling, ShedLock job auto-creates new partitions) with:
request_id · partner_id · api_key_id · method · path · query_params · request_body_hash (SHA-256 — body itself is not stored) · status · latency_ms · client_ip · user_agent · idempotency_key · error_code · created_at
Retention: 90 days hot (database), 7 years cold archive (Cloudflare R2 Object Lock, retention mode compliance — irrevocable).
Application logs go to Fluent Bit → Elasticsearch (90-day hot retention) with Kibana saved searches restored automatically on cluster recovery via ArgoCD PostSync hook.
Software supply chain
- Container images pinned to specific patch versions (
keycloak:26.0.8, not :26.0 or :latest). Moving tags are forbidden — see post-mortem of the 2026-04-17 incident.
- Renovate Bot weekly dependency PRs.
- Trivy scan on every image build — fails the pipeline on Critical CVEs.
- GitOps deploy via ArgoCD — no human writes to the cluster outside emergency procedures (logged).
Patch SLO
| Severity | SLO |
|---|
| Critical (CVSS ≥ 9.0) | 24 hours |
| High (CVSS 7.0 — 8.9) | 7 days |
| Medium (CVSS 4.0 — 6.9) | 30 days |
| Low | Best effort |
Data minimisation
| Booking type | Required Personal Data | Notes |
|---|
| Domestic experience | First name, last name, email, phone | Minimum required for voucher |
| Domestic multi-day trip | Same + optional birth date (when accommodation requires it) | — |
| International flight (Omra/Haj/charter) | Same + passport number | IATA reservation requirement |
We never request: payment card data, biometrics, health data, religious / political / sexual-orientation data, trade union membership.
Compliance matrix
| Framework | Status | Notes |
|---|
| GDPR (EU 2016/679) | Applicable | DPA signed per partner |
| Loi 09-08 (Maroc) | Applicable | CNDP declaration on request |
| Bank Al-Maghrib externalisation | Aligned | 7-year audit log + sub-processor approval workflow |
| PCI DSS | Not in scope | No card data handled |
| ISO 27001 | Targeted Q4 2026 | External auditor engagement in progress |
| SOC 2 Type I | Targeted Q4 2026 | External auditor engagement in progress |
| eIDAS | Not applicable | No qualified signature primitives offered |
Incident response
- Detect — external probes + Prometheus alerts + security log alerts.
- Acknowledge — within MTTA (1h Critical, 4h High, 1bd Normal).
- Triage — scope, affected partners, root cause hypothesis.
- Mitigate — rollback, scale, isolate, patch.
- Communicate — status page every 30 min during the incident; direct email to affected partners.
- Resolve — confirm via probes and metrics.
- Post-mortem — published within 5 business days for Critical / High incidents.
Vulnerability disclosure
- Report to
security@safarapi.com (PGP key on the security page).
- We acknowledge within 24 hours.
- Researcher acknowledgement in the public Hall of Fame (with consent).
Obtaining the attestations bundle
The full attestations bundle is provided as a PDF on request — email
security@safarapi.com. On production approval, the current bundle is included
automatically in your compliance pack and refreshed annually.
- Security:
security@safarapi.com
- Privacy / DPA:
dpo@safarapi.com
- Operations / SLA:
ops@safarapi.com
- Billing:
billing@safarapi.com