Aller au contenu

Architektur & Schutzmassnahmen

Ce contenu n’est pas encore disponible dans votre langue.

Diese Seite richtet sich an IT-Verantwortliche, Treuhänder und Sicherheitsbeauftragte, die einen technischen Überblick benötigen. Wenn Sie Betreiber sind und nur die Kurzfassung wollen, finden Sie diese auf der Übersichtsseite.

CampOne ist eine mehrmandantenfähige SaaS-Anwendung. Backend (Django 5.2, Python 3.12), Admin-Frontend (React 19, Vite 6) und Datenbank (Supabase PostgreSQL, EU-Region) sind drei klar getrennte Komponenten, die ausschliesslich über verschlüsselte Verbindungen (TLS 1.2+) miteinander reden.

ElementWert
Token-VerfahrenJWT (RFC 7519), Algorithmus HS256, Bearer-Header
Lebensdauer Access-Token30 Minuten, ausschliesslich im Speicher des Browsers
Lebensdauer Refresh-Token7 Tage, in einem HttpOnly; Secure; SameSite=None Cookie
RotationRefresh-Tokens werden bei jeder Erneuerung ausgetauscht; das alte Token wird sofort gesperrt
AbmeldungServer-seitiges Sperren des Refresh-Tokens plus Cookie-Löschung
Passwort-PolitikMindestlänge, Ähnlichkeitsprüfung, Liste der häufigsten Passwörter, kein rein numerisches Passwort
Passwort-HashDjango-Standardpipeline (PBKDF2 als Primär, Argon2 verfügbar), Cost-Factor rotierbar
Passwort-ResetEinmalig verwendbarer HMAC-Token, Standardgültigkeit 3 Tage
SitzungslimitPro Mandant nach Plan begrenzt (z.B. Starter 2, Professional 5) — älteste Sitzungen werden bei Überschreitung abgemeldet

Jede Anfrage wird durch eine TenantMiddleware geschleust, die den Mandanten in dieser Reihenfolge ermittelt:

  1. Aus dem JWT-Claim tenant_id (für authentifizierte Aufrufe).
  2. Aus dem X-Tenant-Slug Header (für unauthenticierte öffentliche Endpunkte).
  3. Aus der Custom-Domain im Origin-Header (für Gäste-Buchungs-Webseiten).

Anschliessend wendet ein TenantManager automatisch den Filter tenant=<aktueller> auf jede Datenbankabfrage an. Es ist nicht möglich, ohne explizite, im Code grep-bare Mandantenwechsel-Logik auf Daten eines anderen Betriebs zuzugreifen.

Nicht aktive Mandanten (is_active=False) werden nie aufgelöst — die Deaktivierung wirkt sofort als Notausschalter.

RolleBeschreibung
SuperadminCampOne-interner Support. Kein Mandant zugewiesen. Zugriff auf einen Echt-Mandanten erfordert eine genehmigte Support-Anfrage.
Tenant-AdminVollzugriff innerhalb des eigenen Mandanten. Kann Mitarbeitende anlegen und Module zuweisen.
StaffEingeschränkter Zugriff auf zugewiesene Module (z.B. nur Rezeption oder nur Kasse).
CustomerGast mit Zugriff auf eigene Buchungen über das Gästeportal.

CampOne-Support kann auf einen Echt-Mandanten in drei Modi zugreifen, und dies wird stets im Audit-Log festgehalten:

  • Mock: ein gemeinsamer, synthetischer Beispiel-Mandant. Keine Genehmigung nötig.
  • Maskiert: Ihr Mandant, aber alle persönlichen Daten der Gäste sind in den Antworten ausgeblendet, und schreibende Aktionen werden serverseitig blockiert. Keine Genehmigung nötig.
  • Real: Ihr Mandant mit Vollzugriff. Erfordert eine genehmigte Support-Zugangsanfrage. Token-Lebensdauer 30 Minuten.
HeaderWert
Strict-Transport-Securitymax-age=31536000; includeSubDomains; preload (1 Jahr, Preload-Liste)
Content-Security-Policymit frame-ancestors 'none' und auf bekannte Quellen beschränkten connect-src und img-src
X-Frame-OptionsDENY
X-Content-Type-Optionsnosniff
Referrer-Policystrict-origin-when-cross-origin
Permissions-Policygeolocation=(), microphone=(), camera=()

