Getting your first paying customer is exciting. It’s also the moment your cloud account stops being a sandbox and becomes a production system that real people depend on — and that attackers will probe.

Most startup cloud breaches aren’t sophisticated. They’re embarrassingly simple: an IAM key in a public GitHub repo, an S3 bucket with no access controls, a root account with no MFA. The good news is that the 10 controls below cost almost nothing to implement and eliminate the vast majority of risk before your first customer ever touches your product.

This is not an exhaustive hardening guide. It’s the minimum viable security baseline — the things that, if absent, will cause a serious incident within 12 months of going live.

The 10 cloud security basics checklist

# Control Effort Risk if skipped
1 IAM least-privilege Medium Lateral movement if any credential leaks
2 MFA on root account Low Total account takeover
3 CloudTrail / audit logging on Low No evidence trail after a breach
4 S3 block-public-access Low Accidental data exposure
5 VPC private subnets for databases Medium Direct database exposure to the internet
6 WAF on public endpoints Medium Application-layer attacks (SQLi, OWASP Top 10)
7 Secrets manager over env vars Medium Secrets in logs, source control, crash dumps
8 Patch schedule for managed services Low Known-CVE exploits on unpatched runtimes
9 Alert on root account activity Low Undetected privilege escalation
10 Pen-test schedule Medium Unknown vulnerabilities accumulating silently

1. IAM least-privilege

Every service, function, and CI/CD pipeline should have its own IAM role with only the permissions it actually uses. “Admin access for everything” is a short-term convenience that becomes a liability the moment any one credential leaks.

What to do: Audit existing IAM policies. Remove * wildcards. Create per-service roles. Use aws iam generate-service-last-accessed-details to find permissions that haven’t been used in 90 days and remove them.

On GCP: Use IAM conditions and Workload Identity Federation instead of service account key files. Delete any existing SA keys and switch to short-lived tokens.

2. MFA on the root (or owner) account

The cloud root account (AWS root / GCP owner project) bypasses all IAM policies. It’s the skeleton key. One compromised password without MFA = full account takeover, every resource deleted or ransomed.

What to do: Enable hardware MFA (YubiKey or Google Titan) or at minimum a TOTP app on the root account. Then lock the root account credentials away — it should only be used for the handful of tasks that genuinely require it (billing contact changes, account recovery). Enable an alert (see #9) for any root login.

3. CloudTrail / Cloud Audit Logging enabled in every region

Without an audit log, you cannot answer “what happened?” after an incident. You’re flying blind.

What to do (AWS): Enable CloudTrail in all regions and set log delivery to an S3 bucket with versioning + MFA delete. Enable CloudTrail Insights to catch unusual API activity.

What to do (GCP): Verify Admin Activity and Data Access audit logs are on for all services. Export logs to Cloud Storage with a 365-day retention policy.

Cost is negligible — typically a few dollars per month for a startup-scale account.

4. S3 block-public-access (account level)

AWS S3 buckets default to private, but a single misclick in the console or a misconfigured CDN origin can make a bucket public — and there are automated scanners that find these within minutes.

What to do: Enable “Block all public access” at the account level in S3, not just per-bucket. This prevents any bucket in the account from accidentally becoming public, regardless of individual bucket policies. On GCP, set uniform bucket-level access and use IAM exclusively — no ACLs.

5. VPC private subnets for databases

Your application database should never be directly reachable from the internet. A database exposed on a public subnet with a weak password is frequently compromised within hours via automated credential-stuffing attacks.

What to do: Place all managed databases (RDS, Cloud SQL) in private subnets with no internet gateway route. Access from application servers goes through private networking only. Bastion access for maintenance should be through AWS Systems Manager Session Manager (no SSH port open) or Cloud IAP on GCP.

6. WAF on public-facing endpoints

An application WAF blocks common attack patterns — SQL injection, XSS, path traversal — before they reach your application code. It’s not a substitute for secure code, but it provides a layer of defense for vulnerabilities you haven’t found yet.

What to do: Attach AWS WAF to your Application Load Balancer or CloudFront distribution. Enable the AWS Managed Rules (Core rule set + Known bad inputs). On GCP, Cloud Armor provides equivalent coverage for Cloud Run and GKE ingress.

Cost: roughly $5–$30/month for startup traffic volumes — cheap insurance.

7. Secrets manager over environment variables

Hardcoded secrets and secrets stored in .env files have a way of leaking: they end up in git commits, Docker image layers, crash dumps, and log files. Secrets that rotate automatically can’t be hardcoded.

What to do: Store database passwords, API keys, and TLS certificates in AWS Secrets Manager or GCP Secret Manager. Fetch them at runtime via the SDK, not at deploy time via env vars. Enforce a git pre-commit hook (e.g. detect-secrets) that blocks secrets from being committed. Rotate all secrets that predate this control.

8. Patch schedule for managed runtimes

Managed services don’t patch themselves by default. An ECS task running Node 18 on a Docker image from 18 months ago contains dozens of known CVEs that are being actively exploited.

What to do: Pin dependency versions in lock files. Set a calendar reminder to run npm audit / pip audit / go mod tidy + rebuild base images monthly. Enable automatic minor-version upgrades on managed databases and caches (RDS auto minor version upgrade, ElastiCache maintenance windows). Subscribe to the AWS or GCP security bulletins.

9. Alert on root account activity

You locked down root in step 2. Now make sure you’ll know immediately if it’s ever used anyway.

What to do (AWS): Create a CloudWatch metric filter on CloudTrail events for userIdentity.type = Root, connected to an SNS alert that emails (and ideally PagerDuty/Slack) the engineering team. The official AWS Security Hub “root account usage” control automates this. On GCP, set a log-based alert on principalEmail containing the owner account email.

A root login you didn’t initiate is a major incident signal — you want to know in seconds, not during next week’s log review.

10. Pen-test schedule

The previous nine controls eliminate obvious mistakes. A penetration test finds the non-obvious ones: logic flaws in your authorization model, chained vulnerabilities that no single scanner catches, assumptions you made about how your system is used that don’t hold under adversarial conditions.

What to do: Schedule an external pen test before your first enterprise deal or SOC 2 audit — and annually after that. If budget is tight, start with an automated DAST scan (Burp Suite Pro, AWS Inspector for EC2) and a manual review of your highest-risk surface (auth flows, admin panels, payment integrations). Treat the findings as a roadmap, not a report card.


Start with the low-effort ones today

Items 2, 3, 4, and 9 can be completed in under an hour. If your account doesn’t have them right now, that’s the work for this afternoon.

The medium-effort items (IAM restructuring, VPC redesign, WAF setup) belong on your next sprint. Don’t let “we’ll do it properly later” stretch past your first customer going live.

If you’re not sure where your account stands on this checklist, DMSE runs cloud security reviews as part of our cloud services. We’ll tell you exactly what’s missing and how to fix it — without selling you a six-month engagement to do it. Start the conversation.

Already on AWS and deciding whether to stay or move to GCP? We covered that decision in depth in AWS vs GCP for startups.

Leave a Reply

Your email address will not be published. Required fields are marked *