A ranked, written security review of an app an AI tool built
A read-only review of the repository, the database rules and the deployment of an app built with an AI coding tool, ending in ranked written findings and a plain recommendation to harden it or rebuild part of it.
You built an app with an AI coding tool such as Lovable, Bolt, Cursor or Claude Code, it works, and someone is about to put real customers or staff on it. This review answers one question before they do: what is wrong with it that could cost you money or data, in what order should it be fixed, and is it worth fixing or should part of it be rebuilt?
It is the first step of our vibe coding to production service, scoped as a piece of work in its own right. The report is written so that you can fix everything yourself, hand it to another developer, or ask us to do the fixing, and any of the three works.
A word on evidence before anything else. The nearest published example is our materials marketplace case study: an app first generated on an AI app builder, audited, rebuilt on its own database and put through tests and CI. That was a migration, not a standalone review, and we have not published one of those. This page rests on the method, set out below and in our vibe coding to production article, on that case study, and on controls we built and reviewed by hand in systems of our own. The section on what this page rests on says which.
What you get at the end of the review
A document you can act on without us. Six parts.
Findings ranked by consequence
Each finding names the file, policy or setting it sits in, says what could go wrong and shows how to reproduce it. A finding nobody can reproduce is an opinion, so opinions are not listed as findings.
A map of the app
What it does, who uses it, what data it holds and what a failure would cost. The consequences set the priorities: the same missing check ranks differently in a tool for five colleagues and in a customer app holding addresses and invoices.
A recommendation: harden, rebuild part, or rebuild
With the reasons written down. The question behind it is whether someone other than the AI tool can explain where each permission is enforced. If yes, harden. If the honest answer is somewhere in the screens, the permission layer needs rewriting.
The launch blockers, separated out
The short list of fixes that must happen before real users arrive, kept apart from the longer tail of improvements, so the report does not bury the three things that matter under thirty that do not.
A list of what was not looked at
Anything outside what we read is listed, so the report is not mistaken for coverage it does not have. A review finds what it looked at.
A scope you can price
If you want us to do the fixing, the findings become the scope for a separate quote through the vibe coding to production service. If you do not, the report stands on its own and you are free to take it elsewhere.
Nine areas we read, and what a bad finding looks like
The same areas as the checklist in our vibe coding to production article, in the order the failures tend to cost money. Whatever tool wrote the app, what is reviewed is the codebase and the services it connects to.
| Area | What we read | What a bad finding looks like |
|---|---|---|
| Authentication and authorisation | Sign-in setup, how a user becomes an administrator, and the check behind every endpoint that returns or changes data | A button hidden in the interface while the endpoint behind it answers anyone who asks; an admin flag the browser sends and the server trusts |
| Secrets | Environment variables, the repository and its history, and what is compiled into the code sent to every visitor | A key with a public prefix that can spend money or read every row; a key that was once pasted into a chat, a screenshot or a commit and never rotated |
| Database access rules | Row-level security or its equivalent, table by table and policy by policy, and where the privileged key can be reached | A table holding user data with no rules, or a policy that is simply true, loosened to make a permission error go away |
| Input handling | Server-side validation, how queries are built, uploads and where they are stored, incoming webhooks, sign-up and email-sending endpoints | Queries assembled by joining strings; a public upload bucket; webhooks accepted without checking the signature; no rate limit on anything that sends email or calls a model |
| Dependencies | The package list, the lockfile, a vulnerability audit and the licences of direct dependencies | Packages nothing uses, no committed lockfile, or a package name the tool mistyped or invented that someone else could register |
| Error handling and logging | Empty catch blocks, what a user sees on failure, what is logged and what is kept out of the logs | Errors swallowed so nothing tells anyone; stack traces shown to users; secrets or personal data in the logs; no record of who changed a role or issued a refund |
| Backups | What the database plan includes, how far back it goes, and whether the code lives outside the AI tool's workspace | A backup nobody has ever restored; the only copy of the code inside the tool that generated it |
| Deployment | How a change reaches customers, whether staging and live are separate, and how a change is undone | Editing the only live copy; one database and one set of keys for test and live; no rehearsed way back |
| Spend caps | Every route that calls a paid API, whose key it uses and what limits stand in front of it | An unauthenticated endpoint that calls a model, which is a public line of credit; no per-user limit; no provider spend cap or alert |
Tests on the paths that move money or change permissions are not a tenth area, but their absence shows in the findings above, and we note it where it is the reason a fix cannot be trusted. Platform details such as a database provider's row-level security behaviour change over time, so we check them against the provider's current documentation for your project and say so in the report.
From read-only access to a written report
- 01
What we ask you for
Read-only access to the repository, the database schema and its access rules, the deployment settings and a list of the third-party accounts the app uses. Also which AI tool wrote it and a sentence on what data it will hold and who will use it. Not live customer data, and not the ability to change anything.
- 02
A map before any findings
What the app does, who uses it, what data it holds and what a failure would cost. The consequences set the order everything else is ranked in.
- 03
Read, then reproduce
Each suspected gap is read in the code or the policy first. Where it can be shown, we reproduce it with two test accounts against a local or staging copy and record the steps. We do not run attacks against your live system.
- 04
Rank, then recommend
Findings are ranked by consequence, and the recommendation to harden, rebuild part, or rebuild is written down with its reasons.
- 05
Deliver, and decide
The report arrives as a document, with what was not looked at listed. What happens next is your decision: fix it yourself, give it to another developer, or have us scope the fixing.
What this review is not
It is not a penetration test. Nobody attacks your live system, and the report says what was read, not what an attacker with time and tools could or could not find. It is not a certification or an audit against a standard, and it does not make an app compliant with data-protection, payment or health rules. It is not legal advice, including on who owns code an AI tool wrote or on the licences of your dependencies, where a lawyer is the right call if it matters.
It carries no guarantee either. A review finds what it looked at, when it looked, and anything it did not look at is listed as such. An app that handles health or payment data needs specialist assessment on top of this. If a customer, an insurer or a regulator has asked you for a penetration test or a certificate, this is not the thing to send them.
What this page rests on, and what it does not
The nearest published example is the materials marketplace, an app first generated on an AI app builder that we audited and moved onto its own database. It was a migration, not a standalone review, so this page states no outcome, no number of apps reviewed and no number of vulnerabilities found, because we have none to state.
What it does rest on is the method, which is public: the checklist in our vibe coding to production article, the comparison in our article on custom software, no-code and AI-built apps, and the agent risks in our article on securing AI agents, which matters if the app lets a model call tools. It also rests on controls we have built and reviewed by hand in our own systems, which are the controls we look for in yours:
- Row-level security carrying role and branch, so a branch administrator's queries return only their branch whichever screen asked (school ERP).
- Permissions enforced in the route, the write layer and a database trigger, with an append-only audit log (trading ERP).
- An account-wide token kept in exactly one server process, with a build that fails if a client component reaches for the module that uses it (fleet order automation).
- Secrets moved out of pasted JSON into variables, and a privileged database client guarded three ways (Blueprint Runner and Skofi Outreach, both our own products).
That is building the controls, not reviewing someone else's code, and the difference matters. Judge this offer today by the method and by the table of findings above and not by a track record we cannot show. Anthropic's Claude Code security page puts the principle plainly: you are responsible for reviewing proposed code and commands for safety before approval. The tools help you write the code, but they do not take over the reading.
Harden it, rebuild a layer, or leave it alone
- Harden, when the data model maps to real things, sign-in uses a managed provider and the access rules sit in the database. Fix the policies, add tests on the money and permission paths, and add what is missing: restored backups, a way back from a bad deploy and spend caps.
- Rebuild a layer, when permissions are checked only in the interface or the schema is tangled. Keep the prototype as the specification, because its screens and flows are what users reacted to, and rebuild what sits beneath them.
- Leave it, with the minimum, when it is a small internal tool for a few colleagues with non-sensitive data behind your company sign-in. It still needs sign-in in front, secrets off the client, a backup you have restored and the code in an account you own.
Fixing is a separate piece of work, quoted from the findings, through our vibe coding to production service. A full rebuild is custom development. Either way you finish with software you own, on your accounts, that someone understands.
Where it has shipped
Related projects that were not this job
Here for the argument rather than as evidence of this exact work. Each one bears on a decision above, and the note says which.
- An independent school groupSchool management ERP with permissions enforced per branchNot a review of anyone's app. It is our nearest example of the control the review checks hardest: row-level security policies carrying role and branch in the database, so a mistake in the interface cannot undo the isolation. Public sign-up is disabled and account creation sits behind one privileged server-side function.Case study
- A regional trading & distribution groupAn ERP with AI invoice capture and an audit trail that holdsNot a review either. It shows the layered permissions and the append-only audit trail we look for: the route, the write layer and a database trigger enforcing the same rules, and a trail that cannot be rewritten through the API.Case study
- A fleet-telematics providerOrders that file themselves, and an SLA clock that never forgetsNot a review. It shows a credential boundary: an account-wide token that lives in one server process, with a build that fails if a client component imports the module that uses it.Case study
- Skofi OutreachSkofi Outreach: deliverability rules the database refuses to breakOur own product, not a review. Its privileged database client is guarded three ways (a server-only import, a runtime check for a browser context and a lint rule), which is the kind of secret handling we check for in yours.Case study
Related reading
Vibe code security review, specifically
A read-only review of an app built with an AI coding tool: the repository, the database rules, the deployment settings and the third-party accounts. It covers authentication and authorisation, secrets, database access rules, input handling, dependencies, error handling, backups, deployment and spend caps, and ends in ranked written findings and a recommendation to harden, rebuild part, or rebuild.
No. Nobody attacks your live system. We read the code, the policies and the settings, and where a gap can be shown we reproduce it with test accounts on a local or staging copy. A penetration test is a different, adversarial exercise, and if a customer or an insurer has asked you for one, this is not a substitute.
Not as a yes or no, and we would distrust anyone who offers it. The report ranks what we found, separates out what blocks launch, and lists what we did not look at. It cannot promise that nothing else is wrong, and it carries no guarantee. What it can do is stop you launching with the expensive problems still in.
We have not published a separate price or turnaround for the review, because both depend on what is in the repository. The only figure we publish is for projects in general: most land between $5,000 and $10,000 (US dollars), larger systems cost more than $10,000, and that is a typical range, not a quote. We quote after a discovery conversation, and the review is scoped as its own piece of work before any fix is quoted.
No. We ask for read-only access to the repository, the database schema and its access rules, the deployment settings and a list of third-party accounts. No live customer data and no ability to change anything. Reproducing a finding happens against a local or staging copy.
Less than you would think. Whatever tool wrote it, what is reviewed is a codebase plus the services it connects to: the framework, the database, the sign-in and where it is hosted. If the tool locks the code inside its own platform, we will tell you what moving it out involves.
Often only part of it. If the data model is sound and permissions are enforced in the database, harden it. If permissions live only in the interface or the schema is tangled, rebuild that layer and keep the screens as the specification. Nobody can tell which from outside, which is why the review comes first.
We have published one related project, the materials marketplace: an app first generated on an AI app builder, audited and moved onto its own database. It was a migration, not a standalone review, and we will not present it as more. Beyond that you can judge the method, in our vibe coding to production article, and the controls we look for in systems we built ourselves, such as row-level security on the school ERP and the audit trail on the trading ERP.
Sources
Statements about what a platform, regulator or provider says come from their own pages. Rules and limits change, so check the current page before you rely on one.
- Security · Anthropic (Claude Code Docs)
Page copy drafted with AI assistance. Skofi is accountable for it. Editorial policy
Tell us about the process that keeps costing you.
A 15-minute call is usually enough to say whether this is an automation, an integration, or something that should be built, and whether we are the right people for it.
What happens on the call
- 15 minutes, no deck
- We map the process on the call
- A written scope, or an honest no