Security and Data Protection

Check security status, data location, subprocessors, incident process and DPA evidence.

Last updated: 2026-06-18

Quick check

Verify

Region, encryption, secrets, SSO, audit logs, incident routines and contract documentation.

Security status

Cloud configuration is verified before release; external pentest and formal certification are not complete.

Source

Status is based on production configuration, supplier agreements and documented operating routines.

Data centres and encryption

Location

Skolkoll's Cloud Functions, Hosting, Cloud Storage and Firestore are configured in Google Cloud region europe-west1 (Belgium, EU). Firebase Authentication is covered by Google Cloud DPA/SCC/DPF. Region status in production is verified before each release using gcloud firestore databases describe andgcloud storage buckets describe.

Some subprocessors and external services (Stripe, Anthropic, OpenAI, Google Analytics 4 and social login providers) are US-based and may process data there. EU Standard Contractual Clauses (SCCs) and the relevant supplier DPA apply for these transfers. Zoho PageSense is loaded via the EU script cdn-eu.pagesense.io and is covered by Zoho DPA/SCCs for any third-country transfer. Zoho Desk is used for paying-customer support cases via Zoho's EU hosting (zohohost.eu). Sentry runs in the EU region (Germany). See thesubprocessors and external services table below for the full overview, and Data protection and subprocessors for operational detail.

Encryption at rest

Firestore and Cloud Storage encrypt all data at rest using Google-managed keys (AES-256) by default. We do not currently use customer-managed encryption keys (CMEK) — this is a feature we are evaluating for future Pro-tier commitments.

Encryption in transit

All traffic to and from Skolkoll uses TLS 1.2 or later. Firebase Hosting automatically enables HSTS (HTTP Strict Transport Security), preventing downgrade to unencrypted HTTP. Certificates are managed automatically by Google and renewed without manual intervention.

Secrets and authentication

Secrets management

All secrets — including ADMIN_TOKEN, STRIPE_SECRET_KEYand STRIPE_WEBHOOK_SECRET — are declared asFirebase Secret Manager bindings in the Cloud Functions code (via secrets: […] in functions options and defineSecret()). No secrets are hard-coded in source code or environment files. Cloud Functions v2 reads the values from Google Cloud Secret Manager at runtime. Presence of active secret versions for each declared secret in production is verified usinggcloud secrets versions list before release.

ID token revocation

Firebase Authentication tokens are verified with checkRevoked: true on all protected admin endpoints. This means that signing in on another device, changing a password, or manually revoking a token immediately invalidates existing sessions without waiting for token expiry (default lifetime: 1 hour).

Admin access

The admin token is rotated manually and is never included in client-side code. Admin endpoints require the X-Admin-Token header with the correct value, verified server-side. No admin operations are accessible from the browser without explicit authentication.

Municipality Licence SSO

The Municipality Licence uses Firebase Authentication as its account store. The standard flow is email-based sign-in and organisation invitations. For municipalities that require central identity management, SAML 2.0 or OIDC can be enabled as an Enterprise SSO add-on.

See also SSO status in the procurement pack.

Audit logging

Sensitive administrative operations are logged in the Firestore collection auditLog. The collection has deny-all Firestore Security Rules — no client can read or write to it. Access is exclusively via Firebase Admin SDK (server-side), eliminating the risk of manipulation through client code.

Each audit log entry contains: timestamp, operation, performing identity, and affected object. New entries are tagged with expiresAt for 2-year retention and deleted asynchronously by Firestore TTL when the policy is active.

AI chatbot calls are logged separately with pseudonymised entries (SHA-256 hash of IP, length of question/answer, not content). Pseudonymisation happens at write time; the deletion routine for these entries is documented inData protection and subprocessors.

Backup and recovery

The Firestore database is configured for Point-in-Time Recovery (PITR)via Google Cloud. PITR enables point-in-time restore within the window that Firestore PITR provides (up to 7 days), covering accidental data changes and corruption during an incident period. Actual PITR status and retention window in production are verified with gcloud firestore databases describe before each release. Recovery has not been exercised in a controlled disaster-recovery drill — we intend to run such a drill ahead of the first Municipal Licence production deployment.

Subprocessors and External Services

The following list mixes actual data processors/subprocessors with external data sources and APIs that do not always process personal data on Skolkoll's behalf. The binding subprocessor register for DPA purposes is available onData protection and subprocessors.

