Security and Data Protection
How we protect your and your users' data — in plain language, without marketing spin. This page is intended for municipal IT security managers and procurement officers.
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 and
gcloud storage buckets describe.
Some subprocessors (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 the
Subprocessors 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_KEY
and STRIPE_WEBHOOK_SECRET — are declared as
Firebase 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 using
gcloud 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.
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 in Data 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
The following services process data on Skolkoll's behalf. All subprocessors are bound by either EU Standard Contractual Clauses (SCC) or are located within the EU/EEA. A full GDPR description is available in our privacy policy.
| Service | Role / function | Location | GDPR 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 |
| 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 | Compliant | Full privacy policy, consent banner, DPA available on request, right to erasure implemented |
| 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 to security@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 that join the Pro service. 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