AWS Identity and Access Management decides who can call AWS APIs and which resources each caller may use.
Identity policies grant permissions to users, groups, and roles. Trust policies decide who may assume a role, while resource policies can grant access directly on resources such as S3 buckets or KMS keys.
Least privilege is an iterative process: start with the actions and resources a workload needs, test the real request path, and refine permissions using CloudTrail and Access Analyzer.
IAM users are long-lived identities and should be uncommon. Groups organize permissions for users. Roles are assumed for a limited session by people, AWS services, applications, or identities from another account.
An Allow must apply to the requested action, resource, principal, and conditions. An explicit Deny in an identity policy, resource policy, permissions boundary, session policy, or service control policy overrides an Allow.
Applications running on AWS should receive credentials from their execution role. The SDK refreshes temporary credentials automatically, avoiding access keys in environment files or deployment packages.
When access fails, capture the caller ARN, requested API action, resource ARN, Region, and request conditions. Policy Simulator, CloudTrail, and Access Analyzer can then narrow the cause without adding broad permissions.
An IAM principal is the identity represented in an AWS request. A role is not a person or server by itself; it is an identity that a trusted principal assumes to obtain a temporary role session. The session has a principal ARN, expiration, source identity or session name where configured, and the effective intersection of applicable permission controls.
Human access should normally begin at an identity provider and end in a role session. Workloads on EC2, Lambda, ECS, or other AWS services should use an attached execution role whose temporary credentials are delivered by the platform. Cross-account automation assumes a role in the target account instead of copying a target-account access key.
Use separate roles for runtime, deployment, incident response, and read-only investigation because their actions and trust relationships differ. A deployment system that can pass an unrestricted runtime role may escalate privileges even if its direct service permissions look narrow. Review both `sts:AssumeRole` and `iam:PassRole` paths.
A policy statement combines `Effect`, `Action` or `NotAction`, `Resource` or `NotResource`, and optional `Condition`; resource policies can also name a `Principal`. Start from the business request, translate it into exact API actions, identify the resource ARN format, and add conditions that represent the trust boundary. Avoid beginning with `Action: *` and trying to reduce it later.
Not every AWS action supports resource-level permissions or every condition key. Consult the service authorization reference before assuming an ARN or tag condition will apply. Some workflows require supporting actions such as listing a parent resource even when the main data action is narrow. Keep those permissions explicit so reviewers can distinguish discovery from modification.
Policy variables and tags can reduce repetition, but they increase the importance of controlled tag assignment. A user who may change the tag used for authorization might grant themselves access. Protect authorization tags, validate policies with IAM Access Analyzer, and use meaningful statement identifiers in customer-managed policies.
AWS authorization can involve identity policies, resource policies, session policies, permissions boundaries, service control policies, resource control policies, and service-specific controls. An applicable explicit deny wins. Otherwise, the request needs an applicable allow, with exact behavior depending on principal and policy type. Debug the complete request context rather than reading one attached policy in isolation.
A permissions boundary limits the maximum identity-based permissions available to a user or role. It is useful when a platform team delegates role creation but wants to prevent the delegated administrator from exceeding an approved envelope. The boundary grants nothing by itself, and changing which principals can create, attach, or remove it is part of the control.
Service control policies constrain identities in organization member accounts; resource control policies constrain supported resources. Neither grants access. Test guardrails against administrators, service-linked roles, automation, and incident workflows, and document exclusions or policy behavior that could surprise responders.
Cross-account role access has two sides. The target role trust policy names who may assume it and under which conditions; the source principal also needs permission to call `sts:AssumeRole`. Narrow the trust to an organization, account, role, or federated claim appropriate to the relationship instead of trusting every principal in a broad account without review.
For third-party access, use an external ID when the integration calls for protection against the confused-deputy problem, and require the vendor to provide a unique value. For AWS services, use service principals and available source-account or source-ARN conditions to bind the request to the expected resource. Do not copy a trust statement without understanding which principal can satisfy it.
Role chaining, session duration, session tags, and source identity affect traceability and effective permissions. Design a session name format and require transitive tags only when downstream authorization needs them. Revoke access by changing the trust or source permission, then account for already issued sessions until they expire.
Capture the exact API action, caller ARN, target ARN, account, Region, timestamp, request ID, and relevant context such as tags or VPC endpoint. An `AccessDenied` message may include the policy type responsible, but it is not a complete authorization trace. Reproduce with the same principal and smallest safe request before changing policy.
Confirm that the credential provider selected the identity you expected. Then inspect the identity policy, session policy, permissions boundary, organization controls, resource policy, KMS key policy where encryption is involved, and service-specific ownership settings. A successful console page may call several APIs, so use CloudTrail or browser developer evidence to identify the denied operation.
Correct the narrow cause and rerun both the allowed path and a nearby denied path. Do not attach administrator access as a diagnostic shortcut because it erases information about the missing permission and may remain attached. Record the final action-resource-condition set as a contract test or policy simulation case.
Least privilege changes as a workload and its dependencies change. Begin with a reviewed policy based on documented API needs, deploy it in a controlled environment, and observe actual use through CloudTrail and Access Analyzer. Generate or refine a policy from activity only after representative operations, failures, maintenance, and recovery have occurred.
Review last-used information carefully: absence of recent activity can justify investigation but does not prove a disaster-recovery permission is unnecessary. Mark rare permissions with an owner and test schedule. Remove unused IAM users, access keys, roles, managed-policy versions, federation providers, and trust relationships during a recurring access review.
Version policies through code review and deploy them with rollback awareness. An access expansion needs a reason and expiry when temporary; an access reduction needs tests that cover operations and emergency paths. Security improves when teams can prove which request requires a permission and can remove it without guessing.
This policy permits listing one bucket and reading objects from one prefix instead of granting blanket S3 access.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:ListBucket"],
"Resource": "arn:aws:s3:::company-documents",
"Condition": {
"StringLike": {
"s3:prefix": ["public/*"]
}
}
},
{
"Effect": "Allow",
"Action": ["s3:GetObject"],
"Resource": "arn:aws:s3:::company-documents/public/*"
}
]
}
A workload can list a bucket but must read objects only under its tenant prefix.
Constraints: An identity policy allows tenant-a/*, the bucket policy denies non-TLS requests, and no wildcard principal is acceptable.
Decision: Evaluate explicit denies first, then intersect the role session, identity policy, resource policy, and permissions boundary.
Verification: A TLS request for tenant-a/report.csv succeeds; tenant-b/report.csv and an insecure request are denied in CloudTrail.
Failure test: Add a broad Allow in the identity policy and prove the resource-policy Deny still wins.
Expected evidence: A TLS request for tenant-a/report.csv succeeds; tenant-b/report.csv and an insecure request are denied in CloudTrail.
Explore 500+ free tutorials across 20+ languages and frameworks.