The SaaS security checklists on Google’s first page are written for the SaaS a company buys. This one is for the SaaS you built: seven groups of controls, each row paired with the check that proves it and the evidence to keep. Access comes first, because 11 of the 21 third-party apps I audited had unauthenticated endpoints doing privileged work.

The SaaS security checklist, by area

A SaaS security checklist for the product you built covers seven groups: identity and access, secrets and configuration, the request surface, dependencies, data, deployment and monitoring, and privacy. Each row pairs a control with the check that proves it and the evidence a customer’s reviewer can open. A row with no evidence is a claim, not a result.

Those 11 come from the 21 third-party apps I audited in June and July 2026. I chose them, so they are a selected set of audited apps: not a random sample, and not a rate for AI-built apps in general. The list itself is the SaaS-shaped part of web app security: accounts, tenants, paying customers, and a reviewer who wants proof.

Each group below is a security controls checklist for one part of a SaaS, and each row is written as something you do, then what you keep once it passes. Taken together, the rows are the SaaS security requirements a customer’s reviewer will ask you to prove. There’s no xls file of this SaaS security checklist to download: the blocks copy as plain text into any spreadsheet or tracker, and that copy becomes your template. Read top to bottom against your own app, the list works as a SaaS security assessment checklist; the third group, on its own, is the narrower SaaS application security checklist for the part of the app a stranger can reach. If your app was vibe coded and you want a shorter first pass, the vibe coding security checklist is built for that, and I don’t repeat it here.

Identity and access: every route, every role, every tenant table

This group decides who can reach what, including whether one customer can reach another’s data. The six rows test it from the outside, with real accounts.

  • Call protected actions directly as an unauthorized user and as an underprivileged one, and confirm rejection. Evidence: the refused responses, with the request and the date.
  • Run read and write tests as anonymous users, different roles, and separate tenants. Evidence: the test record for each table, and on Supabase, row level security switched on for every table in an exposed schema.
  • Test administrative operations using both an authorized account and an ordinary one. Evidence: both responses, side by side.
  • Simulate repeated sign-in attempts and verify the limits, the responses, and normal-user recovery. Evidence: the attempt log and the recovery that worked.
  • Attempt sign-in to each owner and admin account without the second factor and confirm it is refused, on the app and on every provider dashboard behind it. Evidence: one refused attempt per account.
  • Delete a seeded account and inspect its related records, files, and recorded retention exceptions. Evidence: what was left, and why each leftover is allowed.

A refused read under row level security can look like success. PostgreSQL’s manual says rows for which the policy expression does not return true “will not be processed”, so a correct Supabase build answers another tenant’s read with an empty result, not an error. Keep that empty response; it’s the evidence for the first row. The table-by-table rule comes from Supabase’s row level security guide: “A table in an exposed schema without RLS is readable and writable by any role with a grant on it.” Run these tests with the publishable key and a signed-in user’s session, never the secret key, because Supabase’s secret key “authorizes access through the service_role Postgres role, which has the bypassrls attribute”, so a test run with it skips the row level security it is meant to check.

The full identity list lives in the authentication checklist, and the sign-up and reset flows are covered in authentication best practices.

Secrets and configuration

  • Scan source and built assets, and inspect browser traffic, for private credentials. Evidence: the scan output and a saved network trace.
  • Scan the repository history, retain the scan results, and confirm exposed credentials have been invalidated and their replacements work.
  • Check runtime configuration, built assets, and each code path using administrative credentials. Evidence: the list of those code paths, each marked server-only.
  • Inspect environment mappings and confirm staging actions stay within staging services. Evidence: the mapping, and a staging action traced to a staging service.
  • Rehearse rotation with a test credential and record the affected services and checks.
  • Produce an inventory listing each provider, the owning account, the owner role holder, and the date the previous builder’s access was removed.

On Vercel, the environment mapping sits on each variable: you select one or more environments to apply it to, from Production, Preview, Development and any custom environment, as Vercel’s environment variables docs lay out. A production database key that is also applied to Preview fails the fourth row. The last row is the build-side version of a SaaS inventory: the accounts your product runs on, and who owns each one. The deeper list is under secrets management best practices.

SaaS application security: the request surface

SaaS application security is the part of the checklist a stranger can test from outside the code: what the app accepts, which websites may call it, what the browser is told to enforce, and how often one caller may hit it. Each row below is proven by sending the request and keeping the response.

