The Top AWS Security Misconfigurations we Find in Customer Environments

Unencrypted databases, exposed endpoints, IAM misuse: discover the AWS misconfigurations we fix most often during SOC 2 and ISO 27001 audits.

10 min read·

Key Takeaways

  • Unencrypted RDS databases require complex migrations to fix. Enable encryption at creation.
  • Internet-exposed resources (databases, K8s control planes) should use Session Manager or VPN access instead.
  • Environment separation at the AWS account level simplifies compliance and reduces blast radius.
  • Long-lived IAM credentials are supply chain attack targets. Use AWS Identity Center and short-lived tokens.
  • Root account misuse creates significant risk. Centralize management and remove unnecessary root credentials.

At Bastion, we help companies achieve compliance certifications like SOC 2 Type II and ISO 27001 while ensuring they're actually secure, not just checkbox compliant. A significant portion of our customers run their infrastructure on AWS, and over time we've identified patterns in the security issues that repeatedly trip organizations up.

These aren't theoretical vulnerabilities. They're real problems we encounter regularly, and in many cases, they're far more painful to fix after the fact than to get right from the start. Here's what we see most often.

Unencrypted RDS Databases

This one seems straightforward, enable encryption at rest on your databases, but we still find unencrypted RDS instances more often than you'd expect. The challenge is that AWS doesn't let you simply flip a switch to encrypt an existing unencrypted database. You have to create an encrypted snapshot, restore from it, and switch your application over to the new instance.

For some customers, this migration has been relatively painless. For others, it's a multi-week project involving careful coordination, data synchronization, and application testing. We've worked with organizations where zero downtime was a hard requirement, turning what should be a simple security control into a complex migration effort involving read replicas, DNS cutover strategies, and significant engineering time.

The lesson: enable encryption when you create the database. It costs nothing, has negligible performance impact, and saves you from a painful migration later.

Internet-Exposed Resources That Shouldn't Be

We regularly find resources exposed to the public internet that have no business being there. The two most common culprits are RDS databases and Kubernetes control planes.

Publicly accessible databases typically happen because developers need to access the database from their laptops during development. The quick fix is to make the database publicly accessible and maybe add their IP to the security group. The problem is that "maybe" often doesn't happen, we've seen databases wide open to 0.0.0.0/0 with just a username and password standing between the internet and production data.

Even when IP allowlisting is in place, this approach is fragile. IP addresses change, VPNs get disconnected, and the allowlist grows unwieldy over time.

The better approach is to keep your database in a private subnet where it belongs and provide access through secure channels. Options include a bastion host (or jump box) that developers SSH through, or even simpler, an EC2 instance configured with AWS Systems Manager Session Manager. With Session Manager, you can access your private resources without opening any inbound ports at all, no SSH keys to manage, no security group rules to maintain, and full session logging for audit purposes. AWS has documentation on enabling SSH connections through Session Manager that makes this straightforward to set up.

Publicly exposed Kubernetes control planes follow a similar pattern. The API server gets exposed to the internet, sometimes with no restrictions in the security group, making it accessible to anyone who can reach it. While Kubernetes has its own authentication layer, this is still unnecessary attack surface.

The fix is the same: make the control plane VPC-accessible only and reach it through a host inside your network. Whether that's an EC2 instance with Session Manager, a dedicated bastion host, or a VPN connection, the point is to eliminate direct internet exposure.

The challenge with both of these issues is that fixing them retroactively is significantly harder than doing it right initially. When you have dozens of developers with local database connections or kubectl configs pointing to public endpoints, migration requires coordination across your entire engineering team.

Mixing Development and Production Environments

We see this at various levels of severity: development and production in the same AWS account, in the same VPC, or even sharing the same database.

Separation of environments matters for both security and compliance reasons. From a security perspective, development environments are inherently less controlled, developers need more permissions to experiment, test data might be less carefully managed, and the attack surface is larger. If development and production share infrastructure, a compromise or mistake in development can directly impact production.

From a compliance standpoint, most frameworks expect clear environment separation. Auditors want to see that changes flow through proper processes before reaching production, and that development activity can't inadvertently affect production systems. This is a core requirement in both SOC 2 Type 2 audits and ISO 27001 certification.

When you separate at the AWS account level, access control becomes dramatically simpler. You can grant developers broad permissions (even PowerUser access) in the development account without worrying about production impact. Production access becomes explicitly controlled, perhaps granted temporarily through just-in-time access when needed for debugging, with full audit trails.

If you're already using infrastructure as code through Terraform or CDK, creating this separation is easy, your configurations can target different accounts with minimal modification. But if you're trying to separate environments after years of organic growth where everything is intermingled, you're facing a potentially significant migration project.

