Privacy Policy

Qopanza is operated from the United States and hosts your data there. The Service is offered to businesses in the United States. If you are in the United Kingdom or the European Economic Area, email support@qopanza.com before using the Service — the GDPR gives you rights this policy does not yet describe, and we would rather say so than let you assume otherwise.

Effective date: 8 September 2026 Last updated: 2 October 2026


1. Who we are

Gsente LLC (“we”, “us”), a limited liability company registered in Colorado under company number 20238145743, registered office 3750 Blake St, Denver, CO 80205, operates the Qopanza post-quantum cryptography scanning and key management service (the “Service”).

For questions about this policy or to exercise any right described in section 9, contact support@qopanza.com.

We have not appointed a Data Protection Officer or an EU/UK representative, because we are a US company processing in the United States and neither is required of us. If that changes — if we begin offering the Service into the EEA or the UK — this section changes first, and before any such customer is onboarded.

2. The two roles we play, and why the distinction matters to you

This Service handles two different categories of data under two different legal roles. Read this section before section 3 — it determines who is answerable for what.

We are the controller of the data we need in order to run a business: your email address, your account and plan, billing identifiers, security logs, and support correspondence. We decide why and how that data is processed, and this policy governs it.

We are the processor of the material you submit for scanning: your source code excerpts, file paths, repository URLs, hostnames, keys and secrets you store with us. You (or your employer) remain the controller of that material. We process it only on your documented instructions — which, in practice, are the actions you take in the product. Those terms are set out in the Data Processing Addendum (dpa.md), which forms part of your contract with us if you are a business customer subject to UK/EU GDPR.

This matters practically: if your source code contains personal data about someone else and they make a request about it, that request goes to you, not to us — and we will help you answer it.

3. What we collect

This table is generated from the actual database schema, not from a template. Fields marked encrypted use application-layer encryption at rest in addition to disk encryption (see docs/field-encryption.md).

3.1 Account and identity — we are the controller

DataStored inNotes
Email addressusers.emailAccount identity and notification address
Password hashusers.password_hashArgon2id. We never store, log or transmit the password itself
SSO subject and providerusers.oidc_subject, users.oidc_providerOnly if you sign in with SSO
Roleusers.roleadmin / member, for access control
Password change time, session epochusers.password_changed_at, users.session_epochUsed to invalidate sessions after a password change
Organisation nameaccounts.nameOptional, supplied by you
Planaccounts.planFree / paid tier
Password reset tokenspassword_reset_tokens.token_hashHashed; single use; expire

3.2 Billing — we are the controller

DataStored inNotes
Stripe customer IDaccounts.stripe_customer_idA reference, not a payment method
Stripe subscription IDaccounts.stripe_subscription_idSame

We never see, receive or store your card number, CVC or bank details. Payment card data goes directly from your browser to Stripe and does not transit our servers. What we hold is an opaque identifier that lets us ask Stripe about your subscription status.

3.3 Scan content — we are the processor, and this is the sensitive part

DataStored inNotes
Source code excerptcrypto_assets.evidenceUp to 200 characters of the line of your source code that triggered a finding. See 3.3.1
File path and line numbercrypto_assets.location, .line_numberPaths from inside your repository
Detected algorithm, key size, severitycrypto_assets.*Derived, not raw content
Scan targetscan_runs.targetA repository URL, hostname or endpoint you submitted
Scan errorsscan_runs.errorClassified verdicts, not raw tool output — see 3.3.2
Repository URL and branchrepository_connections.repository_url, .branchFor continuous discovery
Repository access tokenrepository_connections.access_tokenEncrypted. See 3.3.3
Token hintrepository_connections.token_hintLast four characters only, so you can identify which token it is
Migration plans and stepsmigration_plans, migration_plan_itemsIncludes the file paths above
"Fix it for me" changes (Pro, only if you use it)autofix_runs.changesThe full contents of each file the fix changes, before and after — typically one to three files, at most eight. Encrypted. Kept so an undo restores exactly what was there. See 5
Site-to-repository choicessite_repositoriesWhich of your repositories builds which of your sites, as you told us
Netlify access tokennetlify_connections.access_tokenEncrypted. Issued by Netlify when you connect it; never returned by the Service

