blog.rust.gay

IAM least privilege in practice

Least privilege in AWS IAM means granting only the permissions required to perform a task, for specific resources and conditions. In practice, that is less a one-time policy-writing exercise and more an operating loop: start with a workable baseline, observe real access, and tighten permissions as the workload becomes clearer.

How IAM evaluates a request

Every request is authenticated and then evaluated against the policies that apply to the principal, the resource, and the account. The most important rule is simple: an explicit Deny in any applicable policy overrides Allow.

The way Allow works depends on the policy types involved:

  • Identity-based and resource-based policies in the same account are evaluated together. If an action is allowed by either policy type and not explicitly denied, the request can succeed.
  • Permissions boundaries limit identity-based permissions. For an IAM user or role, the effective permissions are the intersection of its identity-based policies and its permissions boundary.
  • AWS Organizations service control policies (SCPs) and resource control policies (RCPs) set maximum permissions across accounts. They do not grant permissions on their own; an action must also be allowed by the relevant identity-based or resource-based policies.

These rules matter because "least privilege" is not just about writing smaller policies. You can enforce ceilings with boundaries and organization policies, and you can use conditions to narrow when an allowed action actually applies.

Prefer roles and temporary credentials

AWS IAM guidance recommends using temporary credentials instead of long-term credentials whenever possible. For human users, that usually means federation through an identity provider or AWS IAM Identity Center, with access granted by assuming roles. For workloads on AWS compute services, the platform can deliver temporary role credentials to the application through the AWS SDK credential chain.

Long-term access keys still exist for cases where roles are not supported, such as some third-party tools or specific service integrations, but they should be treated as exceptions. Where you must keep them, rotate or remove them based on actual use rather than leaving them indefinitely.

A small trust policy illustrates the role model: it does not grant AWS permissions by itself, it defines who may assume the role.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "Service": "lambda.amazonaws.com" },
      "Action": "sts:AssumeRole"
    }
  ]
}

The permissions come from the identity-based policies attached to that role, constrained by any applicable boundaries or organization policies.

Start broad enough to learn, then narrow

A practical least-privilege workflow rarely begins with a perfect hand-written policy. AWS recommends getting started with AWS managed policies for common use cases, then moving toward customer managed policies that fit your workload. Managed policies are useful scaffolding, but they are designed for broad reuse and may grant more than a specific application needs.

IAM Access Analyzer can help close that gap:

  • Policy generation analyzes AWS CloudTrail activity for an IAM user or role and produces a policy template based on actions that were actually used in a selected time range.
  • Policy validation checks policies against IAM policy grammar and AWS best practices, and reports warnings, errors, and suggestions before deployment.
  • Last accessed information helps identify unused users, roles, permissions, and credentials so you can remove access that is no longer needed.

For resources that might be exposed outside your intended trust zone, Access Analyzer findings can also surface public or cross-account access paths. The point is not to trust the tool blindly, but to use it as evidence while you iterate.

Use guardrails for delegation and scale

Least privilege breaks down when every team can grant unlimited permissions. AWS provides guardrails that separate "what this identity is allowed to do" from "what it is ever allowed to do."

  • Permissions boundaries let administrators delegate role or user management while enforcing a maximum permission set. A boundary does not grant access; it only limits what attached identity-based policies can grant.
  • SCPs and RCPs in AWS Organizations apply guardrails across accounts and resources. They are useful for organization-wide controls, but they still require identity-based or resource-based policies to grant the actual permissions.
  • Conditions in IAM policies can further restrict access, for example by requiring multi-factor authentication or specific request properties supported by the service and action.

Treat guardrails as part of the design, not cleanup. If a developer can create roles, a permissions boundary makes that delegation safer. If many accounts share a baseline security posture, organization policies can prevent exceptions from becoming the default.

What to watch

Least privilege is a moving target. Services add actions, workloads change, and emergency permissions tend to become permanent if nobody reviews them. A useful review cadence combines CloudTrail evidence, Access Analyzer findings, and removal of unused access. If you cannot verify that a permission is still needed, that is a signal to test removing it, not to keep it forever.

The goal is not the smallest possible policy on paper. The goal is a permission set you can explain, monitor, and safely tighten over time.

Sources


← back to posts