Chapter 02
IAM and access control
Every API call on AWS is authenticated and then checked against policies. Getting IAM right is most of AWS security.
IAM users, groups and roles
Also called principal, identity
- What
- A principal is who makes a request. IAM users are long-term identities with passwords or access keys; groups attach policies to many users; roles have no credentials of their own and are assumed to get temporary ones.
- Why
- Roles are the modern default for people, services and pipelines alike, because temporary credentials expire and cannot leak for years.
Watch out
Creating an IAM user with access keys for a CI pipeline or an app on EC2, instead of a role the pipeline or instance assumes.
Policy documents
Also called IAM policy, Effect Action Resource
- What
- A policy is JSON with statements. Each statement has an
Effect(Allow or Deny),Action(such ass3:GetObject),Resource(ARNs) and an optionalCondition. - Why
- Reading and writing these precisely is how you grant exactly what a workload needs and nothing more.
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["dynamodb:GetItem", "dynamodb:PutItem"],
"Resource":
"arn:aws:dynamodb:eu-west-2:123456789012:table/orders"
}]
}Watch out
Writing "Resource": "*" with a broad action list because the right ARN took effort to find.
Identity-based vs resource-based policies
Also called bucket policy, trust policy
- What
- Identity-based policies attach to a user, group or role and say what it may do. Resource-based policies attach to a resource, such as an S3 bucket, SQS queue or KMS key, and name which principals may use it. A role trust policy is the resource policy that says who may assume the role.
- Why
- Cross-account access and service-to-service access often need a resource policy, and the trust policy is why an assume-role call is allowed or refused.
- Example
- For account A to read a bucket in account B, B's bucket policy must allow A's role, and A's role policy must allow
s3:GetObjecton that bucket.
Policy evaluation logic
Also called explicit deny, implicit deny
- What
- Every request starts denied. An explicit Deny in any applicable policy wins. Otherwise the request must be allowed by an identity or resource policy and also fall within any SCP, resource control policy, permissions boundary and session policy in play.
- Why
- Knowing the order turns "access denied" from guesswork into a checklist: look for a deny, then a missing allow, then a limiting boundary or SCP.
Watch out
Adding more Allow statements to fix an access denied error that is really caused by an explicit Deny or an SCP.
Least privilege and Access Analyzer
Also called IAM Access Analyzer, unused access
- What
- Least privilege means granting only the actions and resources a principal needs. IAM Access Analyzer finds resources shared outside your account, reports unused roles and permissions, and can generate a policy from actions seen in CloudTrail.
- Why
- It limits the blast radius of any leaked credential or compromised service, and Access Analyzer makes trimming permissions practical rather than guesswork.
Watch out
Starting with AdministratorAccess "for now" and never coming back to tighten it.
Policy conditions
Also called Condition keys, aws:SourceIp, aws:PrincipalOrgID
- What
- A
Conditionblock adds rules to a statement using keys such asaws:SourceIp,aws:PrincipalOrgID,aws:SecureTransport,aws:RequestedRegionor resource tags. - Why
- Conditions express rules actions alone cannot, such as "only over TLS", "only from our organisation" or "only on resources tagged with my team".
{
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": "arn:aws:s3:::uploads/*",
"Condition": {
"Bool": { "aws:SecureTransport": "false" }
}
}STS and assuming roles
Also called AssumeRole, temporary credentials, OIDC federation
- What
- The Security Token Service issues temporary credentials when a principal assumes a role. CI systems such as GitHub Actions assume roles through OIDC federation, with no stored keys at all.
- Why
- Temporary credentials expire on their own, so a leak has a short life, and one role can be shared across many callers with a clear audit trail.
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/deploy \
--role-session-name ci-run-42 \
--duration-seconds 3600Watch out
A trust policy that lets any GitHub repository assume the role because the sub condition was left out.
IAM Identity Center
Also called AWS SSO, permission sets
- What
- Identity Center is the central sign-in for people across all accounts in an organisation. Users come from its own directory or an external identity provider, and permission sets become roles in each account they are assigned to.
- Why
- It replaces per-account IAM users with one login, short-lived credentials and access you can grant or revoke in one place.
Permissions boundaries
- What
- A permissions boundary is a managed policy attached to a user or role that caps the permissions its identity policies can grant. The effective permissions are the overlap of the two.
- Why
- It lets you delegate role creation to developers safely: they can create roles, but never roles more powerful than the boundary.
KMS, Secrets Manager and Parameter Store
Also called Key Management Service, SSM Parameter Store
- What
- KMS manages encryption keys used by S3, EBS, RDS and others, with every use logged. Secrets Manager stores secrets with rotation; Systems Manager Parameter Store holds configuration and simpler secrets.
- Why
- Apps fetch secrets at runtime under an IAM role instead of baking passwords into images, environment files or source control.
Watch out
Granting kms:Decrypt on *, which quietly unlocks every secret and encrypted object that uses the account's keys.