Most cloud breaches are not the result of a sophisticated exploit. They are the result of a misconfiguration someone meant to fix, an access key that never got rotated, or a storage bucket that was public for testing and stayed that way. Misconfiguration is consistently the leading cause of cloud security incidents, which means most of what you need to get right is achievable without a research team or a big budget. You just need to work through the list.
This is a practical checklist for AWS, GCP, and Azure environments. It is written for the person who owns cloud infrastructure and needs to know what "secure" actually requires, not a vendor's marketing definition of it.
Identity and access management
- Multi-factor authentication on every account with console or API access. Passwords alone are not a control anymore. This applies to root or organization admin accounts especially, since a compromised root credential gives an attacker full control of the environment.
- No standing root or global admin credentials in daily use. Root (AWS), Owner (GCP), or Global Administrator (Azure) accounts should be locked down, used rarely, and logged when they are. Day-to-day work should run through scoped roles.
- Least-privilege IAM policies, not wildcard permissions. A policy that grants
*:*on a resource because it was faster to write during a deploy is a liability that outlives the deploy. Review IAM policies for overly broad grants on a schedule, not just when something breaks. - Access keys and service account credentials on a rotation schedule. Long-lived keys that never expire are a common finding in posture reviews. Where possible, use short-lived credentials or workload identity instead of static keys at all.
- Federated or single sign-on for human users. Centralizing authentication through an identity provider makes offboarding actually work. A departed employee's local cloud console password is easy to forget about.
Network configuration
- No storage buckets or databases open to the public by default. S3 buckets, Azure Blob containers, and GCS buckets set to public read are the single most common misconfiguration found in cloud environments, and one of the easiest for an attacker to find with automated scanning.
- Security groups and firewall rules scoped to specific sources, not 0.0.0.0/0. An open SSH or RDP port to the entire internet is an invitation, not a convenience. Restrict management ports to known IP ranges or a VPN.
- Private subnets for anything that does not need to face the internet. Databases, internal APIs, and backend services should sit behind a load balancer or bastion, not directly exposed.
- VPC flow logs or equivalent network logging enabled. You cannot investigate what you did not log. Flow logs are inexpensive to turn on and often the difference between confirming a breach and speculating about one.
Data protection
- Encryption at rest enabled on storage, databases, and disks. All three major providers make this close to a one-line configuration change. There is rarely a good reason to skip it.
- Encryption in transit enforced, not just available. TLS should be required, not optional, on every endpoint that handles customer or business data.
- Key management through a managed KMS, with defined ownership. Know who can access encryption keys and audit that access. Customer-managed keys give you more control than provider-managed defaults, but only if someone is actually managing them.
- Backups that are tested, not just scheduled. A backup you have never restored from is a hypothesis, not a control. Ransomware and accidental deletion are both real risks, and untested backups fail you at the worst possible moment.
Logging and monitoring
- CloudTrail, Cloud Audit Logs, or Azure Activity Log enabled and centralized. These are the record of who did what, and they need to be turned on before an incident, not after.
- Log retention long enough to support an investigation. Thirty days is rarely enough. Most compliance frameworks and reasonable investigations expect closer to a year.
- Alerting on high-risk events. Root login, IAM policy changes, security group modifications, and disabled logging should all trigger an alert, not just a log entry nobody reads.
- A defined process for reviewing alerts. Monitoring that nobody looks at is not monitoring. Assign ownership, even if it is one person checking a dashboard weekly.
Configuration management
- Infrastructure as code where practical. Manual console changes are how drift and one-off misconfigurations accumulate. Terraform, CloudFormation, or equivalent tooling gives you a reviewable, repeatable record of what your environment actually looks like.
- Automated posture scanning against a benchmark. AWS Security Hub, GCP Security Command Center, Azure Security Center, or a third-party CSPM tool checked against CIS benchmarks will catch drift between deliberate reviews.
- A documented patching and update cadence for anything you manage. Managed services shift some of this burden to the provider, but self-managed compute, containers, and dependencies are still your responsibility.
- Regular manual review, not just automated scanning. Automated tools catch known patterns. They miss context, like a permission that is technically scoped correctly but no longer matches how the team actually works.
Where this checklist tends to break down
Every item on this list is well documented by the cloud providers themselves. The gap is rarely knowledge, it is time and prioritization. Environments accumulate exceptions over months of shipping under deadline pressure, and by the time someone goes looking, the drift between the intended configuration and the actual one can be significant.
This is what a cloud security assessment is built to catch. A structured posture review across AWS, GCP, or Azure walks through exactly this kind of checklist against your live environment, flags the gaps in order of actual risk, and gives you a prioritized remediation plan instead of a generic scan report. For teams that are also working toward a framework like SOC 2, the same misconfigurations that create breach risk are usually the ones an auditor will flag, so closing them early pays off twice. If that is where you are headed, our compliance readiness work picks up from there.
If you want a second set of eyes on your cloud environment, or you are not sure which of these items apply to your setup, get in touch and we will walk through it together.
The account structure decision that makes every other item easier
The checklist above is written per-environment, but the single highest-leverage decision sits above it: how many accounts, subscriptions, or projects you run and where the boundaries fall. A single AWS account holding production, staging, the marketing site, and a data science sandbox forces every control to be expressed as an IAM condition, because there is no blast radius boundary to lean on. Split into separate accounts under an organization, the same environment gets a hard boundary for free: production data cannot leak into the sandbox through a mistyped bucket policy if the sandbox has no trust relationship.
The practical version for a company under about eighty people is four accounts: a management or organization root that holds nothing but billing and organizational policy, a shared services account for logging and CI/CD identity, production, and non-production. Log destinations live in shared services, and no engineer holds write access to them. That one arrangement satisfies a surprising number of separate audit expectations at once: log integrity, separation of duties, and the ability to say that a developer with full staging access still cannot reach customer data.
Retrofitting this later usually costs more than the original build. Moving a production RDS instance or a Cloud SQL database across account boundaries means a migration window, a DNS change, and IAM references scattered through application config. If you are early enough that production has three services in it, split now. If you are past that, do not tear the environment apart for tidiness. Use service control policies or Azure Management Group policy to enforce the guardrails you would otherwise have got from separation, and accept that you are paying for the earlier shortcut in policy complexity instead of migration effort.
The parts of the environment the checklist above does not reach
Container and orchestration layers. A hardened VPC does very little for you if your Kubernetes cluster runs pods with hostNetwork enabled, no network policies between namespaces, and a default service account token mounted into every workload. The cluster is a second network inside your network, with its own identity system and its own set of default-permissive behaviors. Check that the API server endpoint is private or IP-restricted, that RBAC does not grant cluster-admin to a group larger than two or three people, that network policies exist between namespaces rather than relying on the default allow-all, and that workload identity is used instead of long-lived cloud credentials in secrets.
CI/CD identity. This is where the access key rotation item quietly fails in practice. Teams rotate the keys they know about and forget the ones sitting in GitHub Actions secrets, CircleCI environment variables, or a Terraform Cloud workspace. Static deploy credentials with production write access are among the more valuable things an attacker can obtain, because they come with a legitimate-looking path into your environment. All three cloud providers now support OIDC federation from the major CI systems, which removes the static key entirely and lets you scope the trust to a specific repository and branch. Doing this for the deploy role is usually a half-day of work and eliminates an entire category of finding.
Third-party SaaS roles. Every observability tool, cost optimizer, and security scanner you have onboarded probably holds a cross-account role in your environment. Some of them asked for ReadOnlyAccess, which includes the ability to read Secrets Manager and Parameter Store values in older policy versions and still includes far more data than a cost tool needs. Inventory these roles specifically, confirm each has an external ID condition so it cannot be assumed by another customer of the same vendor, and re-scope anything holding a managed policy broader than its actual function.
Backup and DR account isolation. The backup item on the checklist covers testing restores. The part that gets missed is where the backups live. Backups stored in the same account as the primary data, reachable by the same credentials, do not protect you from the credential compromise scenario they are supposed to cover. Cross-account backup copies with object lock or immutability enabled are the version that survives an attacker who has already got admin.
What an auditor asks for, versus what the checklist says
Reading the list, the natural instinct is to fix the configuration and move on. An auditor is not going to ask whether encryption at rest is enabled. They are going to ask you to demonstrate it, and the demonstration is where the work actually sits.
Expect requests along these lines. A population listing of every storage bucket and database in scope, with the encryption status of each, exported on a date they can see. Evidence that the quarterly access review happened, which means a ticket or a signed document showing who reviewed what and what changed as a result, not just the current state of your IAM. A sample of alerts from your high-risk event monitoring, with evidence that a human triaged them, because the control being tested is the review process rather than the alert configuration. Change records for a sample of infrastructure changes, showing the pull request, the approver, and that the approver was not the author.
The pattern is consistent. Controls that are purely configuration are cheap to prove with a screenshot. Controls that involve a human doing something on a cadence are the ones that fail, because nobody was capturing the artifact while it happened. If you are heading toward SOC 2 or ISO 27001, decide up front where the artifact for each recurring control gets stored, and make storing it part of the task rather than something you reconstruct in month nine. Our free Workspace exists partly to hold exactly this material, and a shared drive with a consistent folder convention works fine too. What does not work is deciding after the fact.
Exceptions, and how to write one that survives review
You will not close every item. Some legacy service needs a wider security group than you would like. A vendor integration requires an inbound rule you cannot narrow. The mistake is leaving these as silent gaps that an assessor discovers and treats as an unmanaged risk. A documented exception with a named owner, a business justification, a compensating control, and a review date is a managed risk, and assessors handle those completely differently.
A usable exception record is four or five lines. What the deviation is, which control it deviates from, why the straightforward fix is not available, what you have done instead to reduce the risk, who owns it, and when it gets revisited. Keep them in one register rather than scattered across ticket comments. The register itself becomes evidence that you have a risk management process, which is a separate control you were going to have to demonstrate anyway.
What this costs, and what actually drives the number
The configuration changes on the checklist are mostly free in licensing terms. The costs show up in three places that teams underestimate. Logging is the first: full CloudTrail data events on a busy S3 workload, VPC flow logs at full sampling, and a year of retention in a searchable tier can move a monthly bill by a meaningful amount. The fix is tiering, not skipping. Keep the management events hot and searchable, push data events and flow logs to cheap object storage with a lifecycle policy, and accept a slower query path for the older material.
The second is engineering time on remediation. Enabling encryption on a new resource is trivial. Enabling it on an existing unencrypted RDS instance means a snapshot, a restore, and a cutover. Narrowing an over-permissioned IAM role means finding out what the role actually uses, which means reading access analyzer output or CloudTrail history rather than guessing, and then handling the service that breaks two weeks later because it used a permission once a quarter.
The third is the assessment itself if you bring someone in. Our fixed-scope work starts from a defined environment rather than an hourly meter, and the honest driver of scope is the number of accounts and the number of distinct workload patterns, not the number of resources. Twelve near-identical microservices in one account is a small review, while three accounts running a Kubernetes cluster, a serverless stack, and a legacy VM estate is a large one even at a lower resource count.
When you should not buy a cloud assessment from us
If you have never run a posture scanner against your environment, do that first and do it yourself. AWS Security Hub with the CIS and Foundational Security Best Practices standards enabled, GCP Security Command Center at the standard tier, or Microsoft Defender for Cloud will each cost you an afternoon and produce a findings list that overlaps substantially with the first pass of any external review. Paying a consultancy to tell you that a bucket is public when a free tool would have told you the same thing is a poor use of money. Close the obvious tier, then bring someone in for the part that tooling cannot do, which is judgement about whether a permission that is technically correct still matches how your team works.
If you are pre-product with two engineers and one AWS account, you also do not need us. You need MFA everywhere, no public buckets, CloudTrail on, and a password manager. That is a week of your own time and it covers the realistic threat model for a company with no customer data worth stealing yet.
And if your driver is a single customer questionnaire that asks whether you have a cloud security policy, the honest answer may be that you need a policy and an internal review, not an external assessment. We would rather tell you that on a call than sell you a report you did not need. The point at which outside help genuinely pays is when the environment has grown past what one person holds in their head, when a real auditor is coming, or when something has already gone wrong. If you are at that point, talk to us and we will scope it honestly, including the parts you should keep in house.
If you find something already exposed
Working through this list occasionally surfaces something that has been open for months. A bucket with customer exports in it. An RDS instance reachable from the internet. Resist the urge to quietly close it and move on, because the close destroys the evidence you may need.
Before you change anything, capture the current configuration and pull the access logs for the exposed resource for as far back as retention allows. Then close it. Then work out from the logs whether anyone other than your own infrastructure actually touched it, which is usually the difference between a configuration error and a reportable breach. Under PIPEDA, and under Quebec's Law 25 for Quebec residents' data, the notification obligation turns on whether the incident creates a real risk of significant harm, and you cannot assess that without the access record. Teams that delete first and investigate second end up either over-reporting or guessing, and both are worse outcomes than a two-hour delay to collect logs. If that is the situation you are in right now, our incident response and retained work covers this, and the first call is about containment rather than contracts.
Want this handled? Tell us what your buyer is asking for and we will tell you what the work involves, what it costs, and what you can do yourself.
Talk to usOr talk about a retainer