3.3.1 We store a fragment of your source code — stated plainly

When the scanner finds a use of cryptography, it records the line that matched, truncated to 200 characters, so that you can see why something was flagged without having to go and look it up. A finding with no evidence is a finding nobody trusts.

That fragment is your source code. It is stored in our database, it is returned to you through the API, and it appears in exports you generate. We consider this the most sensitive customer content in the system and it is covered by the DPA.

Two mitigations are built in rather than promised:

  • The application-security scanner, which is the component that looks for hardcoded secrets, redacts every value it matches before storing it (_redact in app/scanner/app_security.py): the first and last four characters, with the middle replaced. Enough to recognise which key it is, never enough to use it.
  • We do not keep a copy of your repository. Clones are shallow (--depth 1), written to a temporary directory, and removed in a finally block whether the scan succeeds or fails (app/scanner/repo_scanner.py). What persists is the findings, not the code.

3.3.2 Scan errors are classified, not echoed

Git's error output can contain an authenticated clone URL, which would mean a credential in a database column and a log line. The scanner classifies the failure and stores only the verdict — “authentication or access failed” or “clone failed” — never the underlying stderr.

3.3.3 Repository access tokens

If you connect a repository for continuous discovery, the access token you supply is encrypted at rest with application-layer envelope encryption and is never returned by any API endpoint, to you or to anyone else. The API returns only the last four characters. The token is injected into the clone URL in memory at scan time and is never persisted or logged in that form.

We ask you to supply a read-only token scoped to the specific repository. We cannot technically enforce that, which is why it is stated here and in the Terms.

3.4 Cryptographic material you store with us

DataStored inNotes
Public keyskeys.public_keyNot secret by design
Private keyskeys.secret_key_encryptedEncrypted under an envelope key
Stored secretssecrets.ciphertext_*, .nonceEncrypted
Certificates and their private keyscertificates.certificate_pem, .private_key_encryptedPrivate key encrypted
Webhook endpoint and signing secretwebhooks.url, .secret
Webhook payloads and delivery errorswebhook_deliveries.body, .last_errorRetained for retry and debugging

Where the deployment is configured for client-side (“zero-knowledge”) encryption, material encrypted on your side is opaque to us and we cannot decrypt it — including when compelled to. Where it is not, we hold the envelope key and we can. Which of these applies to your account is a configuration fact, and we will tell you which on request.

3.5 Security, audit and usage — we are the controller

DataStored inNotes
Audit logaudit_logAction, actor, resource, timestamp; detail is encrypted; entries are hash-chained so tampering is detectable
Per-day request countsusage_countersAggregate numbers, for plan limits
API key hashes and metadataapi_keys.key_hash, .key_prefix, .label, .last_used_atThe key itself is shown once at creation and never stored
API key IP allowlistapi_keys.ip_allowlistOnly if you configure one
IP addressesApplication logs; Redis throttle countersSee 3.6

3.6 IP addresses

We process the IP address of requests to sign-up, sign-in and the public scanner in order to rate-limit them. This is how the Service resists credential stuffing and abuse.

  • In Redis, as short-lived counters keyed by IP, which expire automatically.
  • In application log lines recording a throttling event.

An IP address is personal data under UK/EU GDPR. Our lawful basis is legitimate interests (Article 6(1)(f)) — specifically, keeping the Service available and other customers' accounts secure. We consider this a narrow, expected and low-impact use, but you have a right to object under section 9.

3.7 Support and sales

DataStored inNotes
Support ticket subject and messagesupport_ticketsEncrypted. Free text you write
Enterprise enquiry: company, message, contact emailenterprise_leadsEncrypted

