NetzSec Logo
Security

Nothing hidden.
Everything on the
record

A clear, database-backed view of what we store, why we store it, and how we protect it.

30 record groups7 hard exclusions0 ad profiles
The trust core

Your account is the perimeter.
Nothing else gets in.

Scripts, devices, webhooks, support tickets, licenses: every record you create sits inside your account, encrypted at rest and in transit, and sealed at the same boundary the rings expand from.

  • Role-based access across scripts, devices, and support tools
  • No hidden telemetry: no covert tracking of script runs or device activity
  • Schema-mapped transparency: see exactly what we store, below
Your dashboard/ 01

What an account is for.
Everything a login unlocks — and why you never need one to use the hardware.

Account securityAuthentication protects your workspace and enforces role-based access across scripts, devices, and support tools.
Script & library workspaceScripts, themes, and library items you publish — with their descriptions, tags, and visibility settings — live in your private workspace and need a login to manage.
Devices & licensesDevices, licenses, and provisioning status are tied to your account so you can manage hardware and digital access securely.
Webhooks & integrationsWebhooks and their payloads are stored per account, so only you can view or rotate them.
Support ticketsSupport tickets and replies are private records linked to your account, so we can help without exposing your data.
NotificationsSecurity alerts, product updates, and ticket replies are delivered only to authenticated users.
Community interactionsReviews, ratings, and messages across scripts, themes, and the library need authentication to prevent abuse and keep feedback trustworthy.
Certification & badgesExam attempts and the badges they issue are tied to an account, so a credential can be verified and, if needed, revoked.
Abuse preventionCooldowns and infractions protect the platform from spam and misuse while keeping audit trails scoped to accounts.

An account is optional. Every feature above needs a login because each one stores something private to you — there is no way to keep a workspace yours without knowing it is yours. But the hardware and firmware you bought work without any of it. Buy in ghost mode and no account is ever created; see the ghost-mode note below.

Full transparency/ 02

What data we store.
Pick a product. Every table it keeps, mapped one to one.

The hardware platform with accounts, licensing, and the dashboard. Every table below lives in the ZeroTrace backend.

always

Written for every account. This is the minimum needed to sign you in and keep your device working.

only if used

Not required, and empty until you act. The column exists in the schema, but nothing is written unless you turn that feature on. You can buy, activate, and use a ZeroTrace device without filling in a single one of them.

users
4 fields

There is no email column. An account is a username and a password hash.

  • usernamealwaysPrimary account identifier
  • passwordalwaysStored only as a hash
  • rolealwaysAccess control
  • totp_secretonly if usedOnly if you turn on two-factor authentication
sessions
2 fields
  • keyalwaysSigned-in session token
  • expires_atalwaysAutomatic logout
licenses
4 fields
  • key, license_hashalwaysLicense plus its BLAKE2b lookup hash
  • bound_hwidonly if usedOnly for licensed desktop tools — a hash of your machine, never the raw serials
  • reasonalwaysWhy the row exists (purchase or regen)
  • expires_at, revoked_atonly if usedValidity window and soft-delete, once either applies
devices
5 fields

For a ghost-mode order this is the only row that exists anywhere — see below.

  • device_type, statusalwaysWhat you bought and where it is in fulfillment
  • device_nameonly if usedOnly if you name the device yourself
  • device_licenseonly if usedPer-device license and expiry, for products that use one
  • is_ghost_mode, ghost_keyonly if usedOnly if you chose ghost mode at checkout
  • ghost_claimed_atonly if usedOnly if you later claim a ghost order onto an account, which you never have to do
devices · shipping
4 fields

Your address normally lives at Stripe and goes straight to DHL. These columns stay empty unless a delivery fails and we correct it by hand.

  • shipping_countryalwaysDestination country, for customs and shipping rules (physical orders)
  • shipping_name, street, line2only if usedWritten only when staff manually correct an address a carrier rejected
  • city, postal_code, stateonly if usedSame — manual correction only
  • shipping_id, courier, invoice_idalwaysTracking number, carrier, and the checkout reference
shipment_attempts
3 fields

One row per attempt to create or validate a label, so a failed delivery can be traced.

  • invoice_id, source, modealwaysWhich order, and what triggered the attempt
  • result, shipment_numberalwaysOutcome and the resulting tracking number
  • error_message, validation_messagesonly if usedOnly present when the carrier rejected something
