Most advice on cloud application security starts in the wrong place. It tells you to review IAM, lock down buckets, enable logging, and buy a posture management tool. All of that matters. None of it saves you if your app lets one logged-in user read another user's records, call a privileged RPC, or pull a secret out of a mobile bundle.
That blind spot is common in modern stacks. Teams build quickly on Supabase, Firebase, edge functions, mobile clients, and generated APIs. The infrastructure looks clean. The application logic leaks anyway.
If you're shipping on a BaaS platform, your real attack surface often lives in Row Level Security, RPC permissions, service roles, API design, and frontend secret handling. That's where developers make expensive mistakes. That's also where practical cloud application security needs to start.
Your Cloud Provider Is Not Your Security Team
AWS, Google Cloud, Supabase, and Firebase give you secure building blocks. They don't secure the app you assemble from them.
That sounds obvious, but teams still behave as if choosing a reputable platform transfers most of the risk. It doesn't. The provider protects the underlying service. You still choose who can access data, which functions run with higher privileges, what gets exposed to the client, and whether your defaults stay safe after the third rushed release.
In the UK, 43% of organisations experienced a cyber breach or attack in the last 12 months. In cloud environments, 23% of all security incidents stem from misconfigurations, and those misconfigurations account for 38% of cloud security breaches globally. The average cost of a cloud security breach in the UK is estimated at $5.17 million per incident, according to SecurityBrief's reporting on the UK cyber survey and cloud breach trends.
Secure platform does not mean secure product
A Supabase project with RLS enabled can still leak data if the policy logic is wrong. A Firebase app can still expose records if your rules assume a path is private but a client can query it differently. A mobile app can still hand an attacker what they need if the bundle includes a key, endpoint, or privileged token that was meant to stay server-side.
That's why infrastructure-first advice often disappoints developers. It focuses on the cloud account and barely touches the thing users attack directly: your application.
Practical rule: If a user can trigger it from a browser, app, or API client, treat it as part of your public attack surface.
What teams usually get wrong
The most common failure pattern isn't a dramatic platform compromise. It's a development shortcut that survives into production:
- Trusting defaults: A generated API or permissive rule ships because the team assumed the platform's defaults were production-safe.
- Confusing auth with access control: A valid session exists, so developers assume the request is authorised.
- Using service privileges too broadly: Admin capability leaks into edge functions, cron jobs, and support tooling.
- Skipping app-layer review: The team buys a CSPM product and assumes they're covered. They aren't. Cloud security posture management helps with infrastructure hygiene, but it won't prove whether your RLS logic stops cross-tenant reads.
Cloud application security starts where the provider's responsibility ends. That's your schema, your policies, your tokens, your APIs, and your release process.
Rethinking Cloud Security Threat Models
The cleanest way to think about cloud application security is this: your provider owns the building, but you still control the locks, the room access, and what sits in plain sight on the table.
If the building has strong foundations and a staffed lobby, that's good. If your flat door doesn't latch properly, visitors can still walk in.

Think in layers, not products
Most startup teams threat-model the wrong layer first. They worry about firewalls and region setup before asking a more immediate question: "What can a normal user do if they send requests we didn't expect?"
A practical model for cloud application security usually has five layers:
| Layer | What the provider mostly handles | What your team still owns | |---|---|---| | Infrastructure | Physical security, host maintenance, managed service uptime | Service configuration choices, exposure decisions | | Network | Baseline platform controls | Public endpoints, trust boundaries, allowed callers | | Application | Very little | Business logic, validation, auth flows, session use | | Data | Encryption features and storage controls | Query access, tenant isolation, retention, sensitive fields | | Identity | Authentication primitives | Role design, privilege scope, token claims, service identities |
This is why "we run on a trusted platform" isn't a threat model. It's procurement.
What attackers actually test
Attackers don't care whether your stack diagram looks modern. They care whether they can:
- Read data across tenants by tweaking identifiers or query parameters
- Invoke privileged functions that were meant for internal use
- Replay or misuse tokens that carry too much authority
- Pull secrets from clients because they were bundled into JavaScript, IPA, or APK assets
- Abuse weak business rules such as credit allocation, invitation flows, or role escalation paths
A secure cloud application isn't just one with hardened infrastructure. It's one where a valid but curious user can't do anything surprising.
A developer threat model that works
For BaaS-backed apps, I like a simple sequence:
-
List your trust boundaries
Browser, mobile app, edge function, admin script, background job, database. -
Mark every identity type
Anonymous user, signed-in user, support user, service role, CI account. -
Map every direct data path
Which clients can query tables, invoke functions, upload files, or call third-party APIs. -
Ask the ugly questions
Can a normal user change a record owner field? Can they call an RPC out of order? Can they supply an ID for another customer? Can a mobile build reveal anything sensitive at rest? -
Test for proof, not intent
A policy that "should" block reads isn't enough. You need to prove it blocks reads.
Cloud application security takes on a concrete form. You're not defending an abstract cloud. You're defending specific actions taken by real users, compromised devices, leaked tokens, and over-trusted backend paths.
The New Attack Surface BaaS and Mobile Backends
A lot of modern apps don't fail because S3 was public or a security group was wide open. They fail because the data layer was exposed with just enough logic to seem safe.
A typical startup flow goes like this. The team chooses Supabase or Firebase because it speeds up auth, storage, database access, and realtime features. That decision is often sensible. The trouble starts when convenience features become production architecture.

