Yes, a vibe-coded app can be safe enough for sensitive data, but not by accident. We built a healthcare AI app with AI coding agents, and an independent penetration test found no critical, high or medium issues. What got it there was the engineering around the AI, not the AI itself.
The app checks clinical reports for a UK healthcare provider. It handles special category health data, uses Anthropic's Claude to do the checking, and was written almost entirely by Claude Code. It is deployed entirely within the provider's own Microsoft Azure tenant. Between 19 and 22 October 2026, an independent UK penetration testing firm spent four days trying to break it.
The difference was how we used the AI. We didn't vibe code it. We used AI-assisted engineering: AI writes most of the code, but people set the rules, review every change and test it.
Here is what we did, what the test showed, and what we'd tell anyone shipping an AI-built app.
Vibe coding vs AI-assisted engineering: why the difference matters
Vibe coding means describing what you want to an AI tool and accepting the code it writes without reading it. AI-assisted engineering uses the same tools, with people in charge.
AI-assisted engineering: AI writes most of the code. People set the rules, review every change and test it. The AI can be exactly the same as in vibe coding. The discipline around it is what makes the result safe.
Term | What it means | Where the risk sits |
|---|---|---|
Vibe coding | You describe what you want and accept what the AI writes without reading it. | Nobody has checked the code, so nobody knows what it does with access, secrets or bad input. |
AI-assisted engineering | AI writes most of the code. People set the rules, review every change and test it. | In the rules, reviews and tests. Weak ones let the same problems through, just more slowly. |
Our app sits firmly in the second row. Claude Code wrote nearly all of it, but a person read, questioned and approved every change before it was merged.
The risk in vibe coding isn't that an AI wrote the code. It's the "accept without reading" part. Code nobody has read is code nobody has checked for access control, leaked secrets or what happens when someone sends it something unexpected. That is true whether a model wrote it or a tired developer did at 2am.
Why people worry: what the research says
People worry because the evidence says AI-generated code is often insecure by default. The useful question is what you put around it.
Veracode has been testing code from more than 100 large language models since 2025. Its 2025 GenAI Code Security Report found that AI-generated code introduced a security flaw in 45% of tests. The 2026 edition, published in July 2026, put the average security pass rate at 56%, virtually unchanged from the year before.
Read those figures carefully. Veracode tested raw models with no security-specific prompting, and no agents, tooling or human review. They describe what a model writes on its own, not the defect rate of every codebase built with AI. That caveat matters, because the controls around the model are exactly what changes the outcome.
The real-world version looks like CVE-2025-48757. In 2025 a researcher scanned 1,645 apps showcased by the AI app builder Lovable and found 170 of them with database row-level security missing or too loose, so anyone could read or write data they should never have reached. The supplier disputes the CVE, on the grounds that each customer is responsible for securing their own app's data. Both things can be true: the tool produced something that worked, and nobody checked who could reach the data.
So, is AI-generated code secure? Not by default. The typical failures are familiar:
missing access checks on the server;
permissive defaults, such as open database rules;
secrets in code or config files;
no rate limits on sign-in or expensive operations.
None of these are exotic. They're the mistakes people make too, produced faster and with more confidence.
The project: an AI app handling clinical reports
The app checks clinical diagnostic reports against a healthcare provider's report template and quality checklist. Contracted clinicians write the reports for a UK healthcare provider. The app uses Claude in three review passes and returns a Word copy with comments, which a human QA officer reviews before deciding what to send back.
It has firm limits. It never judges clinical reasoning, never changes the clinician's wording and makes no automated decision about anyone.
The data is about as sensitive as it gets: special category health data about patients, under UK GDPR. There is a data protection impact assessment (DPIA), and the model provider is in the US, which brings its own questions about where data goes.
That is why the whole app runs inside the provider's existing Microsoft Azure tenant, in a UK region, not on our infrastructure or a third-party platform. The data stays under the provider's own security controls, and staff sign in through the provider's existing single sign-on, with multi-factor authentication.
It started life as a prototype used in a small pilot. Version 2 was rebuilt almost entirely by Claude Code, working under a written agreement, with a person reviewing and approving every change. By the time of the pen test it had around 330 automated test files, and every change runs through CI: lint, type checks and the core tests.
What the pen test found
The independent pen test found no critical, high or medium issues. The testers did not demonstrate any compromise, and they did not get past the AI guardrails.
It was a grey-box web application and AI assessment over four days, 19–22 October 2026. Grey-box means the testers knew how the app was meant to work and logged in as real users, rather than attacking blind from outside. They had four ordinary user accounts and the hosted test environment.
Severity | Findings |
|---|---|
Critical | 0 |
High | 0 |
Medium | 0 |
A clean result isn't the same as a perfect app. It means people paid to break it, with real user accounts and four days to try, found no serious way in.
Seven things that made an AI-built app pass
Securing a vibe-coded app is mostly about what surrounds the AI. These are the seven things that did the work.
1. Rules for the AI before code
An AI coding agent follows written rules far better than good intentions, so write them down and make the build enforce them.
A working agreement sits in the repository and every AI agent session reads it. It sets hard prohibitions:
never log document text;
never add patient identifiers or report text to the database schema;
never bypass the validation gate;
no live AI calls in tests;
no real patient data in the repository.
The boundaries between parts of the code are enforced by a lint rule in the build. Only the background worker can call the AI model, for example, and the AI engine can't touch the database. If an agent breaks a boundary, the build fails. It can't quietly drift.
2. Privacy by design that a test can fail
Privacy by design only counts if something fails when it breaks.
Report text never reaches the database, the logs or the audit trail. The logger refuses long or multi-line values before it writes anything. A test runs the full pipeline and fails if any twelve-word run of a report appears in a log line or a database row.
Documents are deleted 14 days after review by default, 90 days at most, and the deletion can't be undone. The safest sensitive data is the data you no longer hold.
3. AI-specific safeguards against prompt injection
Prompt injection is first in the OWASP Top 10 for LLM Applications, and the defence starts with treating every document as untrusted input.
Each report is wrapped in delimiters before the model sees it. Text that imitates those delimiters, including lookalike and invisible characters, is neutralised. Hidden text in an uploaded Word file is detected and shown to staff.
On the way out, the AI's findings must fit a strict schema. Then a deterministic validation gate, written as ordinary code rather than handed to the AI, drops any finding that cites a checklist item that doesn't exist or names a person who isn't in the report. If too many findings are dropped, the whole report fails and nothing is written.
Models are pinned at temperature 0, and any model change needs a benchmark run first. An optional step that swaps names, dates, addresses and GP details for stand-ins before the AI sees a report is under test, and switched off in production until it proves itself.
4. Boring, solid infrastructure
Least privilege everywhere: each part of the system can reach only what it needs, inside the provider's own cloud.
The whole app is deployed within the provider's existing Microsoft Azure tenant, in a UK region.
Data stores are private, with no public endpoints.
The API, the worker and the background jobs each have their own identity and get only the secrets they use.
Database logins have the least rights needed, and the audit table is insert-only for the app.
Secrets live in a managed vault that can't be wiped by mistake.
Deployments don't rely on stored cloud credentials.
The app runs hardened, without administrator rights.
Uploads are checked for macros, embedded objects and oversized archives before they are read.
Security headers include a strict Content Security Policy and HSTS.
None of this is clever. That's the point.
5. We attacked it ourselves first
The most serious issues in the project were found by our own review, a week before the testers arrived.
We went looking for what a tester would look for. We found that an ordinary user could open other users' reports. Now each user opens only their own cases, and managers can open all of them. The review also showed that some permission checks failed open when no manager was configured, that first sign-in linked accounts by display name rather than email, and that some requests were read before the session was checked.
All of it was fixed before the testers arrived. CI now runs the access-control tests on every change, and fails if a new report route has no ownership check.
6. A second AI paid to disagree
An AI reviewer that never saw the author's reasoning catches what the author's own tests miss.
For each significant change, a separate AI agent gets the requirement and the code, but not the author's reasoning or tests. It's told to attack the change and write its own tests. This repeatedly caught defects that the author's passing tests missed. On one feature it found eleven before release.
A person still reviews and approves every pull request. The second agent widens the review; it doesn't replace it.
7. Governance that keeps up
A DPIA written once and filed away isn't governance. Ours changes with the app.
After the pen test, we restructured the DPIA to track what was delivered, the risks identified, the mitigations, the pen test and the risks still open. We added breach detection: alerts on bulk refused sign-ins, failed audit checks and unexpected access to secrets, database audit logging, 90-day log retention and a 72-hour breach response procedure, in line with UK GDPR's 72-hour window for reporting a breach to the ICO.
Some data protection actions were still open after the test, such as the processing terms with the model provider. So the app runs on synthetic reports until they close. That's the process working as it should: the software was ready first, and real patient data waits until the paperwork is too.
What we'd tell anyone shipping an AI-built app
Keep the AI, and add the engineering around it. If you're about to put an AI-built app in front of real customer or regulated data, work through this list first:
Write rules for the AI before the first prompt.
Enforce boundaries in the build, not in a document.
Check permissions on the server, and test every route.
Keep sensitive data out of logs, and test that you do.
Treat anything the model reads as untrusted input.
Put a deterministic gate on model output.
Have a second agent attack each change.
Have a person review every change.
Attack it yourself before the testers do.
Get an independent pen test, then a retest.
None of this means the AI did it alone. This project needed a senior person who understood security, data protection and the domain, directing the agents and reviewing their work. The UK's NCSC guidelines for secure AI system development make the same point at a larger scale: security has to run through design, development, deployment and operation.
And a pen test is a snapshot. It shows the app held up between 19 and 22 October 2026, not that it is secure forever. The controls above, and regular retesting, do that ongoing work.
So, can vibe-coded apps be safe?
Vibe-coded in the strict sense, accepted without reading: probably not, and you won't know until someone tests it. Built with AI-assisted engineering, with AI coding agents under clear rules, human review and real testing: yes, and we have the pen test to show for it.
If you've got an AI-built app heading towards real data, or want one built properly from the start, talk to us. You can see more about our bespoke AI applications, how we deliver AI projects and our wider AI agency and consultancy work.
:quality(75))
:quality(75))
:quality(75))
:quality(75))