scripts
4 fields

Only exists if you write and save one.

  • title, content, descriptiononly if usedYour work, only what you choose to save
  • mode, operating_systemonly if usedRuntime targeting
  • visibility, tagsonly if usedPrivate, unlisted, or public — you decide
  • votes, downloads, flagsonly if usedUsage and moderation state, once you share it
script_interactions
2 fields

Only exists if you vote, rate, or comment.

  • interaction_typeonly if usedVote, rating, or comment
  • rating, messageonly if usedCommunity feedback
themes
3 fields

Only exists if you build and save one.

  • title, description, paletteonly if usedShared theme content
  • visibility, tagsonly if usedDiscovery controls
  • votes, downloadsonly if usedUsage counts, once you share it
theme_interactions
2 fields

Only exists if you vote, rate, or comment.

  • interaction_typeonly if usedVote, rating, or comment
  • rating, messageonly if usedCommunity feedback
library_items
4 fields

Payloads, presets, and configs you publish to the shared library. Only exists if you publish one.

  • type, title, descriptiononly if usedWhat you published and how it is listed
  • payload, payload_bytesonly if usedThe item itself, exactly as you submitted it
  • tags, min_firmwareonly if usedDiscovery and compatibility hints
  • downloads, likes, votes, statusonly if usedUsage counts and moderation state
library_interactions
2 fields

Only exists if you like, favorite, rate, comment, or report an item.

  • interaction_typeonly if usedLike, favorite, rating, comment, or report
  • rating, messageonly if usedCommunity feedback
webhooks
2 fields

Only exists if you create an integration.

  • api_idonly if usedIntegration identifier
  • contentonly if usedPayloads you choose to store
messages
3 fields

Only exists if you post.

  • username, roleonly if usedSender context
  • contentonly if usedMessage body
  • reactions, repliesonly if usedInteractions and reply links
tickets
2 fields

Only exists if you contact support.

  • subject, descriptiononly if usedWhat you reported
  • status, priorityonly if usedWorkflow state
ticket_messages
2 fields

Only exists if you contact support.

  • messageonly if usedReply body
  • roleonly if usedYou or support staff
notifications
2 fields
  • title, bodyalwaysImportant updates about your account and orders
  • is_readalwaysTracks what you have seen
infractions
2 fields

Only exists if a rule is broken.

  • type, reasononly if usedPolicy enforcement
  • details, expires_atonly if usedContext and auto-expiry
cooldowns
2 fields

Only exists if you hit a rate limit.

  • actiononly if usedRate-limited action
  • expires_atonly if usedWhen the limit lifts
airleak_tokens
2 fields

Only exists if you generate an upload token. AirLeak works fully without one.

  • token_hash, prefixonly if usedHashed API token — we never hold the token itself
  • last_used_atonly if usedMost recent use
airleak_runs
5 fields

Only exists if you upload a drive. Capturing and keeping it on your phone creates nothing here.

  • started_at, finished_atonly if usedScan run window
  • row_count, new_networks, statusonly if usedRun results
  • trackonly if usedThe route you drove, as uploaded
  • device_model, device_brandonly if usedWhich phone uploaded it
  • file_hash, file_bytesonly if usedIntegrity check and size — the uploaded file itself is deleted after processing
airleak_networks
4 fields

Only exists if you upload a drive.

  • bssid, ssidonly if usedWireless network identifiers
  • encryption, channel, typeonly if usedRadio characteristics
  • best_lat, best_lononly if usedStrongest observed location — coarsened to ~110 m before anyone else sees it
  • first_seen, last_seen, obs_countonly if usedObservation history
airleak_discoveries
3 fields

Only exists if you upload a drive. Private to you until you separately choose to publish.

  • bssid, country, stateonly if usedNetwork and coarse region
  • published, flaggedonly if usedSharing and moderation state
  • discovered_atonly if usedWhen you found it
exam_attempts
3 fields

Only exists if you sit an exam.

  • questions, answersonly if usedYour exam submission
  • score, passedonly if usedResult
  • integrity_eventsonly if usedAnti-cheat signals during the attempt (tab switches, fullscreen exits, blocked copy/paste)
badges
5 fields

