Skip to content
← LevelSage

Privacy policy

Effective 2026-09-17

LevelSage is a cybersecurity-skills learning platform at levelsage.com. This page describes what LevelSage collects, why, on what legal basis, who receives it, where it goes, and how to exercise your rights.

Who is responsible for your data

v1 placeholder — pending incorporation

LevelSage is not yet an incorporated company. Until it is, the data controller for the purposes of the GDPR is the individual founder who operates the platform, reachable at [email protected]. On incorporation we will publish the company name, registered address, and enterprise number here and in the site footer, and update the effective date. If you need the controller's identity and postal address before then — for example to exercise a right or to file a complaint — write to the address above and we will provide them.

What we collect

We collect only what is needed to run the platform. There is no advertising stack, no third-party analytics, and no cross-site tracking. The usage analytics we do collect are first-party and are described below along with everything else.

  • Account identity. If you sign up with email and password, we store your email address and a password hash (managed by Supabase Auth — we never see your plaintext password). If you sign in with Google or GitHub, we receive an OAuth identifier from your provider and your verified email; we do not request or store any additional scopes (only openid, email, and profile).
  • Profile. A display name, a public handle, and your chosen class identity (e.g. Netwarden). You choose these; you can change them.
  • Practice activity. Track enrolment, per-skill XP, lab attempts, and attempt results. This is what makes a progression map work; it is private to your account and governed by row-level security at the database.
  • Trial submissions. When you take a Trial attempt, we store the attempt's variant id, the flag you submitted, your methodology write-up, and the verdict. A passing attempt issues a Credential record whose public verification token is shareable; the underlying methodology write-up is private.
  • Issued credentials. A pass produces a Credential row containing what was demonstrated, when, the per-attempt variant id, and the public token. These are intentionally surfaced via /verify/<token> for employer auditing — that is the only cross-user public read in the product.
  • Conversations with Sage. Sage is the platform's AI study companion. What you type to him, what he replies, which hint he drew on, and whether you marked a reply helpful are stored against your account so a conversation survives a reload and so we can see which explanations are failing learners. You can clear your conversation history from the Sage tab in Settings. If you are on a plan that offers Sage memory and you switch it on, we additionally store the short notes he keeps about how you learn; they are readable at /sage/memory and editable, switchable, and erasable from the Sage tab in Settings.
  • Usage analytics (first-party). We record product events — which page or lesson was opened, which step was reached, which button was chosen, and a small bag of context properties — to see where learners get stuck. These events are sent to our own servers only; no third party receives them. Before you have an account, the events can carry a random identifier generated in your browser and stored in localStorage (confluence.analytics.anonymousId) so that one visit reads as one visit; if you later create an account, events already recorded under that identifier are attached to your account so your first-session progress is not lost. Analytics stays off until you accept it. We ask on your first visit; before you answer, no analytics event is sent and no analytics identifier is written to local or session storage. If you decline, collection remains off and any identifier already stored is deleted; your answer itself is remembered as a single word in confluence.analytics.consent. Clearing your browser storage clears both. We do not use these events for advertising or share them with anyone.
  • Email contacts. We keep one list, for occasional announcements about major LevelSage releases — a few times a year at most, sent by LevelSage and by nobody else. There are exactly two places you can join it, and both are a box or a button you have to choose: an unticked checkbox when you sign up, and a prompt at the end of a chapter when you have finished the last lesson available in it. Neither is preselected, and saying no (or ignoring it) changes nothing about your account, your progress, or what the product does for you. For each address we store the address itself, which of those two places it came from, the wording you agreed to, when you agreed, and delivery events for the messages we send (sent, opened at the mail provider, unsubscribed). Every such message carries an unsubscribe link, and unsubscribing takes effect immediately. This is kept separate from the transactional mail your account needs (sign-in confirmations, password resets, security notices).
  • Browser-local data. Your Supabase auth session is stored in your browser's localStorage so you stay signed in across reloads. We also store small UI preferences (e.g. companion-rail collapse state), your answer to the analytics question, and, only if that answer was yes, the analytics identifier described above. Nothing here is strictly necessary except the auth session you asked for by signing in. No tracking cookies are set and no third-party storage is used.
  • Operational logs. Standard server logs (request paths, response codes, durations, the verified user id from your JWT). These do not include flag contents or methodology text.

Why we process it, and on what legal basis

Under Article 6 GDPR every purpose needs a lawful basis. Ours are:

  • Running your account — authentication, profile, progression, lab and Trial attempts, issuing and verifying credentials, and the transactional email that goes with them. Basis: performance of a contract, Art 6(1)(b).
  • Keeping the platform safe and working — security logging, abuse prevention, rate limiting, multi-factor authentication, and first-party usage analytics used to fix what is broken. Basis: legitimate interests, Art 6(1)(f) — our interest in a service that works and is not abused, balanced against your interests; we hold a written balancing test and will share it on request. You can object to this processing at any time (see Your rights). Storing the persistent analytics identifier on your device is a separate question under Art 5(3) of the ePrivacy Directive, which exempts only what is strictly necessary. It is therefore asked for and stored on consent, and declining it does not switch off anything you came here to use.
  • Sage's memory and personalised coaching — the notes Sage keeps about how you learn. Off by default. Basis: consent, Art 6(1)(a), given when you switch memory on and withdrawable by switching it off or clearing it.
  • Release-announcement email — the one list described above. Basis: consent, Art 6(1)(a), plus the ePrivacy rules on marketing mail. It is never required to use LevelSage, the checkbox is unticked when you meet it, and withdrawing is the unsubscribe link in any message.
  • Issuing a credential and its verification token — a passing Trial produces a Credential row and a token at /verify/<token>. That is the thing you came for, so the basis is performance of a contract, Art 6(1)(b). The token is readable only by someone you hand it to, nothing is listed publicly, and you can ask us to revoke it at any time — a revoked token resolves to a clean not-found.

