An AI-built app is not secure because the preview works, the login screen looks finished, or the builder reports no obvious errors.
Before launch, you need to test a different question: what can a user, browser, API caller or failed integration do that the interface was not designed to show?
That matters especially when a prototype starts handling real accounts, customer records, payments, uploaded files or admin actions. AI-assisted builders can compress implementation time dramatically, but they do not remove the need to reason about trust, authorization and failure states.
This is the security audit I would use as a founder-level gate before treating an AI-built MVP as production-ready.
The short version
Audit these boundaries before launch:
- authentication and session behavior
- authorization between users and roles
- database grants and Row Level Security
- frontend versus server-side secrets
- privileged API and Edge Function operations
- file and storage access
- payments, webhooks and entitlement state
- admin routes and destructive actions
- input handling and exposed endpoints
- dependency and configuration risk
- logs, errors and recovery
- ownership and production access
Do not ask only, “Can the correct user do this?” Also ask, “Can the wrong user do it if they bypass my interface?”
That second question catches a surprising amount of production risk.
1. Start by drawing the trust boundaries
Before testing individual screens, write down the parts of the system that are allowed to trust each other.
For a typical AI-built SaaS app, that may include:
- public browser/client
- authenticated user
- administrator or staff user
- database
- server-side functions
- storage
- payment provider
- email provider
- third-party APIs
- deployment and repository accounts
Then identify which operations are privileged.
Creating an account is different from changing another user’s role. Reading a public product catalogue is different from reading invoices. Starting checkout is different from marking an order paid. Uploading a profile picture is different from reading every customer’s private document.
Security becomes easier to reason about once those boundaries are explicit.
2. Test authorization, not just authentication
Authentication answers who is this user? Authorization answers what is this user allowed to do?
A login screen can work perfectly while authorization is broken.
For every important resource, test at least four states where they apply:
- signed out
- signed in as the owner
- signed in as a different normal user
- signed in as an administrator or manager
Do not perform these tests only through buttons in the UI. A hidden button is not an access-control system.
Try the underlying request with a different record ID. Try opening another user’s URL. Try reading, updating and deleting records that belong to somebody else.
OWASP’s 2025 Top 10 keeps Broken Access Control at number one and specifically calls out cases where users can view or edit another person’s account by manipulating identifiers or requests. OWASP also recommends enforcing access control in trusted server-side code or serverless APIs rather than relying on controls an attacker can modify in the client.
Source: https://top10.owasp.org/2025/A01_2025-Broken_Access_Control/
For a multi-tenant product, this is one of the highest-value tests you can run before launch.
3. If you use Supabase, audit RLS table by table
Do not reduce a Supabase security review to “RLS is enabled.”
The real question is whether grants plus policies produce the access model you intended.
Supabase’s current documentation explains that exposed tables need Row Level Security and appropriate grants. It recommends testing allowed and denied operations for select, insert, update and delete, including unauthenticated and authenticated roles.
Source: https://supabase.com/docs/guides/database/postgres/row-level-security
For each exposed table, write down:
- who may read rows
- who may create rows
- who may update them
- who may delete them
- whether ownership is tied to the authenticated user’s ID
- whether staff roles have intentionally broader access
- what unauthenticated visitors can do
Then test the negative cases.
If User A owns invoice A, can User B read it by changing the invoice ID? Can User B update it? Can an unauthenticated request insert a row you assumed required login?
A policy that exists but expresses the wrong rule is still a security bug.
Supabase’s production checklist also recommends reviewing database security and ensuring RLS is enabled with reasonable policies before production.
Source: https://supabase.com/docs/guides/deployment/going-into-prod
4. Separate public keys from actual secrets
One of the easiest mistakes in an AI-assisted build is treating every environment variable as equally safe.
Some values are designed to be present in client applications. Others grant privileged access and must never reach the browser.
Supabase explicitly says its publishable key, and the older anon key, can be used from the frontend when RLS and least-privilege access are correctly configured. By contrast, secret and service-role keys bypass RLS and must remain on backend infrastructure.
Source: https://supabase.com/docs/guides/database/secure-data
Audit:
- frontend bundles
- environment files committed to Git
- repository history where relevant
- deployment variables
- browser network requests
- logs and error messages
- copied example code
Do not assume a value is secret merely because it came from an .env file. In many frontend build systems, variables intentionally exposed to client code are compiled into assets a visitor can inspect.
The correct question is: what authority does this credential grant?
If it can bypass user-level authorization, create refunds, administer users or access private backend data, it belongs on trusted server-side infrastructure.
5. Audit privileged functions as if the UI did not exist
AI builders are good at making the happy path feel complete. Attackers do not have to use the happy path.
For every server function or API route that changes something important, check:
- does it authenticate the caller when required?
- does it authorize this specific action?
- does it validate record ownership?
- does it validate input on the server?
- can a normal user call an admin operation directly?
- can the request be replayed safely?
- are errors useful to operators without leaking sensitive information?
Pay special attention to functions that change roles, issue credits, create payments, generate signed links, delete records or use privileged database credentials.
If the function uses a service credential, its own authorization check becomes extremely important because the database may correctly trust the function even when the function incorrectly trusts the caller.
6. Test storage separately from database rows
File access often has a different security model from application data.
A profile table may be protected while the related storage bucket is accidentally public. Or uploads may be restricted while reads are not.
For private documents, test whether a different user can guess or reuse an object path. Check upload, read, replace and delete behavior independently.
Supabase Storage uses RLS policies on storage.objects for access control, so storage rules deserve the same explicit review as application tables.
Source: https://supabase.com/docs/guides/storage/security/access-control
If your product handles tenancy documents, invoices, identity files, medical information or private customer uploads, “the URL is difficult to guess” is not an authorization strategy.
7. Treat payment success and product access as separate states
A payment integration has at least two systems telling you something happened: the payment provider and your application.
Do not make a browser redirect the only authority for granting paid access.
Audit the full state transition:
checkout created → payment provider confirms event → webhook verified → application records payment → entitlement/access changes → user sees correct state
Test duplicate events, delayed events and retries. Test what happens when payment succeeds but your database update fails.
This is particularly important in AI-built SaaS products because the UI can look successful while the backend state is inconsistent.
If you are already debugging that exact failure, see Lovable Stripe Payment Succeeds but Access Stays Locked: What to Check.
The goal is not merely “Stripe works.” The goal is that money, application state and user entitlement remain consistent when something fails halfway through.
8. Audit admin access as a separate product surface
Admin panels deserve more scrutiny, not less, because their actions are more powerful.
Check whether a normal authenticated user can:
- discover an admin route
- call its APIs directly
- change a role field in a request
- read broad customer data
- trigger destructive actions
- impersonate another user without a controlled audit trail
Do not rely on client-side route guards alone.
A browser can hide /admin; it cannot make the backend forget to authorize an admin request.
For products with staff roles, document the permission model rather than scattering one-off checks through components. “Admin can do everything” may be acceptable for a tiny internal product, but it should still be an intentional rule enforced at the trusted layer.
9. Test inputs where they cross into trusted systems
Review forms and API inputs that reach:
- database queries
- HTML rendering
- email templates
- file names and paths
- third-party APIs
- AI prompts
- server-side commands or transformations
Validation in the browser improves user experience, but server-side validation protects the system from callers who bypass the browser.
OWASP’s current Top 10 also includes Injection and Insecure Design among its major application-security risk categories.
Source: https://top10.owasp.org/2025/
For AI features, think beyond classic forms. If user-supplied content becomes part of an LLM prompt that can access tools or private context, define what the model is allowed to retrieve or execute. A clever prompt should not become an authorization bypass.
10. Review dependencies and production configuration
Security is not only application logic.
Before launch, review:
- dependency vulnerability reports
- unused packages
- CORS configuration
- production versus preview URLs
- authentication redirect URLs
- debug endpoints
- source maps and error exposure where relevant
- rate limiting on abuse-prone endpoints
- email/password reset flows
- backups and recovery expectations
OWASP Top 10:2025 includes Security Misconfiguration and Software Supply Chain Failures as major categories, which is a useful reminder that secure code can still be deployed insecurely.
A prototype often accumulates temporary settings while you are trying to make it work. Production is the point where those shortcuts need an explicit review.
11. Make security tests repeatable
A one-time manual check is better than nothing, but repeatable tests are more valuable.
For access control, create cases such as:
- owner can read own record
- owner can update own record
- different user cannot read it
- different user cannot update it
- signed-out visitor cannot access it
- manager can perform only the manager actions intended
Supabase now explicitly recommends database tests for RLS allow-and-deny behavior in its RLS guidance.
The benefit is not only catching today’s bug. It prevents a later AI-generated change from quietly reopening access you had already fixed.
This is one of the biggest differences between “the app works today” and “the product is maintainable.”
12. Know when a founder-level audit is no longer enough
You do not need a heavyweight enterprise penetration test for every prototype.
But the risk changes when the app begins handling:
- real customer identities
- private business records
- financial transactions
- healthcare or other sensitive data
- multiple companies or tenants
- staff/admin permissions
- valuable uploaded documents
- public APIs
- meaningful revenue
At that point, if you cannot confidently explain who can access each sensitive resource and why, get another technically competent person to review the system before launch.
That review should test behavior, not merely read the generated code and say it looks fine.
A practical launch decision
The right question is not whether AI wrote 20%, 80% or 100% of the implementation.
The question is whether the finished system has been tested against the risks created by its actual architecture and business model.
For a simple public marketing prototype with no accounts or sensitive data, the security surface may be small. For a multi-user SaaS with Supabase, payments and private records, the surface is completely different even if both were built with the same AI tool.
If you are still deciding whether the whole product is ready to leave prototype mode, use my AI-built app production checklist. If the codebase has reached the point where prompting is no longer enough, read When Should You Hire a Developer for a Lovable App?.
If you want help reviewing the architecture, access model, payment state and production risks of an AI-assisted MVP, see my MVP development service or contact me.