Security for SaaS applications starts at the request, so the evidence for every row here is the same shape: the request sent, the response kept, and the date.

  • Submit invalid and hostile payloads and confirm safe rejection or handling.
  • Test disallowed formats, oversized files, unauthorized downloads, and storage listings.
  • Test approved and unapproved origins, credential handling, and state-changing request protections.
  • Inspect response headers and exercise the application to confirm intended protections without broken flows.
  • Simulate bursts and verify enforcement without blocking ordinary use.
  • Confirm valid users can submit and rejected or missing bot challenges are handled safely.
  • For each AI feature, run injection test cases against it, a spend simulation that hits the limit, and a provider-outage simulation in staging.

The payload row goes deeper in input validation for a web app, the burst row in rate limiting in an API, and the AI row starts with what prompt injection is. SaaS app security goes wider than one group, though: the full application security checklist has a test per control, and this group is its SaaS-shaped cut.

Dependencies and the framework version

  • Record the dependency scan, the remediation, and the regression checks after changes.
  • Check the framework version you deploy against the framework’s published security advisories, and keep the advisory page with the date you read it.
  • Verify a proposed dependency update triggers the appropriate CI checks and review requirements.

The framework row is one the risks table below counts from my audits. For the scan itself, start with the npm audit command. On GitHub, a review requirement that actually blocks the merge is a branch protection setting (“Require pull request reviews before merging”) or a ruleset, and it carries the same plan condition as the first row of the deployment group.

Data: isolation, backups that restore, deletion that works

  • Test rejected invalid records and expected relationship behavior using representative data.
  • Restore a backup into an isolated environment and check representative data integrity.
  • Account deletion is checked once, as the last row of the identity group.
  • Read your database provider’s own documentation on encryption at rest, and keep the page and the date you read it.

The restore row depends on your plan. Supabase says it backs up “all Pro, Team, and Enterprise Plan projects on a daily basis”, recommends that “free tier plan projects regularly export their data using the Supabase CLI db dump command”, and says restoring to a new project “is only accessible to paid plan users with physical backups enabled”. So on the Free plan, the backup you restore is your own dump, into a local or separate database. A database backup checklist for startups covers the rest of the backup side, and the schema side sits in the data consistency checklist for SaaS.

Deployment, monitoring and incident response

  • Attempt a failing merge and confirm the branch protection prevents it.
  • Submit failing and passing changes and retain the CI results.
  • Roll back a test release and verify application behavior and retained data.
  • Trigger a controlled check failure and verify notification and recovery reporting.
  • Send test alerts and verify their destination, context, and response instructions.

The first row has a plan condition. In GitHub’s words: “Protected branches are available in public repositories with GitHub Free and GitHub Free for organizations. Protected branches are also available in public and private repositories with GitHub Pro, GitHub Team, GitHub Enterprise Cloud, and GitHub Enterprise Server.” Rulesets carry the same split. A private repository on GitHub Free can’t pass that row until the plan changes or the repository goes public, and a filled table records that as the row’s result: a fail, with the plan named. Evidence for each row in this group is the run itself: the blocked pull request, the CI log, the rollback record, the alert as it arrived. A SaaS cloud security checklist for the hosting account itself, meaning what the provider covers and what stays yours, is a separate job, linked from the section on filling the list in. The pipeline side is in DevOps for startups and the alerting side in logging and monitoring.

Privacy, disclosure and the paper trail

  • Check the published security.txt file, its contact details, and the delivery of a test message.
  • Trace a sample user through storage, logs, and providers and compare the trace with the personal-data inventory.
  • Compare the privacy policy’s statements with the data inventory and provider flows, and record the owner-approved alignment.
  • Confirm the subprocessor list matches the provider inventory and the privacy policy.

RFC 9116 puts the file under the /.well-known/ path, served over https, and says two fields must always be present: Contact and Expires. The subprocessor row checks against two things built earlier, the provider inventory from the secrets group and the privacy policy, so do it last. The wider privacy work is a separate question: how to manage SaaS data compliance.

What are the security risks associated with SaaS? The build-side answer from my audits

SaaS security risks on the build side start with access. Of the 21 third-party apps I audited, 7 had confirmed cross-user or cross-tenant authorization failures, 9 had row-level security gaps, and 13 had no rate limiting on their most expensive endpoint.

The months were June and July 2026, and all 21 apps were third-party projects I picked rather than drew at random, so none of these counts measures how often an AI-built SaaS fails. The table keeps one row per risk the checklist catches, with the group above that catches it.