Withdrawing a consent does not affect processing that already happened on the basis of it before withdrawal.

Who receives it

Processors — they act only on our instructions, under a data-processing agreement, and pass data to no one else:

  • Supabase — authentication, database, and row-level security (project hosted in eu-west-1).
  • DigitalOcean — hosting (App Platform, ams region) for the web app and the WebSocket server.
  • Cloudflare — DNS and edge for the domain.
  • Resend — delivery of transactional and product-update email (EU sending region).
  • Zoho — our EU-hosted mailbox, where a message you send us is received and kept.

Identity providers — independent controllers, not our processors. If you choose to sign in with Google or GitHub, we exchange a standard OAuth identity token with them; we never see your provider password. When you use them they also process your data for their own purposes, under their own privacy policies, and we are not responsible for that processing. Signing up with an email address and password avoids it entirely.

Sage currently answers from a library of explanations we wrote and store ourselves — no third-party AI provider is involved. If that changes, we will name the provider here and update the effective date before any conversation is sent to it.

We do not sell or rent your data, and we do not use it for advertising, profiling for third parties, or third-party marketing.

Where your data goes

We deliberately choose EU regions: the database is in eu-west-1, hosting in ams, mail sending in the EU, and our own mailbox is EU-hosted. That is where the data sits.

It is not the whole story, and we would rather say so than imply otherwise. Supabase, DigitalOcean, Cloudflare and Resend are US-controlled companies, so support and engineering access from outside the EEA can occur even when storage is European. For those transfers we rely on the transfer terms in each provider's data-processing agreement — the European Commission's Standard Contractual Clauses (2021), and, where the provider holds one, its certification under the EU–US Data Privacy Framework. You can ask us at the contact address below which mechanism applies to which provider.

Retention and deletion

We keep your account data for as long as your account is active. You can delete your account yourself from the Account tab in Settings; you can also ask us to do it at the contact address below. Either way we delete your profile, your activity rows, your Sage conversations and memory, and your authentication record within 30 days. Public Credentials you have already shared can be revoked on request — once revoked, the public verification token resolves to a clean not-found.

For everything else we keep the data no longer than the purpose needs, on these criteria:

  • Server logs — kept on the hosting provider's rolling retention for operational and security triage, and not joined to your identity for analytics.
  • Usage analytics — kept while they are useful for improving the product; deleted with your account, and, for events recorded before you had an account, no longer identifiable to you once the browser identifier is cleared.
  • Email contacts — kept until you unsubscribe, then only the record needed to honour the unsubscribe.
  • Support mail — kept as long as needed to handle the matter and any follow-up.

Your rights

If you are in the EEA or the UK, the GDPR / UK GDPR gives you the rights below. If you are elsewhere, they apply to you anyway — we run the platform under one policy, not two. You can ask us to:

  • show you the data we hold about you (access, Art 15);
  • correct anything inaccurate — or update it yourself from your profile (rectification, Art 16);
  • delete your account and the data attached to it — self-serve from the Account tab in Settings (erasure, Art 17);
  • export your data in a portable format — self-serve from the Data tab in Settings (portability, Art 20);
  • restrict how we process it while a dispute is resolved (Art 18);
  • object to processing we base on legitimate interests, including the usage analytics described above (Art 21);
  • withdraw a consent you gave — Sage's memory, product-update email, or publishing a credential — without affecting what we lawfully did before you withdrew it (Art 7(3)).

We answer rights requests within one month of receiving them, as Article 12(3) requires; in practice we aim for five business days. If a request is complex we may extend by up to two further months and will tell you why within the first month.

You can also complain to a data-protection authority. Ours is the Belgian Data Protection Authority — Autorité de protection des données / Gegevensbeschermingsautoriteit, Rue de la Presse 35 / Drukpersstraat 35, 1000 Brussels, dataprotectionauthority.be. You may instead complain to the supervisory authority of the EU member state where you live or work. You do not have to contact us first, though we would rather fix it than have you need to.

Sage, and what he is not

Sage is an AI system, not a human being. Everything he says to you is machine-generated, and he can be wrong — check anything that matters. He coaches; he never invigilates, scores, or reports on you, and he is firewalled out of the Trial entirely. We do not make automated decisions with legal or similarly significant effects about you.

Multi-factor authentication

You can opt into TOTP-based MFA from your account. The factor is enrolled and verified through Supabase Auth; we never compute, store, or transmit your authenticator's shared secret beyond the one-time enrolment payload required to set up the factor. If you lose access to your authenticator, contact us at the address in Contact below — we verify your identity through your registered email and can reset the factor for you. Step-up: any session that has not satisfied the second factor is gated at the surface boundary and cannot read account data.

Security

Passwords are managed by Supabase Auth (bcrypt with per-row salts; we never handle plaintext). Sessions ride a verified JWT, validated server-side via JWKS. Access to your rows is enforced in the database itself by row-level security, not only in application code. All traffic is HTTPS / WSS. The lab and Trial environments are designed to be isolated per attempt; the broader threat model is part of an ongoing security posture rather than a finished claim — please report issues to the contact below.

Children

You must be at least 13 to use LevelSage, and at least 16 in the EEA. That EEA line is our own choice and is stricter than Belgian law, which sets the age for a child's consent at 13. We do not knowingly collect data from anyone below these ages; if you believe a younger person has created an account, contact us and we will delete it.

Changes

If we change this policy, we post the change here and update the effective date at the top of the page. Material changes to data handling are also surfaced inside the app the next time you sign in.

Contact

Questions, rights requests, or security reports go to [email protected]. Rights requests are answered within the deadline set out above; for anything else we aim to respond within five business days.