Spick · Säkerhet & Riskhantering
Status Risker Backup Runbooks ← Admin

🛡️ Säkerhet & Riskhantering

Fullständig dokumentation av Spicks säkerhetsstatus, backup-rutiner och åtgärdsplaner för driftstörningar.

Aktuell Säkerhetsstatus
HTTPS / SSL
GitHub Pages – automatisk, gratis
Admin-auth
Supabase Magic Link → hello@spick.se
Stripe PCI-DSS
Kortdata hanteras aldrig av Spick
Nightly Backup
13 tabeller, kl 02:00 varje natt
Uptime Monitor
Kontroll var 15:e minut + e-postalert
GitHub Actions CI
Secrets i GitHub Secrets, ej i kod
Supabase RLS
Row Level Security aktiverat
⚠️
Anon-nyckel i HTML
Publik men begränsad av RLS
⚠️
Kund-auth (email)
Bör uppgraderas till Supabase Auth
ℹ️
Supabase PITR
Ej aktiverat (kräver Pro-plan)
Riskregister
Risk Sannolikhet Konsekvens Risknivå Nuvarande skydd Åtgärd Status
spick.se nere (GitHub Pages)
GitHub har driftstörning
Låg (99.95% uptime) Hög – inga nya bokningar MEDIUM Uptime monitor var 15 min + e-postalert Statuspage på status.spick.se. Backup-URL. Pågår
Supabase nere
DB eller Edge Functions ej tillgängliga
Mycket låg (SLA 99.9%) Kritisk – inga betalningar, inget flöde HÖG Incident-response workflow + e-postalert inom 15 min Aktivera Supabase PITR (Pro). Offline-meddelande på boka.html. Todo
Stripe nere / betalning misslyckas Låg Hög – intäktstapp HÖG Stripe har eget statuspage. Klarna som backup. Swish-integration (pågår). Stripe-webhook retry. Pågår
Resend nere / e-post levereras ej Låg Medel – kunder missar bekräftelse MEDIUM Resend retry-logik. Bokningar sparas i DB oberoende. Fallback-avsändare via Mailgun (konfigurera i Resend). Todo
Dataläcka – obehörig DB-access Låg Kritisk – GDPR, förtroende HÖG RLS aktiverat. Anon-key begränsad. Service role i Secrets. Skärp RLS på bookings. Implementera Supabase Auth för kunder. Pågår
GitHub komprometteras (tokens läcks) Mycket låg Kritisk – deploy-pipeline MEDIUM GitHub 2FA. Secrets rotation rutiner. Rotera GH_PAT varje 90 dagar. Minimal scope på tokens. Todo
DNS-kapning / Loopia-intrång Mycket låg Kritisk – hela domänen äventyras HÖG Loopia 2FA. DNS-TTL 3600s. Aktivera DNSSEC i Loopia. Övervaka DNS-ändringar. Todo
Städares konto komprometteras Medel Medel – obehörig tillgång till kunddata MEDIUM Magic Link (tokenbaserat). Ingen lösenord att läcka. Magic Link upphör automatiskt. Städare ser bara egna bokningar. OK
Dataskada (oavsiktlig delete/update) Låg Hög – bokningsdata försvinner HÖG Nightly backup 13 tabeller. 30 dagars retention. Supabase PITR (Pro). Disaster Recovery workflow. Pågår
GDPR-brott – PII hanteras felaktigt Låg Kritisk – böter upp till 4% av omsättning KRITISK Integritetspolicy publicerad. PNR hashas. Stripe PCI-DSS. Data Processing Agreement med Supabase, Stripe, Resend. Cookie consent. Pågår
Backup-strategi

✅ Vad som backas upp automatiskt varje natt (kl 02:00)

  • bookings – alla bokningar
  • cleaners – alla städarprofiler
  • cleaner_applications – ansökningar
  • reviews – recensioner
  • referrals – referral-data
  • subscriptions – prenumerationer
  • emails – e-postinkorg
  • invoices – fakturor
  • gift_cards – presentkort
  • cleaner_availability – scheman
  • analytics_events – analytics
  • customer_profiles – kundprofiler
  • guarantee_requests – garantiärenden

