Security

Your test evidence, handled with care

KwikQA runs on your machine. Only a redacted, size-limited evidence packet you have previewed and approved ever leaves it. The hosted service doesn't store it, and the AI providers that answer it don't keep it.

At a glance

  • Local first. Reports, traces, source, and git history are read on your machine. Run records, patches, and validation output stay there.
  • You approve every request. Each AI request shows a preview first; declining sends nothing.
  • Nothing stored. The hosted service never stores your evidence, your source code, or the model's answer.
  • Zero data retention. Hosted requests go only to AI endpoints that keep neither the request nor the answer, and the service refuses any request that doesn't ask for that.
  • Minimal account data. A GitHub id and username, your plan, and metadata about each request. No email address, no GitHub token, no analytics.

Where your data goes

StepWhat happensWhat is kept
Your machineThe CLI reads your failing tests' reports, builds the evidence packet, redacts it, and shows you the preview.Run records, captures, patches, and journals, in .kwikqa/
KwikQA service (Cloudflare)Checks your token, plan, and limits; checks that the request uses the configured model, endpoint, output cap, and reasoning effort, with no tools or fallbacks, and asks for zero data retention; counts it; and forwards it unchanged.Request metadata and a SHA-256 hash of the request. The answer is held in memory until your CLI collects it, for at most 15 minutes.
OpenRouterRoutes the request to the one endpoint named in the preview, with no fallback to another.Request metadata such as token counts and timing; no content, with prompt logging off
Model endpointClaude on Google Cloud Vertex AI, or GPT on Microsoft Azure for a repair retry, produces the answer.Nothing, under a zero-data-retention policy

On bring-your-own-key plans the service step is skipped: requests go from your machine straight to OpenRouter with your own key, and the CLI reports only each request's kind, model, provider, and test framework to KwikQA, so it counts toward your plan.

The evidence packet

For each AI request, KwikQA builds an evidence packet on your machine from your failing tests only; passing tests are only counted. It contains:

  • selected report fields: test titles, files, projects, errors, and expected and received values;
  • trace events, or the Cypress and WebdriverIO command log;
  • the page elements around each failed locator, and the accessibility snapshot of the page at the failure;
  • network requests around the failure (method, URL, status, and headers, with sensitive headers removed; never request or response bodies) and console errors;
  • short source excerpts around the failing lines; and
  • recent code changes that mention the failure, described below.

It never contains full files, full diffs, your repository, the full page DOM, or image pixels: screenshots and videos are described by size and dimensions only. The packet is capped in size, and items the request policy doesn't allow are withheld and counted in the preview. With --capture, Playwright adds the locators it generated for elements on the live page; Cypress and WebdriverIO record each failed attempt's page into .kwikqa/capture/ on your machine, and only the parts around the failure enter the packet. Run npx kwikqa analyze --local to see what KwikQA would build without sending anything.

Recent code changes

To tell a deliberately changed app from a broken one, KwikQA searches your uncommitted changes and your branch's recent commits for changed lines that contain what the failure names: locator text and test ids, expected and received values, and failed request paths. Only matching hunks of source files are kept (at most 12, and 24 KB in all), each with its commit's subject line, along with the subjects of the commits searched (at most 20) and the names of source files with uncommitted changes. Author names, emails, commit bodies, and documentation are never read. --no-changes leaves code changes out.

Redaction, and its limits

Before you see the preview, the CLI removes and counts:

  • values of password, token, and other sensitive form fields and elements, including text typed into password, token, or card fields during a capture;
  • Authorization, Cookie, Set-Cookie, and other sensitive headers;
  • usernames and passwords in URLs, and sensitive query parameters; and
  • values assigned to names like password, passwd, secret, token, api-key, and apikey.

Redaction recognizes credentials by their names and places. It is not a general scanner for personal data: names, email addresses, or account numbers in your test data or on the pages under test, and a secret stored under an ordinary name, can still appear in the packet. Test with data you may share, read the preview, and decline a request you don't want to send.

The preview shows the destination, the model and its endpoint, whether it asks for zero data retention, the evidence and redaction counts, the cost estimate and cap, and a hash of the exact payload. Approving sends exactly that payload; the service forwards it byte for byte. Declining sends nothing and costs nothing. --yes pre-approves requests for unattended runs such as CI, but applying a patch needs a person's approval, and fix refuses to run without one. The one exception is a fix in CI under a ci.fix policy you commit: it patches only the CI runner's own checkout, and its repair arrives as a draft pull request, through your code host's API with your job's own token, which a person must merge. KwikQA's service never holds a token that can write to your repository.

Zero data retention

Every hosted request is routed only to an AI endpoint with a zero-data-retention policy: one that processes the request to produce the answer and keeps neither afterwards, so neither is used to train models. Three checks enforce it:

  1. The model routes the service publishes require zero data retention, and the CLI asks OpenRouter for it in each request (provider.zdr).
  2. The service refuses any hosted request that doesn't ask for it.
  3. OpenRouter sends a request that asks for it only to an endpoint whose policy is zero retention, and refuses it otherwise, with no fallback to another endpoint.

Today that means Claude on Google Cloud Vertex AI and GPT on Microsoft Azure. OpenRouter's own prompt logging is off, so OpenRouter keeps request metadata but not content. A nightly check against the live service fails if a route stops asking for zero retention. These are the providers' commitments, under their terms with OpenRouter; we check every request, but we can't inspect their systems.

On bring-your-own-key plans, requests use your own OpenRouter account and its privacy settings. KwikQA's default routes ask for zero data retention there too; a route you set with KWIKQA_DIAGNOSIS_MODEL or KWIKQA_REPAIR_MODEL doesn't.