These are encrypted at rest specifically because people paste credentials, tokens and configuration into support tickets. Please try not to — but the system is built on the assumption that you will.

3.8 Analytics on our public pages — only if you accept

On qopanza.com's public pages (the home page, the free scan, docs, pricing and the like), we ask whether you accept Google Analytics cookies. If you decline, or do not answer, nothing is sent to Google and no analytics cookie is set. If you accept, Google Analytics (Google LLC) receives:

  • the pages you visit, the page you came from, and roughly where you are (country and city, from your IP address — Google Analytics 4 does not log or store the IP address itself);
  • your device, browser and screen size;
  • these events, as counts and choices only: a scan started, a scan finished (how many problems, how many critical, the score), a "Fix it" click, a plan chosen, an account created (and whether with a password).

It never receives the address of a site you scanned, the findings, your email, or anything from inside the signed-in dashboard: analytics switches off when you sign in. Google signals and advertising features are off. Data is kept for 14 months.

You can change your mind at any time with Cookie settings at the bottom of the home page; declining after accepting deletes the analytics cookies from your browser.

3.9 What we do not collect

  • No cookies are set by the signed-in Service. Your dashboard session token is held in your browser's localStorage, which is strictly necessary to keep you signed in. The only cookies are the optional analytics cookies in 3.8, and only after you accept them.
  • No advertising or third-party tracking scripts, and no third-party JavaScript inside the signed-in dashboard. The one exception on public pages is Google Analytics, as in 3.8, with your consent.
  • No card data. See 3.2.
  • No special category data (health, biometrics, political opinions and so on) is requested. Do not put it in a support ticket or a scan target.

Analytics was added on 2 October 2026, as described in 3.8, with consent and only on public pages.

4. Why we process it, and on what lawful basis

PurposeDataLawful basis (UK/EU GDPR Art. 6)
Provide the Service you asked forAccount, scan content, keysContract, 6(1)(b)
Take paymentBilling identifiersContract, 6(1)(b)
Keep the Service secure and availableIP addresses, audit log, throttle countersLegitimate interests, 6(1)(f)
Answer your support requestsTicket contentContract, 6(1)(b)
Respond to sales enquiries you initiateEnterprise lead dataLegitimate interests, 6(1)(f)
Comply with law, tax, and lawful requestsAs requiredLegal obligation, 6(1)(c)
Send you product or marketing emailEmail addressConsent, 6(1)(a) — opt-in, withdrawable
Understand how visitors use our public pages (3.8)Analytics dataConsent, 6(1)(a) — asked first, withdrawable with Cookie settings

Service and security emails (a password reset, a key expiry warning, a breach notice) are not marketing and are sent under contract. You cannot opt out of those while you hold an account, because they are the mechanism by which we tell you something is wrong.

We do not sell personal data, and we do not share it for cross-context behavioural advertising — as those terms are defined under the CCPA/CPRA and comparable US state laws. We have never done so.

5. Automated processing and AI

The Service uses a large language model for two things: the explanation attached to an individual finding, and the written plan that accompanies a prioritised list of findings. Both are commentary on decisions already made. Four facts, all verifiable in the code:

  1. The AI does not decide anything. The remediation is produced by deterministic rules (app/scanner/hosting.py, app/migration/planner.py), and so is the priority order (app/ai/triage.py). The model is given the decision that has already been made and asked to describe it. If the model is unavailable, you get the same findings, the same order and the same fixes with no commentary.
  2. We do not send your source code to the AI provider. For a single finding, the prompt contains the algorithm name, the file path and line, the severity, the standard recommendation, the detected hosting platform, and the deterministic fix. For a prioritised plan, it contains up to 40 findings at once, each with its algorithm, file path, severity, quantum status, our replacement recommendation, and a classification of the path as production, non-production or sensitive.