⚠️ Backup-begränsningar

  • Lagring: GitHub-repo (publik klon kan se backup-data – bör vara privat repo ✅)
  • Retention: 30 dagar (filer äldre rensas automatiskt)
  • Format: JSON via REST API (fullständig men ej transaktionellt konsistent)
  • Gräns: Max 10 000 rader per tabell (tillräckligt nu, bör skalas)
  • Point-in-time recovery: Ej tillgängligt utan Supabase Pro

💡 Supabase inbyggd backup

Supabase Free-tier inkluderar dagliga backups som hålls i 7 dagar. Pro-tier ger Point-in-Time Recovery (PITR) med 7 dagars retention. Vår GitHub-backup kompletterar detta med 30 dagars retention och JSON-format som är läsbart utan Supabase-access.

Incident Runbooks – Vad gör du när något går fel?

🔴 Scenario 1: spick.se svarar inte

  • 1️⃣ Kontrollera githubstatus.com – är GitHub Pages nere?
  • 2️⃣ Kontrollera senaste GitHub Actions-körning – har deploy misslyckats?
  • 3️⃣ Gå till GitHub → spickapp/spick → Actions → Deploy to GitHub Pages
  • 4️⃣ Om deploy OK men sidan nere: vänta 5 min, GitHub Pages kan vara fördröjd
  • 5️⃣ Om git-commit korrupt: git revert HEAD och pusha om
  • 6️⃣ Publicera ett statusmeddelande på sociala medier om driftstörning > 30 min
  • 7️⃣ Meddela väntande kunder via broadcast-mail från admin-panelen
  • # Kolla deploy-status:
    gh run list --workflow=deploy.yml --limit=5

    # Tvinga om-deploy:
    git commit --allow-empty -m "Force redeploy" && git push

    # Återställ till senaste fungerande version:
    git log --oneline -10 # Hitta commit-hash
    git revert [commit-hash] && git push

    🔴 Scenario 2: Supabase / DB nere

  • 1️⃣ Kontrollera status.supabase.com
  • 2️⃣ Kontrollera Supabase Dashboard – är projektet pausat? (Gratisnivå pausas efter 7 dagars inaktivitet)
  • 3️⃣ Om projektet är pausat: klicka "Restore project" i Supabase Dashboard
  • 4️⃣ Lägg till ett maintenance-meddelande på boka.html (commit direkt)
  • 5️⃣ Acceptera inga nya bokningar manuellt tills DB är tillbaka
  • 6️⃣ Om data gick förlorad: kör Disaster Recovery workflow i GitHub Actions
  • # Vakna Supabase-projektet (om pausat):
    curl -X POST https://api.supabase.com/v1/projects/urjeijcncsyuletprydy/restore
    # (eller manuellt via Dashboard)

    # Kör disaster recovery via GitHub Actions:
    # GitHub → Actions → Disaster Recovery → Run workflow
    # Välj: action=verify_backup

    🟡 Scenario 3: Betalning misslyckas (Stripe)

  • 1️⃣ Kontrollera status.stripe.com
  • 2️⃣ Kolla Stripe Dashboard → Payments för felmeddelanden
  • 3️⃣ Kontrollera att Stripe webhook-URL är korrekt registrerad
  • 4️⃣ Webhook-secret: whsec_al4z5aWMSGg5Q5Qpf9WERYl7FUeREFHl
  • 5️⃣ Kunder med misslyckad betalning: erbjud alternativ via hello@spick.se
  • 6️⃣ Manuell bokning möjlig via admin-panelen som backup
  • 🟡 Scenario 4: E-post levereras inte (Resend)

  • 1️⃣ Kontrollera Resend Dashboard → Logs
  • 2️⃣ Kontrollera SPF och DKIM-poster för spick.se i Loopia
  • 3️⃣ Bokningsdata finns i Supabase oavsett – e-post är bara bekräftelse
  • 4️⃣ Manuellt skicka bekräftelser via hello@spick.se om nödvändigt
  • 5️⃣ Kontrollera free-tier-limit: Resend free = 3 000 mail/mån
  • 🔴 Scenario 5: Misstänkt säkerhetsbrott

  • 1️⃣ Rotera OMEDELBART: Supabase anon-key, service role key i Supabase Dashboard
  • 2️⃣ Rotera Stripe API-keys i Stripe Dashboard
  • 3️⃣ Uppdatera alla GitHub Secrets med nya nycklar
  • 4️⃣ Granska Supabase Auth Logs för obehöriga inloggningar
  • 5️⃣ Granska Stripe Dashboard för obehöriga transaktioner
  • 6️⃣ Om kunddata exponerades: GDPR-anmälan till IMY inom 72 timmar
  • 7️⃣ Kontakta berörda kunder via e-post
  • # Rotera Supabase-nycklar:
    # Supabase Dashboard → Settings → API → Generate new key

    # Uppdatera GitHub Secrets efter rotation:
    # GitHub → Settings → Secrets → Actions
    # Uppdatera: SUPABASE_ANON_KEY, SUPABASE_SERVICE_KEY, SUPABASE_SERVICE_ROLE_KEY

    # IMY (Datainspektionen) anmälan:
    https://www.imy.se/anmalan-incidentrapportering/
    Nycklar & Hemligheter – Var finns vad?
    NyckelVar lagras denVem kan se denRotationsintervall
    Supabase Anon Key GitHub Secrets + HTML-filer (publik) Alla med repo-access + användare Vid säkerhetsbrott
    Supabase Service Role Key GitHub Secrets (ej i kod) Bara GitHub Actions Varje 6 månader
    Stripe Secret Key GitHub Secrets + Supabase env Bara GitHub Actions / Edge Functions Varje 6 månader
    Stripe Webhook Secret GitHub Secrets + Supabase env Bara GitHub Actions / Edge Functions Vid ny webhook
    Resend API Key GitHub Secrets + Supabase env Bara GitHub Actions / Edge Functions Varje 6 månader
    GH_PAT (GitHub token) GitHub Secrets Bara GitHub Actions Varje 90 dagar
    Anthropic API Key GitHub Secrets Bara GitHub Actions / Edge Functions Varje 6 månader
    Loopia API credentials GitHub Secrets Bara GitHub Actions Varje år
    GDPR & Dataskydd

    ✅ Vad vi gör rätt

    • Personnummer (PNR) hashas och lagras aldrig i klartext
    • Betalningskortdata hanteras enbart av Stripe (PCI DSS Level 1)
    • Integritetspolicy publicerad och länkad från footer
    • Cookie-banner implementerad
    • Kunder kan begära radering (kontakta hello@spick.se)
    • Data lagras i EU (Supabase eu-central-1 / AWS Frankfurt)

    ⚠️ Vad vi bör förbättra

    • Data Processing Agreement (DPA) saknas formellt med Supabase/Stripe/Resend
    • Automatisk dataradering efter inaktivitet är ej implementerad
    • Rätt till dataexport (GDPR Art. 20) är ej automatiserad
    • Cookies som Google Analytics sätts utan explicit samtycke (bör fixas)
    Åtgärdsplan – Prioriterat
    PrioritetÅtgärdTidAnsvarigStatus
    P1 Aktivera Supabase Pro för PITR-backup 1 dag Farhad Todo
    P1 Rotera GH_PAT (sista rotationsdatum okänt) 30 min Farhad Todo
    P2 Aktivera DNSSEC i Loopia 30 min Farhad Todo
    P2 Skärp RLS: bookings ska kräva auth för SELECT 2 timmar Claude Pågår
    P2 Implementera Supabase Auth för kunder (ej bara email) 1 vecka Claude Todo
    P3 Sätt upp statuspage (status.spick.se) 2 timmar Claude Todo
    P3 DPA med Supabase, Stripe, Resend (formella avtal) 1 dag Farhad Todo
    P3 Cookie-samtycke för Google Analytics 2 timmar Claude Delvis
    P4 Varning om Supabase-projektet pausas 1 timme Claude OK
    P4 Backup-lagring till extern (S3/B2) istället för GitHub 1 dag Claude Todo