What the service stores, and for how long

RecordContentsKept
Account and planGitHub id and username, plan, seats, billing period, Paddle identifiersUntil you delete your account
Request recordsTime, kind, model, provider, test framework, status, whether it counted, token counts, cost, payload hash13 months
Monthly usage countersAnalyses and fixes used each month13 months
Model jobsAccount, request id, and status in storage; the answer in memory onlyUntil your CLI collects the answer; at most 15 minutes
Analysis sessionsHow many requests one analysis or fix may make90 days after they close
Retry ticketsOne-use tickets for a repair retry90 days
Website sessionsSession hash and expiry30 days
CLI and CI tokensToken hash, name, created and last usedUntil revoked, then 90 days
TeamsInvited usernames and membersUntil removed, or the account is deleted
Team insights (opt-in)Test titles, files, projects, framework, fix outcomes, changed-line counts13 months, or until the team's owner deletes them
Refund recordsWhich billing period was refunded, so a refund is never paid twiceUntil the account is deleted
Evidence, source code, model answersNot storedNever

A daily job deletes records as they expire. Deleting your account from the dashboard removes all of its records at once. The database's primary copy is in Cloudflare's Asia-Pacific region.

Encryption

  • In transit: the website, the service, and every provider it calls use HTTPS only. The site sends HSTS for a year, including subdomains, and its cookies use the __Host- prefix, so browsers send them only over HTTPS to kwikqa.com.
  • At rest: Cloudflare encrypts the database (with AES-256) and job storage.
  • Hashed: CLI and CI tokens and website sessions are stored only as SHA-256 hashes. A token is shown once, when it is created.
  • Service credentials: the OpenRouter, Paddle, and GitHub credentials are stored as encrypted Cloudflare secrets, never in source code.

Accounts and access

  • Sign-in uses GitHub with the read:user scope only. KwikQA reads your numeric id and username at each sign-in; the GitHub token is never stored, and KwikQA gets no access to your repositories.
  • You can see and revoke every token from the dashboard. npx kwikqa logout revokes the CLI's token.
  • On your machine, the CLI keeps its token in your user configuration directory, readable only by you, never in a repository. In CI, use a CI token in a secret variable.
  • Website session cookies are HttpOnly, Secure, and SameSite=Lax, and every change must come from the KwikQA site itself.
  • Only KwikQA's operator can reach the production systems. The operator view shows aggregate usage and cost, and the usernames, usage, and cost of the most active accounts. Nobody at KwikQA can see your evidence, because it isn't stored.

Application security

  • The website sends a strict content security policy: scripts, styles, and fonts load only from kwikqa.com, images also from GitHub's avatar server, and the site can't be framed. The checkout page also allows Paddle's checkout. There are no analytics or advertising scripts.
  • It also sends X-Content-Type-Options: nosniff, Referrer-Policy: strict-origin-when-cross-origin, and a permissions policy that turns off the camera, microphone, location, and payment APIs. Dashboard pages are never cached.
  • Plans change only from Paddle's signed notifications, verified in constant time, or from Paddle's answer to a change you confirmed. Each refund is recorded before it is requested, so it can't be paid twice.
  • The service accepts a request only for the configured model and endpoint, within its output cap and at its reasoning effort, with no tools, streaming, or fallbacks. Before asking you, the CLI also checks the request's size and estimated cost against caps the service publishes.
  • The npm package has no runtime dependencies and no install scripts. The open-source code bundled into it is listed with its licenses in THIRD_PARTY_NOTICES.md.

On your machine

Run records, captures, the transaction journal for each applied patch, and validation output stay in .kwikqa/ in your project. Rollback restores exactly the bytes KwikQA changed and refuses to overwrite edits you made after the patch was applied. The CLI sends no telemetry.

Logging and monitoring

The service doesn't log request content. When a request fails unexpectedly, it logs only the method, path, and kind of error. Cloudflare processes IP addresses to deliver the service and protect it from attacks; KwikQA doesn't store them. A nightly check runs a real analysis through the live service and confirms that every model route still works and asks for zero data retention.

Incident response

If we learn of a security incident, we contain it, revoke and rotate any affected credentials, and investigate. If personal data is affected, we tell the people affected and the authorities the law requires, including the Data Protection Board of India, without undue delay and within the time the law sets. Because evidence and source code are never stored, they can't be exposed by a breach of our service.

Service providers

ProviderPurposeData
CloudflareHosting, database, job storage, and network protectionAccount, usage, and request records; IP addresses, in transit
OpenRouterModel routingEvidence packets, in transit; request metadata
Google Cloud Vertex AIClaude, with zero data retentionEvidence packets, in transit
Microsoft AzureGPT repair retries, with zero data retentionEvidence packets, in transit
PaddleMerchant of record: payments, tax, invoices, refundsBilling details
GitHubSign-in and profile picturesGitHub identity

We'll update this list before a new provider receives your evidence. The privacy policy explains your rights over this data.

Certifications

KwikQA doesn't hold a SOC 2 report or ISO 27001 certification. Our infrastructure providers publish their own certifications. Email security@kwikqa.com for a security questionnaire, or with questions about this page.

Reporting a vulnerability

Email security@kwikqa.com with the details and steps to reproduce. We aim to acknowledge reports within three business days and will keep you informed while we fix the issue. Test only against your own account, don't access other people's data or disrupt the service, and give us a reasonable time to fix the issue before you disclose it. We won't take legal action against research done in good faith under these rules.