DocsReports and fixes
Reading a report
The score, the bands, what we saw, and sharing.
On this page
- In short
- Where in the app
- What a finished report looks like
- Step by step
- Take over a report started on vallit.net
- What happens behind the scenes
- The picture in each finding
- Recorded code paths
- Before the domain is confirmed
- How the score is worked out
- How the band is chosen
- What we saw and the evidence
- Repository configuration evidence
- What a line under What we checked means
- What changed since the last check
- Who can read a report
- If something goes wrong
- Related
In short
- A report gives your app a band and says how much needs attention. Partial shows N/A and Not evaluated; other bands show a score out of 100. The findings follow, worst first.
- Three lines at the top say what we checked, what to do now and who can read the page.
- A result describes the completed checks at the recorded time. No findings does not rule out other vulnerabilities; failed or waiting checks leave the report incomplete.
- Each finding shows where we saw it, then what could happen and how to fix it yourself.
- Every report has its own link, and anyone you send it to can read it without an account. A report started on vallit.net shows the band, score display and kind of each finding until someone takes it over.
Where in the app
Every check of an app is a row in the Reports table on the app's page, newest first. Click a row, and its report opens on its own page in your company. Fix next on the app's page opens the latest report at one finding. Every report also has a share link on app.vallit.net. Anyone you send it to reads it as a document; when you open it yourself while signed in, it opens in your company.
What a finished report looks like
The picture shows a synthetic example in an isolated company, drawn by the app's report screen and taken by the docs camera. Your report has the same parts: the findings worst first, then
What happens from here and What we checked, with the score beside them. In a narrower app window, the score sits above the findings so their titles and code stay readable.
Step by step
Read the three lines at the top
On the share link, under the address, What we did says when we checked, how many checks ran and whether your code was read. When it was not, it counts the code checks that What we checked lists further down. What to do now names the next step. When nothing needs fixing it says so, and it says too when some checks have not completed. Who can read this says who can open the link.
Read the score
With Good, Fair, Poor or Critical, the large number is the score out of 100. A Partial report shows N/A and Not evaluated instead, because some checks wait or did not finish. How the score is worked out explains both.
Read the sentence under it
The sentence counts what needs attention and how much of it is urgent, for example "Three things need attention. One is urgent." Below it, Open findings counts the open findings at each severity. The line under the counts turns each severity into a time: critical today, high this week, medium this month, low when convenient.
Open a finding
Under Findings, click a finding's title. The share link calls the list Observations. Every finding starts folded, unless you followed a link to one finding, such as a row of Fix next; that one opens. A finding starts with one sentence on what it is, then Where we saw it, drawn as the place itself. Below come What could happen in the severity's colour, with its short answers under it, then the fix with two tabs: Fix it yourself and We fix it. Evidence sits folded at the end. A finding in your code that could not be confirmed reads Possible before its severity, such as Possible · Critical; point at it to see why.
Follow a code path
In a critical code finding, Follow the path shows the recorded entry, helper calls and affected operation. Choose another Location when the finding names more than one. The file, line and redacted source change together.
Copy a code location
Click Copy location to copy the selected file and line. Paste it into your editor or a message to the person making the fix.
See what was checked
Scroll to What we checked. Each line is one question a check asked, marked Clear, Found, Waiting, Not run or Accepted. A Found line links back up to Observations, where its finding is.
Share the report
Click Copy report link at the top of the report, or beside Run a check on the app's page, which copies the latest report's link. The second sheet of its icon slides off the first. Then Copied replaces the label, the button turns green and its mark becomes a check. The link is ready to paste. If the label reads Not copied instead, your browser did not let the page copy: copy the address from the browser's address bar.
Take over a report started on vallit.net
A check started from the form on vallit.net belongs to no company. Its report shows the band, score display, sentence under it and each finding's severity and kind with Details locked. Move it into a company of your own to read the rest.
Start from the report
Under the findings, click See the full report. Get started at the top of the report leads the same way.
Create your account
Sign up, or sign in to an account that has no company yet. The page Take over this report opens with the report's address filled in.
Confirm and take it over
Tick I own this app, or its owner asked me to look after it. and click Take over this report. The report moves into your new company. After you choose Free or a plan, the app's page opens with every finding in full.
Taking over does not run the check again. The report you came from is remembered for an hour while you create your account. If you change the address on the take-over page, Vallit checks the new address instead.
The plan offer distinguishes monitoring from repairs. Watch and Care check availability every five minutes once your domain is confirmed. Care includes repairs; Watch repairs are paid separately.
What happens behind the scenes
The report recalculates its score, band and sentence each time the page opens, using open findings and the checks that completed. Changing a finding's status updates that calculation without running the checks again.
The picture in each finding
Where we saw it draws the place the check looked at. A page or a file anyone can open gets an address bar, and a finding in your code gets its file and line. A missing header shows as a response. When your homepage has the header and only some files lack it, the response is the first file without it, not the homepage. Your domain shows as a DNS record. A link that forwards to other websites shows as its address and the parameter it forwards with. The lines under it are what came back there. A long address wraps onto the next line, also on a phone, instead of being cut off. Values are masked, so a key shows as its prefix and length and an environment file as its variable names.
Addresses hide usernames, passwords and values after ? or #. Finding text and check errors
mask recognized keys and Bearer credentials, including when you open an older report.
What could happen says the consequence once, in the severity's colour. It describes what the finding could lead to, never how to carry it out.
Under the sentence, the same consequence is sorted into short answers:
- Who can do it: anyone on the internet, anyone with an account, someone on the same network, anyone who can read your code, someone who found another flaw first, or nobody, when it happens on its own.
- Reaches: one user at a time, every user, or the whole business.
- What it takes: shown only when it adds something to the first answer, for example a user who opens their link.
- At stake: what the finding puts at risk, such as customer data, money or user accounts.
The answers come from the kind of finding, not from your data. Every finding of the same kind gets the same answers.
Recorded code paths
The webhook verification, token key, prototype write, archive write and private cache findings can show Follow the path. It draws entries and calls already recorded by the source analyzer. It never fetches extra code or invents missing steps. A finding without recorded locations keeps its existing picture.
The path is evidence from source analysis, not proof that someone exploited the app. The finding keeps its explanation and fix instructions. Locked or redacted findings carry no path into the browser.
Before the domain is confirmed
A finding of a targeted check on an app whose domain is not confirmed keeps its severity, its category and its title. Where it sits, what it lets a person do and the steps to fix it wait. In their place the finding holds a card that reads Confirm and the app's address, to see where this is and how to fix it, with Confirm the domain beside it. The score and the counts include the finding.
Confirming the domain opens the card on every report of the app at once, the old ones too. Nothing runs again. Someone who reads the report through its link sees the same card without the button, because only the owner can confirm. The reason is the same for everyone: a report can be shared by link, and where a problem sits is what a stranger would need.
How the score is worked out
Vallit calculates the score from open findings, starting at 100. Each open finding takes off points by its severity.
| Severity | Points off |
|---|---|
| Critical | 30 |
| High | 14 |
| Medium | 6 |
| Low | 2 |
| Info | 0 |
The score never goes below 0. Findings marked Fixed, Not an issue or Accepted risk move to Handled and no longer count. A finding we are still fixing counts until the fix is done.
A person at Vallit marks a finding Not an issue or Accepted risk. Open the finding and click Tell us it is not an issue. An email to info@vallit.net opens with the finding named, and you write why it does not apply to your app. Use it too for a finding in an old file you no longer deploy. The checks read every file in your repository and cannot tell an old one from a live one. A finding marked Not an issue keeps that mark on later checks.
A Partial report shows N/A and Not evaluated instead of the calculated score. Its scale has no indicator while coverage is incomplete. The other bands retain their numerical score, including when unfinished checks accompany findings that already make the band Fair, Poor or Critical.
How the band is chosen
| Band | When |
|---|---|
| Critical | At least one critical finding is open, whatever the score. |
| Good | 85 or more, with no critical finding and no waiting or unfinished checks. |
| Partial | 85 or more, with no critical finding, while some checks wait or did not finish. The score shows N/A and Not evaluated. |
| Fair | 60 to 84. |
| Poor | Below 60. |
The band follows the worst finding as well as the score. One critical finding and nothing else scores 70, and the band is Critical.
Info findings take nothing off and are left out of the sentence. They record context, such as bot protection answering in place of your app.
What we saw and the evidence
What we saw is one sentence built from what the check recorded. Evidence opens the full record. Secrets never reach it. For an exposed key, the record holds the kind of key, its standard prefix, its length and a short fingerprint. For a published environment file, it holds the variable names and never the values.
Some findings in your code get a second review that tries to confirm the problem can be reached. When neither the check nor that review could confirm it, its severity reads Possible first, such as Possible · Critical. Pointing at it, and the open finding, show We saw the pattern in your code but could not confirm it can be reached. Old files you no longer deploy can raise it too. Check the place we name before you act on it. The finding stays in the list. When the second review itself failed on our side, Evidence leaves that error out and keeps the rest of the record.
Repository configuration evidence
The deployment and build checks report explicit settings from the repository commit that was read. Their Confirmed label confirms that configuration observation. It does not confirm deployment, a reachable service or an exploitable vulnerability.
Where we saw it names the file and line. The recorded evidence identifies the setting without copying customer-supplied configuration values. The consequence describes what can follow if the configuration is deployed and relevant external controls allow it. Cloud account policies, runner isolation and container admission controls still need review in their own systems.
A reason starting Not evaluated: means the check could not resolve a relevant setting or read a matching file completely.
The check shows Not run. An unresolved value, malformed configuration or unsupported merge does not count as a pass.
If the result is clear, no explicit matching setting was found within that check's supported scope.
It does not cover omitted properties, deployment defaults or configuration formats the check does not read.
What a line under What we checked means
When no findings were detected, the report says No findings were detected in the completed checks. When previously detected findings are handled, it says none remain open and asks you to review their current status below. Handled rows show their status on phones too. Accepting a risk does not erase the finding or mean it was repaired. The verdict limits its next step to the open findings in this report. If a check failed or is waiting for authorization, the summary says some checks have not completed and gives the next step. A locked report preserves that distinction before its details open. Monitoring checks again for changes; it does not guarantee that the app stays free of vulnerabilities.
Clear means the check found no sign of the problem this time. It is not a promise about tomorrow. When a check had nothing to test, such as an app without a Supabase project, its line also reads Clear. Found means a finding from that check is open. Accepted means its finding was accepted as a risk, which is not the same as safe. Waiting means a targeted check waits for the domain to be confirmed; nothing went wrong. Not run means the check did not finish. A check that asks a service that did not answer, or an app that was slow to answer, is asked once more before it counts as not run. A check that stopped partway keeps what it confirmed: its finding is listed and its line reads Found, while the report still counts the check as not finished.
On Watch or Care with the domain confirmed, a report with checks that did not run adds a box under the findings. It names why, in plain words, and what to do next. When there is nothing for you to change, such as code larger than the reader follows to the end, it says so and where to write. A report opened from a shared link shows the reason but not the next step. Pointing at Not run shows the same reason as a tooltip.
For an app on Free, until the domain is confirmed, the guardian's daily check leaves out the targeted checks. On Watch and Care it runs them, and their findings are described under Before the domain is confirmed. In its report, their lines read Waiting and sit at the end of Your website. The line under them says Waiting: these checks run once the domain is confirmed. When you own the report, it says Waiting: the daily check runs these once the domain is confirmed. Run a check runs them now. instead, and Confirm the domain beside it opens the app page where you confirm it. Once it is confirmed, the line reads Waiting: the domain is confirmed now, so the next check runs these. Waiting checks are not counted in the checks the report says it ran. A check you start yourself with Run a check runs them.
Reading your code is part of a paid plan. Without one, What we checked still lists every code question, grouped by topic, each marked Not checked. The first four show, and the next ones peek out blurred under them. The button on the blur opens the rest, and Show fewer folds them again. A line under them says why: Not checked: these checks need access to your code, which comes with a plan. On a plan with no repository connected yet, it says to connect the repository instead. Once the code checks run, their lines are grouped by the same topics:
- Who can reach which data
- Where money can leak
- What a request can make your server do
- What your repository carries, which holds the libraries you install, the keys committed to your repository, private keys named for the browser and your GitHub Actions workflows
Who your app believes adds its lines to the first group, and Who can spend your AI budget to the third. Who your app believes also runs for an app whose only server code is its Supabase migrations, pages or middleware. Who can spend your AI budget also runs for an app with pages and no other server code.
The rule checks split between the first and third groups. Those about sign-in tokens, passwords, access codes and which websites may use your API go under the first, and so does Firebase security rules. Those about scheduled jobs, responses, signatures and raw HTML go under the third. Every rule check but Scheduled jobs anyone can start also runs for an app without routes or Server Actions that Vallit recognises.
What changed since the last check
When the app was checked before, the report adds What changed since the last check with the date of that check.
New lists active findings that were not active last time, from checks that also ran last time.
A check that did not run last time could not have found anything then. What it finds now is listed apart, under First read of your code when this is the first check that read your code, and under First look otherwise. It is not a change in your app. A sentence above the lists says so. After the first read of your code, it reads This is the first check that read your code, so it found what the website alone does not show. When that read found something above Info, it adds The score now counts it too. When nothing else moved, it adds Your app did not change. A first read that found nothing says This is the first check that read your code, and it found nothing there.
Fixed since lists earlier active findings that the current scan no longer reports. It requires a completed scan and a successful reassessment by the same check.
Checks marked Not run, Waiting or Not checked leave that finding's disappearance unknown. An incomplete comparison can still show new findings and fixes confirmed by successfully completed checks. An unfinished check does not establish a fix, even when the current report contains no new findings.
Manual resolutions remain in Handled, including findings marked Fixed, Not an issue or Accepted risk. Changing a finding's status does not prove that the check stopped reporting it and does not place it under Fixed since.
Who can read a report
- Anyone with the link can read the report. The page asks search engines not to list it. It names every weakness and where it is, so share it only with the people fixing them.
- To show customers that your app is checked, publish its trust page. It lists what passed and never a finding.
- Only the owner sees What happens from here at the end of the report. It shows what the company has now and what a plan and connected code add. Without a plan, its middle tile reads Watched by us with the lowest price per app. On a plan, the middle tile names the plan this app is on, so a Watch app reads Watch even when other apps in the company are on Care. A report of an app on Free reads as if the company had no plan, with the plans on offer.
- Back from paying for a fix, the report opens with Payment received. The fix is filed., the day the change is due and Open Inbox, at the finding you paid for. The line appears only for a payment Stripe confirms as your company's, never for a link someone typed.
- Only a signed-in member of the company the report belongs to can ask us for a fix. Each open finding shows Request fix on a Care app, which includes every fix, and Fix it for €99 on a Watch or Free app. Where payments are not switched on, it shows See plans instead.
- The same members see See plans under What we checked without a plan, and Connect code on a plan, where connecting code is switched on.
- The bar at the top depends on the reader. With a company, Open Vallit leads to it. Without one, Get started leads to sign-up, or straight to the take-over page when you are signed in already. On a wider screen, Sign in sits beside it.
- The Vallit mark at the top left opens your company, or the sign-up page for a reader without one. The app has no front page of its own.
- A report that no company owns shows no titles, explanations, evidence or What we checked list to anyone. Anyone can check any address, so those details open only once an account takes the report over and confirms the app is theirs.
- Only a report that no company owns offers See the full report. An account that already has a company sees Open Vallit instead and cannot take a report over.
- The line under the address says when the check ran and who started it: a visitor, the guardian, you or the owner. A report started on vallit.net says a visitor.
- Ref is the start of the link; quote it when you write to us.
- A report that no company owns is deleted 90 days after the check. Taking it over keeps it with your app.
- When you print the report, every finding prints open.
While a check runs, the report lists each check and marks it as it finishes. The page refreshes by itself.
If something goes wrong
| What you see | What it means | What to do |
|---|---|---|
| There is nothing here | The report link is incomplete or wrong. Report links are long, and a cut-off one lands here. | Copy the whole link again from your app's page or from the alert email. |
| We could not finish this check | The check stopped partway. The line under it gives the reason when the check recorded one. | Open the address in a browser. Once it loads, click Run a check on the app's page in your company. |
| Some checks did not complete, so this report is not the full picture: … | The named checks did not finish. Their lines under What we checked read Not run. | Click Run a check on the app's page. To send us the names, click Copy the check names. |
| Some checks did not run, so this report is not the full picture. | On Watch or Care with the domain confirmed: the reason is written under it, with the checks it applies to. | Do what the line under the reason says. If it says there is nothing to change, write to info@vallit.net and name the checks. Copy the check names copies them. |
| Waiting: these checks run once the domain is confirmed. | Checks that probe beyond what a browser loads wait for your confirmed domain. Nothing went wrong. | Click Confirm the domain beside it and follow Confirm your domain; the next daily check runs them. |
| Waiting: the daily check runs these once the domain is confirmed. Run a check runs them now. | The same wait, as the owner of the report sees it. You can run the checks now. | Click Run a check on the app's page, or Confirm the domain and the next daily check runs them. |
| Your app is behind bot protection | A security service answered in place of your app, so the other checks could not see your pages. | Treat the report as incomplete, not clean. Let VallitBot through with one narrow rule; the finding's fix kit shows how. |
| Not checked | Reading your code is part of a paid plan, so the code checks did not run. | Click See plans. On a plan, connect the repository with Connect your code. |
| That report already belongs to a company. | The report is already in a company. Either it was checked there, or someone took it over first. | Enter your app's address on the same page to start a fresh check. To work on it with its owner, ask them to invite you. |