Security & data
Where your data lives, how it's protected, what isolation looks like under the hood, and how the right-to-be-forgotten flow works.
Where the data lives
Everything customer-facing runs on Cloudflare's UK edge — the application Worker, the API, the static assets and the CDN cache. The database sits on PlanetScale Postgres (UK region) fronted by Cloudflare Hyperdrive for low-latency edge access. Authentication is WorkOS AuthKit; the user / member tables on our database are a mirror of the WorkOS source-of-truth so every authenticated request resolves through one identity provider.
No customer data crosses the UK border in normal operation. Open-Meteo weather lookups are the only outbound call to a non-UK endpoint, and those carry latitude/longitude only — no identifiable customer info.
Tenant isolation
Every query the application makes filters by organisation. There is no shared-cache or shared-state path where one organisation's data could leak into another's response. Two enforcement layers:
- Code-level. Every API route resolves the caller's organisation from their session and applies an
organisation_id = ?filter on every query. This is the primary guard. - Test-level. A repo-wide integration test sweeps every
/api/*route and asserts that none of them can be coaxed into returning another organisation's data. The test runs on every push tomain; a regression blocks the deploy.
The internal /admin namespace is locked down: internal-only endpoints are gated to InspireGreen staff. Customers can't reach it even with a valid session for their own org.
Credential encryption
All third-party API credentials (SolarEdge keys, Solis Cloud secrets, Stripe webhook secrets, future provider tokens) are encrypted at rest with AES-256-GCM. The master encryption key is a Cloudflare Workers secret — it isn't present in source, isn't in environment files, and isn't accessible to non-platform code.
Credentials are stored encrypted at rest (AES-256-GCM). The scheme is versioned so we can rotate it without breaking historic rows.
Transport security
- HSTS enforced (one-year max-age), preloaded.
X-Content-Type-Options: nosniff,X-Frame-Options: DENY, strict referrer policy.- Permissions-Policy blocks camera, microphone, geolocation, browser cohorts.
- CSP enforced on the API surface, report-only on the marketing site (we're moving the marketing site to enforced once we've audited every third-party include).
UK GDPR posture
We're UK GDPR compliant. The legal basis for processing customer data is contract performance — without it the platform doesn't work. Telemetry from third-party APIs is captured under the customer's contract with those providers; we don't acquire or share data with anyone outside the platform.
You can review the full privacy policy for the legal version.
Right to be forgotten
Owners can initiate a complete data deletion from Settings → Billing → Delete organisation. The flow has a 24-hour confirmation window — the request is logged, an email goes to every owner on the account, and the destructive action only fires after a second click from the original initiator confirming intent.
On confirmation:
- Every tenant row across telemetry, equipment, alerts, cases, visits, reports, documents is hard-deleted.
- The organisation record itself is anonymised (we keep an audit row that an org with this id existed and was deleted on this date, but no identifying fields remain).
- All member rows, pending invitations, integration credentials and notification subscriptions are deleted.
- The corresponding Stripe customer is closed and billing terminates.
The deletion is atomic and irreversible. We confirm completion to the initiator's email of record.
Reporting a security issue
Responsible disclosure: security@solarfleet.io. We acknowledge within one working day and aim to triage within three. We don't run a bug bounty programme right now, but we'll credit you on the security page if you'd like.