Alle vier ausgelieferten Web-Frontends (Admin, Marketing, Docs, mandantenspezifische Buchungs-SPAs) setzen diese Header am Vercel-Edge zusätzlich zur Backend-Konfiguration.

DatentypSpeicherortSchutz
DatenbankSupabase PostgreSQL, AWS Frankfurt-Region (eu-west-1)TLS-Verbindung, tägliche Backups, Point-in-Time-Recovery
Datei-UploadsSupabase S3, EU-Regionprivate ACL, mandantenspezifische Pfade, signierte URLs für jeden Zugriff
Mandanten-Geheimnisse (Stripe-Keys, SMTP-Passwörter)DatenbankAnwendungsseitig verschlüsselte Felder, eigener Schlüssel pro Umgebung
LogsVolume des Backend-HostersRotation alle 5 MB, max. 5 Generationen, kein PII in Anfrageparametern
EndpunktSchwelle
Anmeldung10 Versuche/Minute pro IP
Passwort-Reset5 Versuche/Stunde pro IP
Konto-Löschung3 Versuche/Stunde pro Konto
Verfügbarkeitssuche (öffentlich)60 Anfragen/Minute pro IP
AI-Assistent (anonym)20 Anfragen/Stunde pro IP
Public API pro Schlüsselkonfigurierbar, Standard 1000/Stunde

Zusätzlich erzwingt die Anwendung pro Mandant ein Limit gleichzeitiger Sitzungen — älteste Refresh-Tokens werden bei Überschreitung gesperrt.

  • Public API (/api/v1/public/): API-Key-Authentifizierung mit Format ck_<prefix><secret>, in der Datenbank wird nur der gesalzene Hash gespeichert, der Klartext ist nach der Erstellung nicht wiederherstellbar. Jeder Aufruf wird in APICallLog mit Status, Pfad und Latenz protokolliert. Bodies werden nicht geloggt — der Audit-Trail enthält keine personenbezogenen Inhalte.
  • Webhooks: Stripe-Webhooks werden mit dem mandantenspezifischen Webhook-Secret signaturgeprüft. Der OTA-Webhook (Booking.com) authentifiziert sich per HTTP-Basic über TLS.
  • Lead-Formular auf der Marketing-Webseite: Validierung über react-hook-form und zod, serverseitiges Drosseln auf 20 Anfragen/Stunde pro IP.

Sechs separate, mandantenspezifische und indizierte Tabellen halten relevante Vorgänge fest:

  • UserLoginLog — jede erfolgreiche Anmeldung mit IP-Adresse und Zeitstempel.
  • BookingAuditLog — jede Änderung an einer Buchung als Diff-Eintrag mit Akteur und Begründung.
  • SupportAuditEvent + SupportAccessSession — jede Support-Sitzung von CampOne in Ihren Mandanten.
  • APICallLog — jeder Aufruf über die Public API.
  • MessageLog — jeder verschickte transaktionale E-Mail-Versand.
  • ErrorLog — unbehandelte Fehler im Backend.

Detaillierte Beschreibung auf der Audit-Trail-Seite.

CampOne läuft auf den jeweils aktuellen Hauptversionen:

KomponenteVersion
Django5.2
Django REST Framework3.17
SimpleJWT5.4
React19
Vite6
Python3.12
PostgreSQL15 (Supabase)

Es gibt keine End-of-Life-Komponenten im produktiven Einsatz. Sicherheitspatches werden in den jeweils nächsten Wartungs-Release übernommen; kritische Updates werden ausserhalb des regulären Release-Zyklus eingespielt.

Diese Seite ist eine Zusammenfassung. Für ein technisches Audit stellen wir auf Anfrage zur Verfügung:

  • die interne Sicherheitsposture-Dokumentation mit Verweisen auf jede einzelne Code-Stelle,
  • den nDSG-Compliance-Audit-Bericht,
  • den aktuellen Sicherheits-Roadmap-Stand mit Risikoeinstufungen,
  • Zugriff auf eine Test-Umgebung zur eigenständigen Überprüfung.

Anfragen an security@campone.ch.