RiskWhat my audits foundGroup that catches it
Unauthenticated endpoints doing privileged work11 of 21 (the opener’s number)Identity and access
Confirmed cross-user or cross-tenant authorization failures, where a logged-in user could read or write another customer’s data7 of 21Identity and access
Row-level security gaps9 of 21Identity and access
No rate limiting on the most expensive endpoint13 of 21Request surface
A framework version with a publicly known, reachable RCE or auth bypass; the fix was usually a one-line version bump9 of the 26 audited apps (8 of the 21 third-party apps plus 1 of my own)Dependencies
A real secret permanently in git history: a webhook signing secret, a live AI-provider key, and a Stripe test key with its webhook secret3 of 21Secrets and configuration
No deploy gateAt least 17 of 21, and all 5 of my own appsDeployment

Every recurring pattern from those audits, with the method and its limits, is in the recurring failure patterns from 26 real audits; this table keeps only the rows this checklist catches. Three of the seven rows are about who can reach whose data, and those SaaS security challenges only show up when you test as someone other than yourself. When a customer raises SaaS security concerns, the answer points at these rows and the evidence behind each. Each row is a SaaS security issue I’d close before moving to the one below it. SaaS security best practices, read from this table, are its fixes in the same order, and the last question on this page lists those SaaS application security best practices one by one.

How to fill it in: assessment, audit and testing are the same list read three ways

An assessment is you reading the checklist against your own app. An audit is someone who did not build it doing the same read, with evidence. Testing is tools and a person trying to break the rows that passed. The list stays the same; the reader and the evidence change.

Filling it in is simple and a little tedious. Every row gets pass, fail or not applicable, and a not-applicable row carries its reason: an app with no file uploads marks the upload row not applicable and says so. A pass carries its evidence. A fail carries the test record that found it.

Run it yourself and it’s a SaaS security assessment, and the fail rows become your to-do list. A SaaS security audit brings in someone outside the build; that version is a web application security audit. For SaaS application security testing bought from an outside firm, start with web application security testing services, or affordable penetration testing on a smaller budget. A SaaS security test of a single row is nothing more than that row’s check, run once, with the response kept.

A SaaS security risk assessment, as I read the term, adds two columns, likelihood and impact, and orders the fails by them. The general vocabulary (assessment, audit, review, posture) and a startup’s baseline belong to a separate question: what a security review checks.

Two halves of the job sit on other pages. The cloud half, what the hosting provider covers and what stays yours, is a cloud SaaS security assessment, covered in cloud application security assessment. The API half is an API security assessment of every route. The questionnaire a customer sends is the buyer’s version of this same list: the standard forms are a topic of their own (security questionnaire), and a software security assessment questionnaire from a big customer walks through answering one row by row from the receiving side.

“SaaS security”, the way the pages ranking for this checklist use the phrase, is the other job: keeping the SaaS a company buys under control. Their titles and descriptions talk about posture management (SSPM), cloud access security brokers (CASB), usage inventories, steps for managed service providers and questions to put to a vendor. All of that is real work, and none of it touches the code of the product you built.

A filled example: a two-person SaaS on Supabase and Vercel

This is a worked example, not a real app, and its results are illustrative. The assumptions: two founders, Next.js on Vercel, Supabase Postgres with row level security, Stripe for payments, Resend for email, one AI feature, no file uploads, and the code in a private GitHub repository on a paid plan.

GroupRowResultEvidence a reviewer would openDate
Identity and accessProtected actions called directly while signed out and as an ordinary userPassThe refused responses, with each requestThe day you ran it
Identity and accessRead and write tests per table, as anonymous, as another role, as another tenantFailTest record: a table added after the others answered another tenant’s read, with row level security off on itThe day you ran it
Identity and accessOwner and admin sign-in without the second factorPassOne refused attempt per account, app and dashboardsThe day you ran it
Secrets and configurationEnvironment mapping: staging stays on staging servicesPassThe Vercel variable list per environment, and a staging action traced to the staging Supabase projectThe day you ran it
Secrets and configurationProvider inventoryPassSupabase, Vercel, Stripe, Resend, the AI provider and the domain, each with its owning accountThe day you ran it
Request surfaceFile uploadsNot applicableThe app accepts no file uploadsThe day you ran it
Request surfaceAI feature: injection cases, spend limit, provider outagePassThe test cases and both staging simulationsThe day you ran it
DependenciesFramework version against published advisoriesPassThe deployed version and the advisory page readThe day you ran it
DataBackup restored into an isolated environmentPassThe restore log and the integrity checkThe day you ran it
Deployment and monitoringFailing merge blocked, test alert deliveredPassThe blocked pull request and the received alertThe day you ran it
Privacy and disclosuresecurity.txt, subprocessor listPassThe published file, the test message received, the list compared with the inventoryThe day you ran it