Where the real exposure sits
Most cloud security writing still over-focuses on posture and under-explains runtime access control. That's a serious gap for BaaS stacks. The UK NCSC states that 80% of cloud breaches in the UK stem from misconfigured service identities and granular access controls, as discussed in the NCSC guidance on using a cloud platform securely.
That matters because Supabase and Firebase make it easy to expose application capabilities directly to clients. Done well, that reduces backend complexity. Done carelessly, it moves your trust boundary into places many teams barely test.
A realistic failure chain
Start with a harmless product requirement: "Users can update their profile, invite teammates, and view organisation data."
The rushed implementation often looks like this:
- the mobile app talks directly to the backend
- an RPC is added for convenience because the logic spans multiple tables
- a service role is used during development because permissions are annoying
- RLS gets enabled later, after features already depend on broad reads
- QA checks that the happy path works, not that cross-user access fails
No single choice looks catastrophic. The combination is.
A weak RLS policy might allow select on a table where access should depend on organisation membership. An RPC might run as a more privileged role than intended. A frontend bundle might expose a key or endpoint that makes internal tooling discoverable. A signed-in user then becomes the attacker's starting point.
The dangerous bug in BaaS apps usually isn't "no security". It's "security that looks present but breaks under a slightly different request".
Common BaaS mistakes that deserve more attention
RLS policies that trust user-controlled fields
If a policy assumes user_id or organisation_id on a row is always trustworthy, an attacker may be able to create or update records in ways that satisfy the rule later. Policies must be written against trusted relationships, not convenient fields alone.
Public or weakly protected RPCs
Database functions often become hidden backends. Teams create them for speed, then forget they are callable interfaces with permissions, side effects, and input-handling risk.
Secrets inside client artefacts
This is especially ugly in mobile apps. If a value is in the shipped app, an attacker should be assumed able to recover it. Client-side bundles are delivery vehicles, not secret stores.
Security review that stops at infrastructure
A green dashboard for cloud configuration tells you almost nothing about whether one tenant can read another tenant's invoices.
BaaS platforms are productive because they collapse layers. That same design means mistakes in auth, authorisation, and data access also collapse faster into user-facing breaches.
Securing Access Authentication and Authorisation
Many teams spend more time on login than on permissions. That's backwards.
Authentication answers "who are you?" Authorisation answers "what are you allowed to do?" Many cloud application security failures happen after authentication succeeded. The user is real. The request is still wrong.
Cloud attacks in the UK are reported as rising 21% year over year, 80% of cloud breaches involve compromised or misused privileged credentials, and 31% of cloud data breaches are linked to API vulnerabilities. The same source notes an NCSC projection that cloud audit failures and identity drifts will cause 80% of data breaches by 2026, according to SentinelOne's cloud security statistics summary.
Authentication is the gate, not the policy
Teams often congratulate themselves once sign-in is stable. JWTs work. Sessions refresh. MFA exists for admin users. That's fine, but none of it enforces tenant isolation by itself.
A signed-in user should still fail when they try to:
- fetch another team's records
- update a role they don't own
- call a backend action reserved for support staff
- submit an object reference outside their tenant scope
If your app checks only is authenticated, you've built a lobby, not access control.
For a clean mental model, this breakdown of authentication vs authorisation is worth keeping in mind during design reviews.
Privilege drift is what hurts small teams
Startups rarely create over-privileged systems on purpose. Drift creates them.
An edge function starts with admin capability because it was easier during prototyping. A support tool reuses the same secret. A cron job gets broad access because scoping it properly takes time. Then a frontend starts depending on a result that only exists because one privileged path stayed open.
That pattern matters because compromised credentials aren't always stolen through advanced cloud-native exploitation. Sometimes the attacker gains access to something you gave too much power to. For teams working on preventing online account takeovers, the lesson maps directly to cloud apps: even a valid account becomes dangerous when session protection and permission scope are weak.
Design check: Every role in your system should have a sentence-length purpose. If you can't explain why a role exists and what it may do, it's probably too broad.
What robust authorisation looks like
Good authorisation is narrow, explicit, and testable.
- Use least privilege for service identities: Give background jobs and edge functions only the permissions they need.
- Make tenant membership authoritative: Derive access from a trusted membership relation, not from client-submitted ownership fields.
- Separate read and write rules: Many teams write one broad rule that accidentally permits both.
- Treat admin paths as separate products: Internal tooling deserves its own review, logging, and permission model.
A login system proves identity. Cloud application security depends on what happens after that proof.
Hands On Mitigation Protecting Data and APIs
The fix isn't "be more careful". The fix is to make your data layer harder to misuse.
In Supabase, that usually means stricter RLS, safer RPC design, and moving secrets out of clients. In Firebase, it means tightening rules, reducing direct client trust, and pushing sensitive operations behind controlled server-side execution. The exact syntax differs. The principles don't.
Write RLS against trusted relationships
A weak policy often checks a row field the client can influence. For example, allowing access where profiles.user_id = auth.uid() looks sensible until another workflow can create or alter that mapping in ways you didn't expect.
A stronger pattern is to anchor access in a membership table you control more tightly.
Less safe pattern
create policy "users can read their organisation data"
on public.documents
for select
using (organisation_id = current_setting('request.jwt.claim.org_id', true)::uuid);
This trusts a claim shape and can age badly if token issuance, support flows, or multi-org membership changes.
Safer pattern
create policy "members can read organisation documents"
on public.documents
for select
using (
exists (
select 1
from public.organisation_members om
where om.organisation_id = documents.organisation_id
and om.user_id = auth.uid()
and om.status = 'active'
)
);
This is better because the policy checks a server-side relationship you can inspect and test.
Separate actions and test failure paths
Developers often write one broad policy that covers every operation. That makes debugging easier at first and breaches easier later.
A cleaner split looks like this:
- Read policy: Can the user view this row?
- Insert policy: Can the user create a row in this tenant?
- Update policy: Can the user modify only the fields and rows they own?
- Delete policy: Is deletion even allowed from the client?
If you haven't written a test that proves a user from Tenant A cannot read or update Tenant B data, you don't know whether your policy works.
Lock down RPCs like public APIs
Every RPC should be treated as a callable product surface. Ask four questions:
| Check | Bad sign | Better pattern | |---|---|---| | Caller identity | Function assumes only trusted clients will invoke it | Verify caller context explicitly | | Execution rights | Function runs with elevated privileges by default | Limit execution role and grants | | Input scope | Accepts arbitrary IDs from client | Validate ownership or tenant membership inside the function | | Side effects | Updates multiple tables without guardrails | Add explicit checks before each sensitive action |
A defensive PostgreSQL function often includes permission checks before it performs the business action.
create or replace function public.archive_document(p_document_id uuid)
returns void
language plpgsql
as $$
begin
if not exists (
select 1
from public.documents d
join public.organisation_members om
on om.organisation_id = d.organisation_id
where d.id = p_document_id
and om.user_id = auth.uid()
and om.role in ('owner', 'admin')
and om.status = 'active'
) then
raise exception 'not authorised';
end if;
update public.documents
set archived_at = now()
where id = p_document_id;
end;
$$;
Don't stop at function code. Review who can execute it. A well-written function is still risky if the wrong role can call it.
Keep secrets out of the client
If a secret is embedded in a website bundle, IPA, or APK, assume it can be extracted. The right fix is architectural, not cosmetic:
- Move privileged calls server-side
- Use short-lived, scoped credentials where possible
- Separate publishable keys from privileged secrets
- Review build outputs, not just source code
A mobile app should identify the user and call approved endpoints. It should not carry hidden authority.
Automating Your Defence with CI CD and Scanning
Manual review doesn't scale with modern release speed. A founder ships a fix at midnight. A mobile developer pushes a new build before lunch. An AI coding tool generates a helper function that works perfectly and bypasses your intended permission model.
That's why cloud application security has to live in CI/CD, not in a quarterly review doc.
A 2023 BrightSec trend analysis says 70% of UK organisations now demand extreme shift left with vulnerability prioritisation, and the NCSC recommends implementing the bulk of security approaches using automation, including autonomous checks before deployment, as noted in BrightSec's application security trends analysis.

