Start from what the workload actually does, then replace wildcard actions and resources with named ones, add conditions, and validate the result before merge. AWS recommends granting only the permissions needed for a task, and describes starting broad and narrowing as your use case matures. The key is to schedule the narrowing, not leave it for later.
Why IaC makes this easy to get wrong
A policy in code is copied, pasted and rarely revisited. A quick Action star on Resource star gets a pipeline green, and the pull request that introduced it is long forgotten. Because IAM changes come through the same pipeline as everything else, they also deserve the same review rigor as application code.
A path from broad to narrow
AWS's best practices describe these steps.
- Start with managed policies if you must. AWS managed policies cover common cases but are written for all customers, so they may not be least privilege for you. Replace them with customer managed policies specific to your use case.
- Generate a policy from activity. IAM Access Analyzer can analyze the actions a role used in CloudTrail and generate a fine-grained policy. AWS says to test each generated policy before deploying it to production.
- Validate. IAM Access Analyzer policy validation offers more than 100 checks with actionable recommendations, covering both grammar and security best practice.
- Add conditions. Conditions can restrict access further, for example requiring TLS, or allowing an action only when used through a given service.
- Remove what is unused. Last accessed information shows permissions, roles and credentials that nobody uses.
What to change in the code
- Replace
Action = "*"with the list of actions the workload calls. - Replace
Resource = "*"with the specific ARNs, built from Terraform references rather than hard-coded strings so they track the resources. - Split one large policy into smaller ones per role, so each role has one job.
- Keep wildcards only where the service requires them, with a comment explaining which call needs it.
Guardrails around the policy
- Permissions boundaries set the maximum permissions an identity-based policy can grant. AWS suggests them when you delegate permission management, for example letting developers create roles for their workloads.
- Service control policies at the organization level set guardrails across accounts. AWS notes they grant no permissions on their own.
- Temporary credentials for workloads, using roles rather than long-lived access keys.
Review questions for a pull request
- Does any statement allow all actions on all resources?
- Can this role create or modify IAM policies or roles? That is a path to escalate.
- Could this role read secrets or state outside its job?
- Is there a condition that limits where the role can be used?
- Is there a plan to review the policy after real usage data exists?
An honest limit
Generated policies reflect observed behavior, so they miss rare but legitimate calls, such as a quarterly job. Test against the full set of workflows, and keep the policy in code so fixing a missing permission is a small, reviewed change.
Safeguard's policies and gates can hold a merge on checks you define, and its compliance evidence automation can keep the review trail.
Quick check
Is an AWS managed policy least privilege?
Not usually. AWS says managed policies may not grant least privilege for your use case, so move toward customer managed policies.
Can generated policies be deployed straight to production?
AWS says to test each generated policy first. They reflect observed activity and can miss rare actions.
Sources
Last reviewed: 19 October 2026.