IAM Users with Long-Lived Access Keys

AWS provides excellent mechanisms for short-lived credentials (STS, assume role, instance profiles), but we still frequently find environments relying primarily on IAM users with static access keys. These keys often haven't been rotated in years, and when we ask about rotation policies, the answer is usually that no policy exists.

This pattern shows up in two common places. First, in application code and CI/CD pipelines, where an IAM user's access keys are embedded in configuration or environment variables. The alternative: using IAM roles for EC2 instances, ECS tasks, Lambda functions, or OIDC federation for CI/CD; provides credentials that automatically rotate and don't require secrets management.

Second, for human users accessing AWS through the AWS CLI. Rather than configuring AWS Identity Center (formerly AWS SSO), organizations create IAM users and generate access keys. This becomes especially problematic with multiple AWS accounts, where you end up with IAM users duplicated across accounts, each with their own long-lived credentials.

AWS Identity Center solves this cleanly. Users authenticate once and can assume roles in any account they're authorized for, using short-lived credentials that expire automatically. The aws sso login command handles the authentication flow, and your CLI sessions use temporary credentials rather than static keys sitting in ~/.aws/credentials.

This matters more than ever given the prevalence of supply chain attacks. Compromised development tools, malicious packages, and credential-stealing malware are real threats. Long-lived access keys stored in plaintext configuration files are exactly what attackers look for. See our guide on secrets management best practices for more. Short-lived credentials that exist only in memory and expire within hours significantly limit the blast radius of a compromise.

Misunderstanding and Misusing Root Accounts

There's persistent confusion about what "root account" means in AWS, and it leads to real security gaps.

Many people conflate the organization's management account with root account, or don't realize that every AWS account has its own root account. When you create a new account in AWS Organizations, that account has a root user with its own email address and the ability to set its own password and MFA. If these root credentials aren't secured, you have a significant vulnerability.

Root credentials in AWS are different from normal administrative access. The root user can do things that even the most privileged IAM user cannot: close the account, change the account's email address, modify certain billing settings, and restore IAM permissions if they've been completely locked down. Root is the ultimate break-glass credential.

We find root accounts being used for routine administrative work, and root users in organizational member accounts that have never been secured because nobody realized they existed.

AWS has recently improved this situation with centralized root access management. This feature allows you to manage root credentials for member accounts in your organization from a central location, including removing root credentials entirely from accounts where they're not needed. If you haven't looked at this capability yet, it's worth investigating, it significantly simplifies the challenge of securing root access at scale.

The practical advice: don't use root for anything routine. Secure root credentials with strong unique passwords and hardware MFA. Consider whether you can eliminate root credentials from member accounts entirely using the new centralized management features.

The Common Thread

Looking across these issues, there's a common pattern: shortcuts taken early in an AWS deployment become increasingly expensive to fix as the environment grows. An unencrypted database is trivial to avoid at creation time but requires a coordinated migration later. A publicly exposed database endpoint takes seconds to set up but weeks to properly replace with secure access patterns across a large team.

The compliance and security requirements in frameworks like SOC 2 and ISO 27001 aren't arbitrary. They reflect actual security best practices. The organizations we work with that have the smoothest compliance journeys are the ones that built these practices in from the start rather than retrofitting them later.

If you're early in your AWS journey, take the time to set up proper account structure, encryption defaults, network isolation, and identity management. If you're further along and recognize some of these patterns in your own environment, the best time to fix them is now, before they become even more entrenched.


Frequently Asked Questions

Based on our audits, the most common issues are unencrypted RDS databases and internet-exposed resources that should be private. Both are easy to prevent during initial setup but painful to fix later.

In the AWS Console, navigate to RDS > Databases, select your instance, and check the "Encryption" field in the Configuration tab. If it shows "Not encrypted," you'll need to migrate to an encrypted instance.

Not directly. You must create an encrypted snapshot of the database, restore from that snapshot to create a new encrypted instance, then migrate your application to use the new instance.

Use AWS Systems Manager Session Manager. It provides secure access without opening inbound ports, eliminates SSH key management, and provides full audit logging for compliance.

While not prescriptive about specific tools, both frameworks require encryption at rest, network segmentation, access controls, and audit logging. These configurations address all of those requirements.


Bastion helps companies achieve SOC 2, ISO 27001, and other compliance certifications while building genuinely secure infrastructure. If you're dealing with any of these issues or want to ensure you're set up correctly from the start, reach out to us.

Share this article

Other platforms check the box

We secure the box

Get in touch and learn why hundreds of companies trust Bastion to manage their security and fast-track their compliance.

Get Started