What to automate first
Don't try to automate everything at once. Start with the checks developers routinely miss under delivery pressure.
- Secret detection in source and build artefacts: Scan JavaScript bundles, IPA files, and APK files for hardcoded secrets, keys, and environment leakage.
- Schema and policy review: Flag tables with sensitive data where RLS is missing, overly broad, or inconsistent across operations.
- RPC exposure checks: Identify callable functions that lack adequate auth and authorisation safeguards.
- Regression testing for access rules: Re-run known failure cases whenever schema, claims, or membership logic changes.
A good pipeline doesn't just find defects. It blocks old defects from coming back.
Runtime probing matters more than static confidence
Static analysis helps, but BaaS security often breaks at runtime. The policy compiles. The edge function deploys. The app works. The leak only appears when a different user identity, tenant relationship, or request order hits the system.
That's why dynamic scanning matters. You need tooling that tries to read across boundaries, invoke exposed functions, and inspect released client artefacts. In practice, this behaves more like an automated red team than a linter.
If your app also sits behind bot protection, understand what those controls can and can't do. Services such as Cloudflare's anti-bot measures may reduce abusive traffic, but they won't fix a broken authorisation rule or an over-privileged RPC. Perimeter friction is useful. Application logic validation is still mandatory.
A workable CI/CD pattern
The teams that do this well usually adopt a flow like this:
-
Pre-merge checks
Scan code and config for obvious secret handling and policy issues. -
Build-stage artefact inspection
Review the actual frontend or mobile artefact, because that's what attackers get. -
Staging runtime tests
Probe auth paths, RLS outcomes, and exposed callable functions with multiple identity contexts. -
Release gates
Block deployment when critical access control failures appear. -
Continuous re-scanning
Re-test after schema updates, mobile releases, and auth changes. Not just after major launches.
For teams wiring this into delivery workflows, a focused approach to CI/CD security testing is usually more effective than adding another dashboard no one checks.
Your Cloud Application Security Checklist
You don't need a giant programme to improve cloud application security. You need a disciplined checklist that catches the mistakes modern teams make.
Use this as a self-audit before release, after auth changes, and whenever you add a new table, function, or mobile feature.