Only exists if you pass an exam. Issued public so the badge can be verified — you can make it private at any time.

  • public_idonly if usedThe verification link for your badge
  • holder_nameonly if usedOnly the name you choose to print on it
  • publiconly if usedPublic by default; switch it off and the link stops resolving
  • issued_at, expires_atonly if usedValidity window
  • revoked_at, reasononly if usedRevocation record
redeem_codes
3 fields

Reseller and voucher codes. Nothing links to you until you redeem one.

  • code, product_name, batch_idalwaysThe code and what it grants
  • reseller_name, noteonly if usedWhich partner a batch was issued to
  • redeemed_by, redeemed_atonly if usedWritten only at the moment you redeem it
ghost_license_tokens
2 fields

A short-lived, single-use token that hands you your ghost licence after checkout. It expires, and it is not linked to any account.

  • token, licenseonly if usedOnly if you chose ghost mode — both stored as secrets
  • expires_at, used_atonly if usedOne use, then it is dead
withdrawals
5 fields

Only exists if you file a cancellation or return. This is the one place we store an email address.

  • emailonly if usedSo we can reply to your request
  • reference_number, statusonly if usedRequest tracking
  • declaration_text, reason, languageonly if usedThe withdrawal declaration exactly as you submitted it
  • refund_amount, currencyonly if usedRefund total — no card data, ever
  • itemsonly if usedReturned products and condition
stripe_events
2 fields
  • event_id, event_typealwaysStripe event, for dedup only
  • processed_atalwaysWhen we handled it
platform
4 fields

Catalog and content tables. No personal data in any of them.

  • products, packagesalwaysCatalog and shipping presets
  • announcements, changelogalwaysPublic change history
  • versionsalwaysRelease tracking
  • certificationsalwaysExam definitions — questions, thresholds, and time limits
Ghost mode

One row. That is the whole record.

If you check out in ghost mode, we never create an account for you. There is no row in users, none in sessions, and nothing that ties the order to a person. The only thing written to our database is a single devices row holding: what you bought, its fulfillment status, the destination country, the Stripe checkout reference, and the ghost licence you were handed at checkout.

Your name and delivery address are not in it. They stay at Stripe and are passed to DHL to print the label — the only exception is a carrier rejecting an address, where we store the corrected version on that order so the parcel can go out.

The licence is the only thing connecting you to the device, and it is yours to keep or discard. You can later claim a ghost order onto an account if you want the dashboard, warranty history, and support tied to it — but nothing about the product requires you to, and if you never do, that one row is all that ever exists.

Privacy guardrails/ 03

What we don't store.
Nothing below has a place in our core account database.

Data lifecycle/ 04

Built-in expiry & auditability.
Expiry fields and timestamps define how long data persists.

Expiring sessionsSessions include explicit expiry timestamps to limit how long tokens remain valid.
Time-bound governanceInfractions and cooldowns include expiry fields, so restrictions can be lifted automatically.
Auditable timestampsMost tables include created-at and updated-at fields to support auditability and change tracking.
License windowsLicenses track expiration dates so access is granted only for valid periods.
How we protect you/ 05

Security measures.
Controls designed to reduce risk and protect sensitive data.

Authentication hardeningPasswords are stored as non-reversible hashes, and accounts can be protected with optional TOTP two-factor authentication.
Secure infrastructureDedicated servers, hardened configurations, and regular OS updates protect services at the machine level.
Database controlsStrict access controls and audited schema changes limit who can reach sensitive data.
Least-privilege accessRole-based permissions reduce blast radius and keep user data isolated.
Secure developmentWe apply secure-by-default coding practices and review sensitive changes before release.
Session safetySession expiry and rotation reduce exposure if a token is ever compromised.
Transparency/ 06

Public accountability.
Changes, audits, and policy updates, documented in public.

Announcements & changelogMajor changes, fixes, and policy updates are posted in a clear public record.
Independent auditsWhen we commission third-party audits, we publish summaries and the full reports.
Incident disclosureIf user data is at risk, we disclose what happened and what we changed to fix it.
Data minimizationWe follow a privacy-first approach inspired by leaders like Mullvad: collect only what we need.
Still curious?

Security is a conversation, not a page.

If anything here is unclear, or you think we can do better, tell us. Transparency only works when it goes both ways.