In neither case does the prompt contain the evidence field — the excerpt of your code. That exclusion is structural rather than a filter applied at the end: the object the prompt is built from has no field for it, and a test fails if one is added (test_the_prompt_never_contains_source_code).

Because a plan covers many findings at once, one such request may contain the file paths of up to 40 files from your repository. See the note below on file paths.

  1. The suggested code changes are not written by the AI. Where the Service shows a before/after edit to one of your own lines, that edit is produced by a substitution table in app/scanner/code_fix.py, inside our systems. Your line is read from our database, changed here, and returned to you. It is not sent to the AI provider at any point, and no model is involved in producing it. Where a change cannot be made that way — because the replacement alters more than one line — the Service shows standalone example code written by us, not code derived from yours.
  2. The provider is Anthropic PBC (currently Anthropic, via api.anthropic.com), listed in subprocessors.md.
  3. "Fix it for me" is the exception to 2 and 3, and only when you use it. This Pro feature writes a fix into your own code. When you start it, we send the AI provider the full contents of the files the fix needs to change — at most eight, chosen by our rules (for example your server file and your build configuration) — together with the fix our rules produced. The model's proposed edits are then checked by our own code, which discards any that touch other files, add network calls, imports, executed code or secrets, and are shown to you; nothing is published to your site until you approve it. Nothing is sent to the AI provider unless you start "Fix it for me". Findings that are leaked keys are never handled this way.

Note that a file path is itself customer data and can be revealing (src/payments/acme_bank_integration.py), and that a prioritised plan sends up to 40 of them in a single request — enough to convey something about the shape of your codebase, not only about one file. If that is unacceptable for your threat model, AI features can be disabled for your account — contact us — and the Service works fully without them.

5.1 Automated processing that does not involve AI

Two further things are computed automatically, and neither uses a model or leaves our systems:

  • Whether a remediation was actually carried out. When you mark an item done, the Service compares that claim against your later scans of the same target and derives one of: claimed but not yet re-scanned, verified by a later scan, or still present despite the claim. It is computed from your own scan history each time it is read, not stored, so it changes when that history changes.
  • The priority order of findings, from severity, quantum status and the shape of the file path.

There is no automated decision-making producing legal or similarly significant effects about any individual within the meaning of Article

  1. Risk scores, priority orders and verification states describe code, not people.

6. Who we share it with

Only the sub-processors listed in subprocessors.md, which is kept current and is part of this policy by reference. Each is engaged under a written contract with confidentiality and security obligations, and processes data only on our instructions.

Which sub-processors apply to your deployment depends on what is configured — a self-hosted deployment with no Stripe key and no AI key uses neither.

Beyond those, we disclose personal data only:

  • when you tell us to (for example, a webhook you configured, which sends data to an endpoint you chose and are responsible for);
  • to professional advisers under a duty of confidence;
  • where required by law — and where we are legally permitted to tell you about it, we will;
  • in a merger, acquisition or asset sale, in which case this policy continues to apply until you are given notice of any change.

We will not hand over customer content in response to an informal request. Where a request is legally binding but appears overbroad, we will challenge it where we reasonably can.

7. International transfers

Primary hosting and data storage is in the United States (New York).

We do not transfer personal data outside the United States. Every sub-processor in subprocessors.md is a US entity processing in the United States: Stripe, Anthropic, Resend and DigitalOcean. There is no onward international transfer to describe, and so no transfer mechanism to rely on.

If that changes, this section and subprocessors.md change before the new sub-processor begins processing — that is the 30 days' notice in section 5 of our DPA, and it exists so a customer can object.

8. How long we keep it

Stated honestly: this Service currently performs no automated deletion of historical data. There is no scheduled pruning job. Scan runs, findings, audit log entries, webhook deliveries and usage counters are retained for as long as your account exists, until you delete them or delete the account.

We are treating that as a gap to close rather than a policy to defend, and the intended schedule is recorded in README.md under “Retention work still to do”. Until it ships, this section describes what the system actually does — which is the only thing a privacy policy is allowed to do.