Access control checks
- User roles are explicit: Can you describe what each role may do without hand-waving?
- Tenant boundaries are enforced: Can one logged-in user ever supply another tenant's identifier and get data back?
- Service identities are constrained: Do cron jobs, support tools, and edge functions have only the minimum permissions they need?
- Admin capability is isolated: Are internal actions separated from normal user paths?
Data layer checks
- RLS exists where it should: Are all sensitive tables protected with policies that match real business access?
- Read and write rules are separate: Did you avoid one broad rule that permits too much?
- Policies rely on trusted relationships: Are membership and role checks derived server-side rather than from client-controlled fields?
- Negative tests exist: Have you tested that forbidden reads and writes fail?
Small teams get the most value from testing the "should never happen" path. Happy-path testing won't uncover tenant leakage.
API and function checks
- Every RPC is reviewed like a public endpoint: Who can call it, what rights does it run with, and what side effects can it trigger?
- Input is scoped: Can callers pass arbitrary IDs, or does the function validate ownership and membership?
- Secrets stay off the client: Are privileged keys absent from web bundles and mobile app artefacts?
- Generated APIs are still reviewed: Convenience tooling doesn't remove the need for authorisation design.
Delivery and response checks
- Security runs in CI/CD: Are secrets, policies, and client artefacts scanned before release?
- Runtime tests are automated: Do you regularly probe staging or production-safe environments for broken access rules?
- Logging supports investigations: If something goes wrong, can you see who accessed what and from which path?
- Response steps are documented: Does the team know how to rotate keys, revoke access, and patch a policy quickly?
Cloud application security isn't a one-time hardening exercise. It's a release discipline. Teams that treat it that way ship faster with fewer nasty surprises.
If you're building on Supabase, Firebase, or shipping mobile apps with backend integrations, AuditYour.App helps you find commonly overlooked issues: exposed RLS rules, public or unprotected RPCs, leaked API keys, and hardcoded secrets in frontend bundles, websites, IPA files, and APKs. You can run a one-off scan for a fast snapshot, use continuous monitoring for ongoing coverage, or get a deeper architecture review when your app's logic is getting more complex.
Scan your app for this vulnerability
AuditYourApp automatically detects security misconfigurations in Supabase and Firebase projects. Get actionable remediation in minutes.
Run Free Scan