Security and Data Protection
Check security status, data location, subprocessors, incident process and DPA evidence.
Quick check
Region, encryption, secrets, SSO, audit logs, incident routines and contract documentation.
Cloud configuration is verified before release; external pentest and formal certification are not complete.
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.
- IdP options: SAML 2.0 or OIDC, including Microsoft Entra ID / Azure AD.
- Role mapping: The municipality's IdP controls the identity; Skolkoll stores the role and organisation membership for authorisation in the service.
- Offboarding: When the municipality removes the user in its IdP, new sign-in stops. Existing Firebase sessions can be revoked manually if needed.
- Onboarding: Metadata exchange, a test account and domain verification are required before going live.
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.
| Service | Role / function | Location | GDPR role / basis |
|---|---|---|---|
| Firebase / Google Cloud | Hosting, database (Firestore), Cloud Functions, Secret Manager, Cloud Storage | Cloud 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 |
| Stripe | Payment processing for Pro services; card data is never handled by Skolkoll | Ireland (EU) primarily; some fraud-detection functions may involve Stripe US under SCC | Contract (Art. 6.1.b); Stripe DPA; SCC where needed |
| Google Analytics 4 (GA4) | Anonymous visit statistics; only loaded after consent | USA | Consent (Art. 6.1.a); SCC; IP anonymisation enabled |
| Zoho PageSense | Web analytics, A/B testing and heatmaps/session recording on public pages; only loaded after consent | EU script via cdn-eu.pagesense.io; DPA/SCCs for any third-country transfer | Consent (Art. 6.1.a); Zoho DPA/SCCs |
| Zoho Desk | Support cases for paying customers via support@skolkoll.se and the support portal | EU (support.skolkoll.se via Zoho EU hosting, zohohost.eu); DPA/SCCs for any third-country transfer | Contract (Art. 6.1.b) and legitimate interest (Art. 6.1.f); Zoho DPA/SCCs |
| Sentry | Error monitoring; collects error messages, stack traces, browser/OS info and IP address that is anonymised shortly after receipt | EU (Germany, ingest.de.sentry.io); SCC for any support by US team | Legitimate interest (Art. 6.1.f); Sentry DPA; SCC for any US support access |
| Anthropic (Claude API) | AI assistant Kollen; processes chat messages in real time | USA | Consent (Art. 6.1.a); SCC; Anthropic DPA; data retained max 30 days by Anthropic |
| OpenAI | School-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 SCC | Consent (Art. 6.1.a); OpenAI DPA; SCC for third-country transfers |
| Resend | Email delivery for school alerts and transactional mail | USA | Legitimate interest / consent (Art. 6.1.f/a); SCC |
| Nominatim (OpenStreetMap) | Geocoding for "Near me" feature; no personal data is stored | EU/EEA | Legitimate interest (Art. 6.1.f); no DPIA required |
| ResRobot (Trafiklab) | Public transport data for commute tab; coordinates proxied via Skolkoll's server | Sweden (EU) | Legitimate interest (Art. 6.1.f) |
| JobTech (JobEd Connect) | Career matching for career tab; education text sent, no personal data | Sweden (EU) | Legitimate interest (Art. 6.1.f) |
| Skolverket API | School data (open data); does not process personal data | Sweden (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.
- 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.
- 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?
- 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.
- 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.
- 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.
- 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 / requirement | Status | Notes |
|---|---|---|
| GDPR | Evidence available | Privacy 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 II | Not certified | We 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 27001 | Not certified | ISO 27001 certification has not been obtained. We work systematically with information security but without a formal ISMS implementation. |
| External penetration test | Not conducted | No 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 DSS | Via Stripe | Skolkoll 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:
- Acknowledge receipt of your report within 5 working days.
- Keep you informed of the progress of the investigation.
- Fix confirmed vulnerabilities within a reasonable time depending on severity.
- Acknowledge your contribution in the release log if you wish (with your consent).
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.
- Standard template: See our DPA template for a ready-to-use data processing agreement.
- Custom agreement: Contact markus@skolkoll.se if your organisation requires a tailored DPA.
- ROPA (Record of Processing Activities): Available on the ROPA page.
- Data protection details: See the data protection and subprocessors page for operational GDPR details.
See also: Privacy policy · SLA and uptime · Commercial separation · Transparency