ServiceRole / functionLocationGDPR role / basis
Firebase / Google CloudHosting, database (Firestore), Cloud Functions, Secret Manager, Cloud StorageCloud Functions, Hosting, Cloud Storage and Firestore: EU (europe-west1, Belgium). Firebase Authentication covered by Google Cloud DPA/SCC/DPF.Contract (Art. 6.1.b); DPA included in Firebase terms
StripePayment processing for Pro services; card data is never handled by SkolkollIreland (EU) primarily; some fraud-detection functions may involve Stripe US under SCCContract (Art. 6.1.b); Stripe DPA; SCC where needed
Google Analytics 4 (GA4)Anonymous visit statistics; only loaded after consentUSAConsent (Art. 6.1.a); SCC; IP anonymisation enabled
Zoho PageSenseWeb analytics, A/B testing and heatmaps/session recording on public pages; only loaded after consentEU script via cdn-eu.pagesense.io; DPA/SCCs for any third-country transferConsent (Art. 6.1.a); Zoho DPA/SCCs
Zoho DeskSupport cases for paying customers via support@skolkoll.se and the support portalEU (support.skolkoll.se via Zoho EU hosting, zohohost.eu); DPA/SCCs for any third-country transferContract (Art. 6.1.b) and legitimate interest (Art. 6.1.f); Zoho DPA/SCCs
SentryError monitoring; collects error messages, stack traces, browser/OS info and IP address that is anonymised shortly after receiptEU (Germany, ingest.de.sentry.io); SCC for any support by US teamLegitimate interest (Art. 6.1.f); Sentry DPA; SCC for any US support access
Anthropic (Claude API)AI assistant Kollen; processes chat messages in real timeUSAConsent (Art. 6.1.a); SCC; Anthropic DPA; data retained max 30 days by Anthropic
OpenAISchool-image safety/content review and chalkboard-style transformation; only after explicit consent in the school-image form. Contact details, photographer name, rights-holder name and free-text notes are not sent to OpenAI.EU/USA under SCCConsent (Art. 6.1.a); OpenAI DPA; SCC for third-country transfers
ResendEmail delivery for school alerts and transactional mailUSALegitimate interest / consent (Art. 6.1.f/a); SCC
Nominatim (OpenStreetMap)Geocoding for "Near me" feature; no personal data is storedEU/EEALegitimate interest (Art. 6.1.f); no DPIA required
ResRobot (Trafiklab)Public transport data for commute tab; coordinates proxied via Skolkoll's serverSweden (EU)Legitimate interest (Art. 6.1.f)
JobTech (JobEd Connect)Career matching for career tab; education text sent, no personal dataSweden (EU)Legitimate interest (Art. 6.1.f)
Skolverket APISchool data (open data); does not process personal dataSweden (EU)Not applicable (public data)

Incident response

We are a small team and want to be honest about our process: we do not have a formal Security Operations Centre (SOC) or 24/7 on-call rotation. What we have is a defined process that we follow consistently.

  1. Monitoring and detection: Sentry captures application errors in real time. The Google Cloud console has alerting for unusual CPU spikes, quota overruns, and auth errors. We review the Sentry dashboard daily.
  2. Triage (within 24 hours): When a possible security incident is detected, the responsible developer performs an initial classification: does the incident affect personal data? Is the service unavailable? Are there signs of unauthorised access?
  3. Containment and mitigation: Depending on the incident type, immediate action is taken — revoking compromised tokens, blocking suspicious IP addresses, or temporarily disabling the affected feature.
  4. Notification: If the incident is assessed as a personal data breach under GDPR Art. 33, we notify the Swedish Data Protection Authority (IMY) within 72 hours. Affected data subjects are contacted if the incident is likely to result in a high risk to them (GDPR Art. 34). Notification is via markus@skolkoll.se.
  5. Recovery: In the event of database impact, Firestore's PITR feature (up to 7 days of history) is used to roll back affected documents. Static pages are rebuilt from source data.
  6. Post-incident review: After each serious incident we document the root cause, actions taken, and preventive changes internally. Material security improvements are communicated in the release log.

Service status and planned maintenance are published on the status page.

Compliance and certifications

Standard / requirementStatusNotes
GDPREvidence availablePrivacy policy, consent banner, DPA template, ROPA, subprocessor register and erasure routines are documented. A municipal signing package still requires legal review of the DPA, security appendix and continuity answer before it is used as binding approval evidence.
SOC 2 Type IINot certifiedWe follow SOC 2 principles (security, availability, confidentiality) but have not undergone a formal Type II audit. Certification is being evaluated ahead of large-scale municipal rollout.
ISO 27001Not certifiedISO 27001 certification has not been obtained. We work systematically with information security but without a formal ISMS implementation.
External penetration testNot conductedNo external security audit of the application has been conducted in 2026. An external pentest is planned ahead of the production launch of the public free-tier API.
PCI DSSVia StripeSkolkoll does not handle card data directly. Stripe, which is PCI DSS Level 1 certified, handles all card data.

Responsible disclosure

If you discover a security vulnerability in Skolkoll, we appreciate you reporting it to us before publishing it publicly. We commit to:

We currently offer no financial reward (bug bounty), but we take all reports seriously and communicate openly about the outcome of the investigation.

Disclosure policy: We apply a 90-day coordinated disclosure period. If a vulnerability has not been fixed within 90 days of your report, you reserve the right to publish the details. We will communicate proactively if we need more time.

Contact: Send your report tosecurity@skolkoll.se with the subject line "Security disclosure". Include reproduction steps and an assessment of the impact. Please encrypt with our public key if you are handling sensitive information — contact us and we will share it.

Please do not report via GitHub Issues or social media.

DPA and contract documentation

Skolkoll acts as a data processor for municipalities and schools when we process personal data on their behalf within Enterprise or other paid services. We provide a Data Processing Agreement (DPA) adapted for municipal procurement.

See also: Privacy policy · SLA and uptime · Commercial separation · Transparency