Cloud security

Hardening a small AWS environment without losing track of access

This lab was less about turning on every AWS security setting and more about understanding who could reach what, why that access existed, and how to reduce it without breaking the environment.

← ALL WRITEUPS

Cloud security problems are often configuration problems. Nothing has to be exploited if a user, service, bucket, or network path already has more access than it needs.

For this lab, I worked through three areas that repeatedly shape AWS exposure: IAM roles, S3 policies, and security groups. The goal was to identify broad access, understand what was actually required, and replace it with narrower rules.

1. Start with identities, not services

Before changing individual resources, I looked at how access was granted. IAM policies can accumulate permissions quickly, especially when broad managed policies or wildcard actions are used for convenience.

identity → attached policy → allowed action → target resource

I reviewed permissions by asking a simple question: what task does this identity need to perform? The answer should determine the actions and resources in the policy. If the explanation for a permission was only “it might need this later,” that was a sign to narrow it.

Least privilege is easier to maintain when every permission has a specific reason to exist.

2. Separate identity policy from resource policy

S3 was useful because access can be controlled from more than one direction. An IAM policy may allow an action while a bucket policy sets resource-level conditions. Looking at only one side can produce an incomplete picture.

I reviewed bucket access for unnecessarily broad principals and actions, then tightened the policies around the intended users and operations. The important part was not simply making a bucket “private.” It was being able to explain exactly which identity could perform which action against which bucket or object path.

principal + action + resource + condition = effective access decision

3. Treat security groups as reachability rules

Security groups are easy to understand as a list of ports, but that view misses the real question: which source can reach which destination, over which protocol, and for what reason?

I reviewed inbound and outbound rules for broad sources and unnecessary exposure. Replacing a wide CIDR range with a narrower source, or removing an unused rule entirely, reduced the attack surface without changing the application itself.

This reinforced the difference between a service being functional and being intentionally reachable. “The connection works” is only the first test. The next test is whether it works only from the places that should be allowed.

4. Remediation needs a reason and a verification step

It is possible to make a configuration look stricter and still misunderstand the risk. For each change, I connected the original configuration to a concrete exposure, applied a narrower control, and checked that the required access still worked.

find broad access → define intended use → narrow the control → verify required behavior

That sequence matters because security changes can create outages when they are made without understanding dependencies. The safest remediation is not always the smallest policy; it is the smallest policy that still supports the legitimate task.

What I took away

The lab made cloud security feel like a problem of relationships. IAM roles, S3 policies, and security groups are different control types, but they all answer versions of the same question: who or what can reach this resource?

Good hardening makes that answer shorter, more specific, and easier to review later. The goal is not a pile of restrictive settings. It is an environment where access is deliberate and the remaining risk is visible.

Back to the project overview →