Sample report. The app, the people and the findings are illustrative; a real report follows the same layout.

Evidence report: Taskflow

App
Taskflow, a team task tracker built with Lovable and Supabase
Package
Harden, fixed price, scope approved 2 October 2026
Version checked
Repository commit 4f1c9e2, production deploy of 16 October 2026
Work period
3 to 16 October 2026
Report date
16 October 2026
Accepted by
Founder review, PostVibe

Summary

Six findings in the agreed scope: two critical, two high, two medium. All six are fixed and each fix has a check you can run yourself. Two limits remain and are listed at the end. Nothing outside the scope was changed.

FindingSeverityStatus
API key shipped in the client bundleCriticalFixed, verified
Row level security off on 3 tablesCriticalFixed, verified
No rate limit on /api/authHighFixed, verified
Secrets still present in git historyHighFixed, verified
No backups configured for the databaseMediumFixed, verified
0 tests, 41 unhandled error pathsMediumBaseline in place, 12 paths left

Findings

1. API key shipped in the client bundle Critical

Found
The Supabase service role key was compiled into the public JavaScript bundle at /assets/index-8d2f.js.
Impact
Anyone opening the site could read and change every row in the database, bypassing all access rules.
Fix
The key was rotated in Supabase. The client now uses the public anon key only; admin actions moved to an edge function that holds the new key on the server.
How we checked
curl -s https://taskflow.example/assets/*.js | grep -c service_role returns 0. The old key is rejected by the API with 401.
Result
No server key in any public file. The rotated key is stored only in the edge function settings.
Limits
Requests made with the old key before rotation cannot be audited: Supabase keeps 7 days of logs on this plan.

2. Row level security off on 3 tables Critical

Found
Tables tasks, comments and invites had row level security disabled.
Impact
A signed-in user of one team could read and edit the tasks of every other team.
Fix
Row level security enabled on all three tables, with policies that limit each row to members of its team. Migration 20261008_rls_team_scope.sql.
How we checked
An automated test signs in as a member of team A and tries to read, insert and update rows of team B. All three are refused.
Result
Cross-team access refused for every table in the schema, not only the three above.
Limits
Storage buckets were out of scope; their rules were reviewed but not changed.

3. No rate limit on /api/auth High

Found
The sign-in endpoint accepted unlimited attempts from one address.
Impact
Passwords could be guessed by brute force, and the endpoint could be flooded.
Fix
A limit of 10 attempts per 15 minutes per address and per account, with a clear message to the user.
How we checked
A script sends 11 sign-in attempts in a row; the 11th is answered with 429.
Result
Brute force slowed to a rate that makes it impractical.
Limits
A distributed attack from many addresses needs a WAF; recommended, not part of this scope.

4. Secrets still present in git history High

Found
Two old .env files with a Stripe test key and an email provider key were in earlier commits.
Impact
Anyone with read access to the repository, now or later, could use those keys.
Fix
Both keys revoked and reissued. History rewritten to drop the files; a secret scan now runs on every push.
How we checked
gitleaks detect --log-opts="--all" on the cleaned repository finds nothing.
Result
No secrets in the history; new ones are blocked before they land.
Limits
Existing clones made before the rewrite still hold the old files. The keys in them no longer work.

5. No backups configured for the database Medium

Found
Point in time recovery was off and no other copy of the data existed.
Impact
A bad migration or a deleted table would have been permanent.
Fix
Daily backups enabled with 14 days of retention, plus a weekly export to separate storage.
How we checked
Yesterday's backup was restored into a fresh project; row counts match production for every table.
Result
A tested restore, not just a backup setting.
Limits
Up to 24 hours of data can be lost between daily backups.

6. 0 tests, 41 unhandled error paths Medium

Found
No automated tests. 41 places where an error from the database or a third party was ignored or shown as a blank screen.
Impact
Every change risked breaking something unnoticed; users saw failures without explanation.
Fix
A test baseline of 38 tests covering sign-in, teams, tasks and invites, run on every deploy. 29 error paths now show a message and are logged.
How we checked
The test suite passes in the deploy pipeline; a deploy with a failing test is stopped.
Result
A baseline you can grow, and a rules file for your AI tool so new code keeps it green.
Limits
12 error paths in rarely used admin screens are listed in the appendix and not yet handled.

What this report does not cover

How to check this report yourself

The report is signed with our Ed25519 key. The signature proves the document was not changed after we issued it. It does not prove the audit found everything; the checks above are what prove each fix.

sha256sum taskflow-report-2026-10-16.pdf
openssl pkeyutl -verify -pubin -inkey postvibe-report.pub -rawin \
  -in taskflow-report-2026-10-16.pdf -sigfile taskflow-report-2026-10-16.sig

Our public key is published with every report. A changed byte in the file and the check fails.

Run a free scan