How I Would Fix database rules leaking customer data in a Bolt plus Vercel client portal Using Launch Ready.
The symptom is usually simple to spot: one customer logs in and can see another customer's records, invoices, files, or support messages. In a client...
How I Would Fix database rules leaking customer data in a Bolt plus Vercel client portal Using Launch Ready
The symptom is usually simple to spot: one customer logs in and can see another customer's records, invoices, files, or support messages. In a client portal, that is not just a bug. It is a trust break, a support fire drill, and in the US, UK, and EU it can become a data protection incident fast.
The most likely root cause is bad authorization at the data layer, not the UI. In Bolt-built apps deployed on Vercel, I usually find one of three things: database rules are too open, the app is querying shared tables without filtering by tenant or owner, or secrets and service keys are being used in the wrong place. The first thing I would inspect is the actual path from browser to database: which account is making the request, what role it has, and whether the database policy is enforcing customer boundaries or just trusting the frontend.
Triage in the First Hour
1. Check whether the leak is active right now.
- Open the portal in an incognito session.
- Log in as two different customer accounts.
- Compare what each account can list, view, download, and search.
- If cross-account data is visible, treat it as an active incident.
2. Inspect recent deploys on Vercel.
- Look at the last 3 production deployments.
- Note any schema changes, environment variable changes, or auth-related commits.
- Confirm whether the issue started after a deploy or after a database rule change.
3. Review application logs and error traces.
- Check Vercel function logs for auth errors, unexpected 200 responses, or requests using privileged keys.
- Look for repeated queries returning more rows than expected.
- Check whether any serverless function is logging raw payloads or customer identifiers.
4. Audit database rules and policies first.
- Review row-level security policies if you are on Postgres with RLS.
- Review Firestore rules if you are on Firebase/Supabase-style tooling.
- Confirm that read access requires ownership, tenant match, or membership checks.
5. Inspect environment variables in Vercel.
- Verify no service role key is exposed to client-side code.
- Confirm public variables are only truly public values.
- Rotate any secret that may have been copied into a frontend bundle.
6. Check shared tables and query filters.
- Find every query that reads portal records.
- Confirm each query filters by user_id, org_id, account_id, or tenant_id.
- Look for "get all" patterns hidden behind search endpoints or admin views.
7. Freeze risky changes until you understand scope.
- Pause new deploys for 24 hours unless they are part of the fix.
- If needed, temporarily disable access to affected views rather than guessing.
Here is the kind of check I would run first if this were a Postgres-backed app:
-- Verify whether rows are protected by ownership select table_name from information_schema.tables where table_schema = 'public'; -- Example policy check select * from pg_policies where tablename = 'portal_records';
Root Causes
1. Missing row-level security or equivalent rules
- Confirmation: a logged-in user can query rows without proving ownership or membership.
- What I look for: tables with no RLS enabled, permissive read policies, or "authenticated users can select all" rules.
2. Frontend filtering only
- Confirmation: the UI hides other customers' records after fetch instead of preventing access at source.
- What I look for: queries that pull broad datasets and then filter them in React before rendering.
3. Wrong use of privileged server keys
- Confirmation: server-only service credentials are used in routes that can be called too broadly or exposed through client code paths.
- What I look for: service role keys in browser bundles, edge functions with weak authorization checks, or helper functions that bypass normal rules.
4. Broken tenant scoping
- Confirmation: records have org_id or tenant_id fields but queries do not enforce them consistently across all endpoints.
- What I look for: one endpoint scoped correctly and another returning global data from the same table.
5. Misconfigured auth claims or session mapping
- Confirmation: user identity exists but does not map correctly to account ownership in the database.
- What I look for: stale JWT claims, wrong profile linkage, missing join table entries, or mismatched auth provider IDs.
6. Overbroad admin/debug routes left in production
- Confirmation: an internal route returns all customers' data when hit with an authenticated session or predictable URL.
- What I look for: debug endpoints added during development and never removed before launch.
The Fix Plan
I would fix this in layers so we stop the leak first and avoid breaking legitimate access next.
1. Stop exposure immediately.
- Disable any endpoint that returns unscoped customer data until it is patched.
- If needed, put affected portal sections behind a maintenance message while preserving login and safe pages like profile settings.
2. Move authorization into the database rules.
- Enforce row-level access based on user_id or tenant_id at read time.
- Do not rely on frontend filters as your security boundary.
- For shared organization portals, require membership checks through an org_users join table.
3. Remove privileged access from browser paths.
- Keep service-role secrets only inside server-side functions or secure backend jobs.
- Audit Bolt-generated code for accidental client-side imports of admin clients or secret env vars.
4. Tighten every query path one by one.
- Search all portal queries for list endpoints and detail endpoints.
- Add explicit filters to every read path even if RLS exists. Defense in depth matters here because bugs happen above the database too.
5. Add deny-by-default policies first.
- Start with "no access unless explicitly allowed."
- Then add only the minimum read/update permissions required for each role:
customer, staff member, admin.
6. Rotate secrets if there was any chance of exposure.
- Rotate database credentials if they were logged or bundled incorrectly.
- Rotate API keys used by email delivery, storage access, analytics admin tools, and monitoring webhooks if they were shared anywhere unsafe.
7. Validate redirects, subdomains, and auth callback URLs on Vercel and Cloudflare.
- Make sure login callbacks only go to approved domains.
, Oops? Let's keep going cleanly:
7. Validate redirects, subdomains, and auth callback URLs on Vercel and Cloudflare.
- Make sure login callbacks only go to approved domains.
8. Deploy with monitoring turned up before traffic returns fully.
- Watch error rates, auth failures,
- watch unauthorized response counts,
- watch unusual spikes in record reads,
- watch support tickets from real users during the first hour after release.
A safe rollout sequence looks like this:
1. Patch rules in staging first. 2. Run seeded test accounts across two tenants. 3. Deploy to production behind low-risk traffic windows if possible. 4. Monitor p95 function latency and auth failure rate for 60 minutes.
My opinionated recommendation: do not start by redesigning screens or rewriting Bolt components. Fix authorization at the data boundary first. If you skip that step because "the UI already hides it," you will ship another leak later under load or through a new endpoint.
Regression Tests Before Redeploy
I would not redeploy until these checks pass:
1. Cross-account isolation test
- Acceptance criteria: Account A cannot list or view Account B records through any endpoint or screen.
2. Direct API request test
- Acceptance criteria: A crafted request using Account A's session still returns only Account A data even if someone changes IDs in the URL or request body.
3. Unauthorized role test
- Acceptance criteria: Unauthenticated users get blocked from protected routes and APIs with proper 401/403 responses.
4. Admin scope test
- Acceptance criteria: Admin users can see only intended global views; they cannot accidentally expose raw tenant data beyond their job needs.
5. Session expiry test
- Acceptance criteria: Expired sessions fail closed and do not fall back to cached privileged data.
6. File access test
- Acceptance criteria: Documents uploaded by one client cannot be fetched by another client through direct links unless signed access was intentionally granted.
7. Regression coverage target
- Acceptance criteria: At least 80 percent coverage on authorization-critical routes and database policy tests before production redeploy.
8. Smoke test after deploy
- Acceptance criteria: Login works within 30 seconds; dashboard loads; no cross-tenant records appear; support inbox remains quiet for at least 15 minutes after release.
Prevention
I would put guardrails around this so it does not come back two weeks later when someone adds "just one more endpoint."
- Security review gate:
Every pull request touching auth, queries, storage links, or roles gets reviewed for ownership checks before merge.
- Database policy tests:
Add automated tests that prove one tenant cannot read another tenant's rows.
- Least privilege secrets:
Split public env vars from server-only secrets clearly in Vercel settings and document them in handover notes.
- Logging hygiene:
Never log full tokens, full payloads containing PII, file URLs with long-lived signatures, or admin credentials.
- Monitoring:
Alert on unusual spikes in list queries per user, repeated forbidden responses, elevated error rates, and direct object reference patterns such as sequential ID probing attempts blocked by policy rather than UI alone.
- UX guardrails:
Show empty states when no data exists instead of loading broad datasets then hiding them later on screen; this reduces both leakage risk and wasted backend work.
- Performance guardrails:
Keep portal list endpoints under p95 300 ms where possible; slow authorization checks often lead teams to remove them later unless they are measured properly.
When to Use Launch Ready
Launch Ready fits when you need me to stabilize the launch layer fast without turning this into a month-long rebuild. email authentication, Cloudflare, SSL, deployment, secrets, and monitoring so your fixed portal can go live safely instead of sitting half-broken behind staging links.
This sprint makes sense if:
- your app already works but deployment is messy,
- you need DNS/redirect/subdomain cleanup,
- your environment variables are inconsistent between Bolt and Vercel,
- you want DDoS protection plus uptime monitoring before sending traffic,
- you need SPF/DKIM/DMARC set correctly so client emails do not land in spam,
- you want a clean handover checklist instead of tribal knowledge buried inside chat threads.
What I would ask you to prepare:
- Vercel access,
- domain registrar access,
- Cloudflare access if already connected,
- database admin access,
- email provider access,
- a short list of protected routes and customer roles,
- any known examples of leaked records or suspicious behavior.
If your portal has already leaked customer data once, Launch Ready should be paired with an authorization audit sprint next so we fix both deployment safety and data boundary safety together.
References
1. Roadmap.sh API Security Best Practices https://roadmap.sh/api-security-best-practices
2. Roadmap.sh Cyber Security https://roadmap.sh/cyber-security
3. Roadmap.sh QA https://roadmap.sh/qa
4. Supabase Row Level Security Docs https://supabase.com/docs/guides/database/postgres/row-level-security
5. Vercel Environment Variables Docs https://vercel.com/docs/projects/environment variables
---
Take the next step
If this is a problem in your product right now, here is what to do next:
- [Use the free Cyprian tools](/tools) - estimate cost, score app risk, check launch readiness, or pick the right service sprint.
- [Book a discovery call](/contact) - I will tell you honestly whether you need a sprint or if you can DIY the next step.
*Written by Cyprian Tinashe Aarons - senior full-stack and AI engineer helping founders rescue, launch, automate, and scale AI-built products.*
Cyprian Tinashe Aarons — Senior Full Stack & AI Engineer
Cyprian helps founders rescue, secure, deploy, and automate AI-built apps with production-grade engineering, launch systems, and AI integration.