Security is the one thing you can't retrofit into a SaaS product after the fact. You can refactor bad code, redesign a clunky UI, and rewrite a slow API — but a security breach that exposes customer data doesn't have a patch. It has a post-mortem, a PR crisis, and a churn spike.
This checklist is for developers actively building SaaS products who want to get security right from the start — not after their first incident.
1. Authentication & Identity
This is where most SaaS breaches start. Get this layer wrong and everything else is irrelevant.
- ✅ Enforce strong password policies — minimum length, complexity, breach detection (check against HaveIBeenPwned API at registration)
- ✅ Implement MFA by default — TOTP (Google Authenticator, Authy) at minimum. For enterprise tiers, support SSO via SAML 2.0 or OIDC
- ✅ Use short-lived access tokens — JWTs should expire in 15–60 minutes. Pair with refresh token rotation and invalidate on logout
- ✅ Rate limit authentication endpoints — brute force protection on
/login,/forgot-password, and/verify-otp. Exponential backoff + account lockout after N failed attempts - ✅ Implement device fingerprinting — flag logins from new devices or unusual geolocations and trigger step-up authentication
// Rate limiting login endpoint with express-rate-limit
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 10,
skipSuccessfulRequests: true,
message: { error: 'Too many login attempts. Try again in 15 minutes.' }
});
app.post('/auth/login', loginLimiter, authController.login);
2. Authorization & Tenant Isolation
Multi-tenancy is what makes SaaS economics work. It's also what makes authorization failures catastrophic — one misconfigured query and Tenant A reads Tenant B's data.
- ✅ Enforce Row-Level Security (RLS) — if you're on PostgreSQL, use RLS policies so tenant isolation is enforced at the database layer, not just the application layer
- ✅ Validate tenant context on every request — never trust tenant ID from the client. Derive it from the authenticated session server-side
- ✅ Implement RBAC from day one — even if you only have two roles initially. Retrofitting role-based access control into an existing permission model is painful
- ✅ Audit permission checks — log every access denial. Patterns in 403s often reveal probing attempts before they escalate
-- PostgreSQL RLS example
ALTER TABLE documents ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON documents
USING (tenant_id = current_setting('app.current_tenant')::uuid);
3. Data Protection
- ✅ Encrypt data at rest — AES-256 for stored data. Use your cloud provider's managed encryption (AWS KMS, GCP Cloud KMS) rather than rolling your own
- ✅ Encrypt data in transit — TLS 1.2 minimum, TLS 1.3 preferred. Disable older protocols explicitly. Use HSTS headers
- ✅ Separate encryption keys per tenant — for enterprise SaaS, per-tenant key management means a compromised key affects one customer, not all of them
- ✅ Mask sensitive data in logs — PII, payment info, and tokens should never appear in application logs. Implement log scrubbing middleware
- ✅ Handle PII with a data map — know exactly what personal data you collect, where it's stored, how long you retain it, and who can access it
// Log scrubbing middleware example
const sensitiveFields = ['password', 'token', 'ssn', 'cardNumber'];
function scrubLogs(obj) {
return Object.fromEntries(
Object.entries(obj).map(([k, v]) => [
k,
sensitiveFields.includes(k) ? '[REDACTED]' : v
])
);
}
4. API Security
Your API is your attack surface. Treat every endpoint as publicly accessible until proven otherwise.
- ✅ Validate and sanitize all inputs — use a schema validation library (Zod, Joi, Yup) on every incoming request. Never pass raw user input to a database query or shell command
- ✅ Implement API rate limiting per user, not just per IP — IP-based rate limiting is trivially bypassed with proxies. Rate limit by authenticated user ID
- ✅ Use API versioning with deprecation windows — abrupt endpoint removal breaks integrations and pushes clients toward workarounds
- ✅ Return generic error messages externally — stack traces and internal error details in API responses are a gift to attackers
- ✅ Implement request signing for webhooks — sign the payload with HMAC-SHA256. Verify the signature before processing
// Webhook signature verification
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expected}`)
);
}
5. Infrastructure & Cloud Security
- ✅ Apply least privilege to all IAM roles — every service, Lambda function, and EC2 instance should have only the permissions it needs. Audit IAM policies quarterly
- ✅ Never hardcode secrets — use environment variables for local dev and a secrets manager (AWS Secrets Manager, HashiCorp Vault) for production
- ✅ Enable VPC and private subnets — databases and internal services should never be publicly accessible
- ✅ Configure security groups tightly — default deny, explicit allow. Document why each port is open
- ✅ Enable CloudTrail / audit logging — maintain a record of who did what to your infrastructure, not just your application
# Check for publicly accessible S3 buckets
aws s3api list-buckets --query 'Buckets[].Name' --output text | \
xargs -I {} aws s3api get-bucket-acl --bucket {} \
--query 'Grants[?Grantee.URI==`http://acs.amazonaws.com/groups/global/AllUsers`]'
6. Dependency & Supply Chain Security
The SolarWinds and Log4Shell incidents made one thing clear: your security is only as strong as your weakest dependency.
- ✅ Audit dependencies regularly — run
npm auditorpip-auditin CI on every build, not just locally - ✅ Pin dependency versions in production — use lockfiles (
package-lock.json,poetry.lock) and don't auto-update in production - ✅ Use a software composition analysis (SCA) tool — Snyk, Dependabot, or Socket.dev catch vulnerabilities before they reach production
- ✅ Vet third-party integrations — every OAuth integration, analytics SDK, and payment library is an extension of your trust boundary
7. Compliance & Monitoring
Security without visibility is just hope.
- ✅ Define your compliance scope early — SOC 2 Type II, GDPR, HIPAA, PCI-DSS — know which apply and build toward them from the start
- ✅ Implement centralized logging — aggregate application, infrastructure, and security logs in one place (Datadog, CloudWatch, ELK stack)
- ✅ Set up anomaly alerting — unusual API call volumes, new admin accounts, bulk data exports should trigger immediate alerts
- ✅ Run penetration tests before major launches — automated scanners catch known CVEs; human pentesters find logic flaws scanners miss
- ✅ Create an incident response runbook — document what happens when a breach occurs before it occurs
8. Secure Development Practices
Security is a team habit, not a deployment step.
- ✅ Conduct threat modeling before building new features — ask "how could this be abused?" before "how do we build this?"
- ✅ Enforce security-focused code reviews — establish a checklist for reviewers: input validation, auth checks, error handling, logging hygiene
- ✅ Run SAST tools in CI — Semgrep, SonarQube, CodeQL catch common vulnerability patterns before code merges
- ✅ Train developers on OWASP Top 10 — injection, broken auth, misconfiguration, and insecure deserialization are still responsible for the majority of SaaS breaches in 2025
The Honest Reality
Most SaaS security failures aren't caused by sophisticated zero-day exploits. They're caused by:
- Tenant IDs trusted from client requests
- Secrets committed to Git repositories
- Admin endpoints left unauthenticated
- Dependencies not updated for 18 months
- Logs that captured everything including passwords
The checklist above isn't exhaustive — security is an ongoing practice, not a one-time audit. But covering these fundamentals puts you ahead of the majority of SaaS products in production today.
If you're building a SaaS product and want security embedded in your architecture from day one, the SaaS application development process at MicrocosmWorks treats these as defaults, not afterthoughts. And if you're unsure where your current product stands, a digital consulting engagement can help you find the gaps before your users do.
Found a checklist item missing or worth expanding? Drop it in the comments — this is a living document.
Top comments (0)