What is implemented today:

DataActual behaviour
Everything belonging to an accountDeleted immediately and irreversibly on account erasure (section 9)
Redis throttle countersExpire automatically, minutes to hours
Password reset tokensExpire, and are deleted with the account
Repository clonesDeleted at the end of every scan, success or failure
Backups7 days, after which they roll off

Erasure removes data from the live database. Encrypted backups made before an erasure are not individually rewritten; they age out on the cycle above, and are not restored into production except in a disaster-recovery event.

9. Your rights

If you are in the UK or EEA you have rights of access, rectification, erasure, restriction, portability and objection, and a right to withdraw consent. If you are in California or another US state with comparable law, you have rights to know, delete, correct, and to opt out of sale or sharing — noting that we do neither.

You may exercise all of these regardless of where you live. We do not discriminate against anyone for exercising a right.

How to exercise them:

  • Access and portability — export your data from the dashboard, or ask us at support@qopanza.com.
  • Erasure — DELETE /v1/accounts, or ask us. This is a genuine hard deletion across every table, not a hidden flag. You can run a dry-run first that shows exactly what would be destroyed. It is immediate and irreversible, which is why it requires typed confirmation. It will refuse while you have a live Stripe subscription — cancel first, so that a data request never silently leaves you paying for an account that no longer exists, or silently cancels a subscription you meant to keep. When we erase your account we also destroy your audit log, including its tamper-evident hash chain. That is intentional: keeping it would mean keeping the email addresses inside it. Other customers' chains are unaffected. A single application log line records that an erasure happened, when, and how many rows went — with no personal data in it — because otherwise we could not later prove we did what you asked.
  • Rectification, restriction, objection, withdrawal of consent — support@qopanza.com.

We respond within one month, extendable by two further months for complex requests, and we will tell you if we need the extension.

If your request concerns personal data inside content you uploaded (source code, a support ticket), we act on your instruction as processor — see section 2.

Complaints. You can complain to us first at support@qopanza.com, and we would prefer that. You also have the right to complain to the Federal Trade Commission (reportfraud.ftc.gov) or to the Attorney General of your state, without contacting us first.

10. Security

Specific measures, not adjectives:

  • Passwords hashed with Argon2id; a minimum length of 12 characters and a character-variety rule enforced whenever a password is set. The policy is deliberately never applied at sign-in, so tightening it can never lock out an existing user.
  • Application-layer encryption on the most sensitive columns — repository tokens, support tickets, enterprise leads, audit detail — in addition to encryption at rest and TLS in transit.
  • Envelope encryption for private keys, optionally backed by HashiCorp Vault, AWS KMS, GCP KMS or Azure Key Vault.
  • Tamper-evident audit log: each entry commits to its predecessor, and the chain can be verified on demand.
  • Rate limiting and throttling on sign-up, sign-in and public scanning.
  • Per-key IP allowlisting available.
  • Outbound request guarding to prevent the scanner being used to reach internal network addresses.
  • API keys shown once, stored only as hashes.
  • Automated security scanning in CI.

No system is perfectly secure, and anyone who tells you otherwise is selling something. If a breach affects your personal data and presents a risk to you, we will notify the relevant supervisory authority within 72 hours where required, and tell you without undue delay.

To report a vulnerability, email security@qopanza.com. We will not pursue legal action against good-faith research conducted within our disclosure policy.

11. Children

The Service is for business use and is not directed at children. We do not knowingly collect data from anyone under 18. If you believe a child has given us data, contact us and we will delete it.

12. Changes

We will post any change here and update the date at the top. For a change that materially reduces your rights or expands our use of your data, we will give you at least 30 days' notice by email before it takes effect, so that you have time to export your data and leave if you disagree.

13. Contact

Gsente LLC 3750 Blake St, Denver, CO 80205 support@qopanza.com