DocsAccount and plan
Privacy and safety
What Vallit reads, sends to AI and keeps.
On this page
In short
- A check starts after you confirm that you own the app or its owner asked you to check it.
- Vallit uses reading methods and identifies itself as VallitBot. It does not sign in or submit changes to your app.
- A finding describes an exposure and where it was observed.
- Reports that no company holds, and monitoring results, are deleted after 90 days.
Permission first
The free check on vallit.net needs no account, but it starts only after you tick I own this app, or its owner asked me to check it. Its report shows the score and the kind of each finding; the details open once someone signs in and takes the report over. In the app, the page for your first app and the dialog that adds an app both ask for permission too. Neither adds the app until you tick I own this app, or its owner asked me to look after it. Vallit does not verify the tick.
When the page for your first app starts a check, your answer is stored with that check. The stored answer lets that check run the targeted checks. A check you start with Run a check runs them too. The dialog that adds an app starts no check and does not store the tick.
The daily check of an app on Watch or Care runs the targeted checks from the first day, on the tick you gave when you added the app. Their findings show their title and severity; where they sit and how to fix them stay hidden until the app's domain is confirmed. The requests are the same read-only ones, GET, HEAD and OPTIONS. Every app gets the same checks, whoever else added the domain. The daily check of an app on Free runs the targeted checks only once the app's domain is confirmed. The close watch and the AI sample need a confirmed domain as well. Confirming means adding a DNS record, which only someone who controls the domain can do. Confirm your domain shows how.
To stay a polite visitor, one domain can be checked three times an hour, counting its subdomains.
Reading requests and their limits
A check asks your app only for what any browser could ask for:
- the page at the address you gave, and the scripts it loads;
- a fixed list of addresses where apps leak files or admin tools by mistake, such as
/.env,/.git/config,/backup.sqland/server-status; - the certificate your server presents, and one short handshake each for TLS 1.0 and TLS 1.1, to see whether your server still accepts them. Nothing is sent over those connections;
- up to 12 of your own links with a test address in place of where they forward to, such as
/login?next=https://example.org/vallit-redirect-check. Vallit reads where your app would send a visitor and never follows the redirect, so example.org receives nothing.
Every checker request uses GET, HEAD or OPTIONS, which are intended for reading.
A server can still implement these methods with side effects. Each request carries this user agent, so your server logs show it was Vallit:
VallitBot/<major>.<release> (+https://vallit.net/bot; security and stability checks by request of the site owner)
- A check sends at most three requests at a time, at least 150 milliseconds apart.
- Each request stops after 10 seconds, reads at most 2 MB and follows at most five redirects.
- Vallit connects only to public addresses. It refuses private and local addresses, and cloud metadata addresses, where cloud servers keep their own credentials. It checks the address again when it connects and at every redirect.
Your database
When your pages carry a Supabase project address and its public key, Vallit asks up to ten tables for one row each. It uses the same public key your app hands to every visitor. It records whether a row came back, never the row.
With the same public key, Vallit reads the sign-in settings your Supabase project publishes to every browser, and asks your file storage for its list of buckets. It keeps the settings it reports on and the bucket names, never a file. Nothing is signed up and no file is listed or downloaded.
When your pages load files from a storage bucket on Amazon S3, Google Cloud Storage, Azure or Firebase, Vallit asks that bucket once for a list of one file. It keeps only whether a list came back, never a file name.
Public registries
Some checks ask public registries instead of your app:
- The OSV vulnerability database receives the name and version of each library it looks up.
- DNS answers for your domain's mail records and your subdomains.
- The domain registry answers for your renewal date, through rdap.org.
- The public certificate logs (Cert Spotter, then crt.sh) list the names certificates were issued for.
They receive a package name and version, or your domain name. Never your code, a key or a page.
Vallit sends one request to a subdomain only when its DNS record points at a hosting service where others have claimed abandoned names before. The request reads that service's answer and keeps only whether it matched the service's "no such site" page.
The AI sample
Every app page has Include this app in the sample under Settings, ticked until you untick it. Only apps with a confirmed domain are sampled. An AI reviewer then reads what the daily check already saw and may ask for a few extra read-only requests from a fixed list. The model never contacts your server. Vallit's own checker makes those requests, under the same limits. What the sample finds is filed without your app's name.
Before the AI request leaves Vallit, values in recognized credential formats are replaced with markers, including values in earlier finding descriptions. Other text can remain; this filter does not remove every secret or make personal data anonymous.
Page health
On Watch and Care, page health opens up to 15 pages of an app once a day in a browser. It runs only on a domain you confirmed, and it reaches that address and its www or bare twin and nothing else. It ignores robots.txt there, because confirming the domain is your permission for us to read it. It still only reads, sends nothing, signs in nowhere and says it is VallitBot.
Your code
Code checks run only after you connect a GitHub repository to an app.
- Today the Vallit GitHub App asks to read the contents and metadata of the repositories you share with it, and nothing more.
- To open fixes as pull requests, the app may also ask to write contents and pull requests. GitHub then asks you to accept the new permission before it applies to your repositories.
- The connect page shows whether you have accepted it, with Allow on GitHub while you have not. Fixing what we found lists what it says.
- With write access, Vallit pushes only to a branch of its own and opens a pull request. It never merges, and with the pull request box unticked it opens none.
- Each check first asks GitHub which commit the default branch points at, then downloads the repository at that commit into memory. Nothing is written to disk, and none of your code is run.
- The check keeps the repository's name and that commit's id, not a copy of the code.
- Besides the code, the checks read your lockfiles,
package.json, database migrations, configuration and committed.envfiles. A key found there is recorded by its kind, file and line, never its value. - To confirm a finding, the code on its path goes to language models through the Vercel AI Gateway. The whole repository is never sent at once.
- Before each chat or evaluation request, Vallit replaces values in recognized credential formats with markers, including values in additional code the model requests.
- This filter covers named token formats and private-key blocks, not every secret or personal record. Ordinary code, comments and other strings can remain.
- The markers preserve equal-value comparisons and source lines. If deciding evidence is missing, the reviewer must leave the result uncertain.
- A settled verdict from one review round is cached under a fingerprint of its code and review policy. Judgments requiring additional code are reviewed again.
- The cached verdict holds a short reason, which can quote code with recognized credentials masked. Its retention rule is 30 days.
- Recognized keys, Bearer credentials and address parameters are masked before a verdict is stored. Older verdicts are masked when read too.
- When a finding is in your code, a person at Vallit may read the lines around it to help fix it. They see up to 12 lines above and below each place the finding names.
- Those lines come through the same Vallit GitHub App, at the commit the check read. For an older check that kept no commit, they come from the default branch as it is now.
- The lines are fetched when the finding is opened and are not stored. Keys in known formats are replaced with
[redacted], as in the report. - A file with a committed key, and a committed environment file, are never opened. The person sees only what the finding records: the key's kind and prefix, or the variable names.
- Once a file has been read, the What we did list on Home says so, at most once a day per finding. The line reads "A person at Vallit read the code behind “…” to help fix it", with the finding's name in the quotes.
- Once pull requests are on, a person at Vallit who fixes a finding works on copies of the files it names. They get only those files, whole, at the commit the check read. A file with a committed key, and a committed environment file, are never copied.
- Those copies sit in a working folder on that person's computer and are removed when the pull request is opened. None of your code is run there.
- Before the pull request opens, Vallit's server downloads the repository into memory at that commit, as a check does, applies the change and runs the finding's check on it. The check reads the files and runs none of them.
- The pull request comes from the Vallit GitHub App, on a branch of its own. A fix as a pull request shows what it holds and what your activity says.
- Disconnecting the repository stops Vallit reading it. To revoke access on GitHub as well, uninstall the Vallit GitHub App in your GitHub settings.
A Cloudflare token
If you confirm your domain with a Cloudflare token, Vallit adds the one record and checks it. The token is not stored.
What a finding records
A report has to show where a problem is without becoming a copy of it.
- An exposed key is recorded by its kind, its public prefix such as
sk_live_, its length and a short fingerprint. The fingerprint recognises the same key in a later check without storing the key. - The excerpt around a key shows the nearby code with the key replaced by a note of its length.
- An exposed environment file is recorded by the names of its variables, never their values.
- An exposed backup, file or open folder is confirmed by the shape of what came back. The finding keeps its address and status, not its contents.
- Addresses in a finding keep their path. Every value in the query string, the part after
?, is replaced with…. - A stored address also removes any username and password and masks its fragment, the part after
#. Addresses inside error messages receive the same treatment. - Finding text and code excerpts replace recognized keys and Bearer credentials with
[redacted]. This also applies when an older report opens; its stored record stays unchanged. - A code finding records the file, the line number and that line, shortened. Keys in known formats are replaced with
[redacted].
A report opens from a long random link, and anyone with the link can read it. Share it the way you would share the findings.
What Vallit keeps, and for how long
| What | Kept for |
|---|---|
| A report that no company holds, with its findings | 90 days from the check's creation |
| Monitoring results, one per check the guardian runs | 90 days |
| Reports attached to your company | While attached; the unclaimed-report rule applies afterward |
| Company records and report contact fields | Removed when the company is deleted |
| Reports that read your code | Deleted when the company or the app is deleted |
| A model's cached verdict on a place in your code | 30 days |
| A nightly encrypted copy of Vallit's database | 14 days |
- A check started on vallit.net without an account opens under its link until it is 90 days old, unless someone takes it over.
- Such a check stores the first 32 characters of a SHA-256 hash of the visitor's IP address, not the address itself. The hash counts the checks one visitor starts in an hour.
- No secret goes into that hash, so it is not anonymous: anyone holding it can find the address by hashing addresses until one matches. Checks started in a company, and the guardian's, store no IP address.
- Some of those reports also hold an email address the visitor left for the link. The Vallit team sees it beside the check. Vallit no longer asks for one.
- Taking such a report over moves it into your company with the hash and the email address it holds.
- The Vallit team gets an email when a check you start finds something critical. It names the domain, the score and the critical findings, and links to the report. The daily checks send no such email.
- The Vallit team also gets short messages in its Slack about checks, incidents and fix requests. What Vallit's team is told lists what they carry; evidence, keys, report links and email addresses are never in them.
- Every night Vallit copies its database, encrypted with a key that only Vallit's owner holds outside every system. A deleted company's rows stay in those copies until they are 14 days old. The copies hold no sign-in details and no card details.
- Deleting a company or one of its apps deletes the apps, monitoring, incidents and settings. Reports that read the code are deleted too. The other reports keep working under their links, with the company, the app, the hashed IP address and the email address removed, and nobody can take them over.
- Their target addresses and results remain. Clearing account links and contact fields is not complete data erasure or anonymization.
- Those reports then belong to no company. Scheduled cleanup removes them once they are more than 90 days old, measured from the check's creation.
- A dedicated sign-in service holds your account details. Card details stay with Stripe; Plans and billing lists what Vallit keeps about a plan.
- On app.vallit.net, Vercel Analytics counts page views and Speed Insights measures loading speed. Report links and take-over links are masked before anything is sent.