The fail row is the one worth studying. The table added last was created after row level security had been set up everywhere else, which is the case Supabase’s rule in the identity group warns about. It stays in the table as a fail, with its test record, until the fix has a record of its own. One app I audited had exactly this row fail: a table added after the rest of the schema, with row level security never switched on, told in full under enable RLS on every reachable table, including the one you added last week.

The upload row carries its reason in the row instead of a blank. Before the table goes to a reviewer, sort it: fails first, then not-applicable rows with their reasons, then passes with evidence. A filled checklist earns a reviewer’s trust because its failures are visible, each one with the test record that found it. Fix in the risks table’s order, access first.

How to verify the result

To evaluate the security health of a SaaS from the side being evaluated, fill the checklist and attach one artifact per row that a stranger can open: a refused request, a response header, a configuration export, a scan report. A failure stays on the list, marked, until its fix has its own artifact.

That’s the rule from the top of the checklist, applied to the whole table instead of one row. SaaS vendor security, seen from the vendor’s chair, is whatever your customer’s reviewer checks, and the filled table with its artifacts is what you send back.

To keep your SaaS secure after the first pass, my working rule is to re-run the groups a release touched whenever it changes sign-in, keys, the schema or a provider, and to run the whole list about once a quarter and before each customer review. Use that as the answer to how often you should review security settings; it’s my rule, not a standard.

The OWASP Top 10 is the same read at category level, and the current edition is the OWASP Top 10 2025. Read against it, a finished review delivers category-level results and supporting test evidence, with justified non-applicable cases identified. If the reviewer asks for a SOC 2 report instead, the first question is what SOC 2 certification is, and SOC 2 compliance consultants covers the ways to get ready for one.

On a Production Hardening Sprint, the record a reviewer opens is deliverable 13.1, the production readiness report, and it is verified this way: account for all 123 IDs; keep failures visible until resolved and explain genuine non-applicable items.

Where the sprint does this

Area 03 of the sprint scope, Input, output and application security, contains 12 of the 123 deliverables, and the request-surface group above follows seven of their verify lines. The other groups draw on area 01, Authentication and authorization, with 11 deliverables; area 02, Secrets, keys and configuration, with 9; area 04, Database and data, with 14; area 07, Environments, CI/CD and deployment, with 13; area 08, Logging, monitoring and alerting, with 8; and area 12, Privacy and compliance foundations, with 8. Formal third-party certifications and independent audit opinions are separate from the sprint deliverables. Each deliverable’s verify line is on the published scope.

Common questions about securing the SaaS you built

What is SaaS testing?

SaaS testing means testing a software-as-a-service product. On the security side, it’s a checklist of controls for the product you run, with tools and a person trying each row against the live app and keeping the request and response as evidence for every result.

What are the security controls required for SaaS applications?

Which controls are required depends on who is asking: a customer’s reviewer, a standard the customer names, or a law that covers the data you hold. That’s my reading, not legal advice. For a customer’s reviewer, seven groups cover it: identity and access (who can call what, and whose rows they see), secrets and configuration (keys out of the browser and the repository), the request surface (validation, origins, headers, rate limits), dependencies (a patched framework), data (isolation, restores, deletion), deployment and monitoring (a merge gate, a rollback, alerts that reach someone), and privacy (security.txt, a data inventory, a subprocessor list).

Which security measure is crucial for protecting data in SaaS applications?

Authorization at the data layer: every table checked from another tenant’s account, so one customer can never read or change another customer’s rows. Second comes a backup you have actually restored, because a backup nobody has restored is still an assumption.

What are the best practices for securing SaaS applications?

Close the gaps in the order they expose data. Put a server-side authorization check on every privileged route, test tenant isolation table by table, turn on row level security for every exposed table, rate-limit the expensive endpoints, keep the framework on a patched version, rotate any secret that ever reached the repository, and gate every deploy on passing checks. For each one, keep the artifact that proves it: a refused request, a test record, a scan report, a blocked merge.