Mastering AWS Security Specialty - Post 1: Deep Dive into IAM – Core of AWS Security


What Is IAM and Why It Matters
AWS Identity and Access Management is at the core of AWS security. It determines who can access what, how, and under what conditions.
Note: IAM protects AWS APIs only.
AWS IAM is your initial defense layer. Misconfiguration can result in overly permissioned access—or worse, exposed data.
IAM Identities
Identity | Description | When to Use | Example |
User | Represents an individual or a service | Long-term identity, used for console or programmatic access | Developers, CI/CD tools |
Group | A collection of users | Apply same policies to multiple users | Developers group with S3 access |
Role | Temporary credentials | Used by AWS services, users, applications, external identities | EC2 to access S3, cross-account access |
Federated User | External identity (AD, Google, etc.) authenticated via STS | Don’t want to manage IAM users. | SSO with Okta or AD Federation |
Service-linked Role | Predefined role linked to AWS service | Allows AWS service to manage resources on your behalf | AWS Elastic Beanstalk role, Auto scaling. |
AWS Account Root User | Full access identity created during account setup | Only for billing or account recovery | Never use for daily tasks |
IAM Policies
An IAM policy is a JSON document that must follow a strictly defined format.
Primary Elements of policy:
Principal : Who is making the request. It is an Identity that sends the request, such as user, role, AWS service, or some special entity.
Action : What they want to do. It defines what the Principal wants to do, such as reading an object in S3.
Resource: What they want to access. It is the logical entity in the account. Any AWS service that is the subject/target of the request.
IAM Policy Filters
Elements like Principal/NotPrincipal,
Action/NotAction,
Resource/NotResource can serve as filters.
example policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowSpecificPrincipalAccess",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:user/SpecificUser"
},
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::example-bucket"
},
{
"Sid": "DenyAllExceptSpecificPrincipals",
"Effect": "Deny",
"NotPrincipal": {
"AWS": "arn:aws:iam::111122223333:user/SpecificUser"
},
"Action": "s3:*",
"Resource": "arn:aws:s3:::example-bucket/*"
},
{
"Sid": "AllowExceptSpecificActions",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/SpecificRole"
},
"NotAction": [
"s3:DeleteObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::example-bucket/*"
},
{
"Sid": "DenySpecificResources",
"Effect": "Deny",
"Principal": {
"AWS": "arn:aws:iam::111122223333:user/SpecificUser"
},
"Action": "s3:*",
"NotResource": "arn:aws:s3:::example-bucket/specific-folder/*"
}
]
}
IAM Policy Conditions
Conditions refine permissions by specifying when a policy statement is applicable.
Key Components:
Condition Keys: Predefined or AWS-specific keys (e.g.,
aws:SourceIp
,s3:Prefix
).Condition Operators: Logical operators to compare values (e.g.,
StringEquals
,IpAddress
).Condition Values: The value(s) against which the condition key is evaluated
Condition Types
1. Global Condition Keys
These keys are common across all AWS services.
Examples:
aws:SourceIp
: Restrict access based on the IP address.aws:UserAgent
: Restrict access based on the user agent of the client.aws:RequestTag
: Control access based on request tags.aws:MultiFactorAuthPresent
: Check if MFA is used.
2. Service-Specific Condition Keys
Each AWS service has its own condition keys. Below are examples from popular services:
S3 (Amazon Simple Storage Service):
s3:Prefix
: Control access to objects with a specific prefix.s3:x-amz-acl
: Restrict actions based on the ACL used in the request.s3:RequestObjectTagKeys
: Control access based on object tags in the request.
EC2 (Elastic Compute Cloud):
ec2:Region
: Restrict actions to a specific region.ec2:InstanceType
: Control actions based on instance type.
KMS (Key Management Service):
kms:EncryptionContext:Key
: Restrict access based on encryption context keys.kms:ViaService
: Control access based on the service that is using the key.
IAM (Identity and Access Management):
iam:PolicyARN
: Restrict actions based on attached policy ARNs.iam:ResourceTag
: Control access based on resource tags.
CloudWatch:
cloudwatch:Namespace
: Restrict actions to specific namespaces.cloudwatch:ResourceTag
: Control actions based on tags.
3. Common Operators
StringEquals
: Checks if the string matches exactly.StringLike
: Checks if the string matches a pattern (wildcards supported).IpAddress
: Checks if the IP address is in specific ranges.NumericEquals
: Checks if a numeric value matches.DateEquals
: Checks if a date matches.Bool
: Checks if a value istrue
orfalse
.
IAM Policy Types
How a policy behaves is determined by what it is attached to. We can attach a policies to different entities as below, and they are named accordingly.
1. Identity-based:
- Grant permissions to identities, attached to user, group, or role. As it attached to a Principal so there is no
Principal
element in policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::app-logs/audit.log"
},
{
"Effect": "Deny",
"Action": [
"s3:PutObject"
],
"Resource": "arn:aws:s3:::app-logs/*"
}
]
}
2. Resource-based:
- Defined on the resource (e.g., S3 bucket policy, Lambda permission). Supports cross-account access. Only certain services support resource-based policies (S3, SNS, SQS, Lambda, etc.)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789:role/app-auditors"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::app-log/audit.log"
}
]
}
Note: All resources NOT supports Resource-based policies refer the table for details
3. Permission Boundaries:
Limit max permissions regardless of attached policies. Important for delegated access.
Delegate admin role to developers but cap their power using permissions boundaries
Policy
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}]
}
Boundary
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "LimitToSpecificServices",
"Effect": "Allow",
"Action": [
"s3:*", // Allows S3 actions
"ec2:Describe*", // Allows describing EC2 resources
"lambda:InvokeFunction" // Allows invoking AWS Lambda
],
"Resource": "*"
},
{
"Sid": "DenySensitiveActions",
"Effect": "Deny",
"Action": [
"iam:*", // Deny IAM actions
"ec2:Terminate*" // Deny EC2 termination
],
"Resource": "*"
}
]
}
4. Session Policy:
- Attached to STS temporary session to restrict permissions during a role/session. Used during AssumeRole. They do not limit what the identity (who is using a role) can do, but they put self-imposed restraints on the permissions.
A role that has full access to all S3 buckets
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
However, you want to ensure that during the session, this user can only access a specific S3 bucket (example-bucket
) and only perform read operations (GetObject
).
Session-policy-example.json
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReadAccessToSpecificBucket",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::example-bucket/*"
]
},
{
"Sid": "DenyAllOtherS3Actions",
"Effect": "Deny",
"Action": "s3:*",
"Resource": "*"
}
]
}
Apply the Session Policy:
aws sts assume-role \
--role-arn "arn:aws:iam::123456789012:role/FullAccessRole" \
--role-session-name "RestrictedSession" \
--policy file://session-policy-example.json
5. Service Control Policies (SCPs):
Org-level permission filter. It sets permission boundaries for accounts. Note: Cannot grant permissions, only restrict.
An operation is denied if it does not explicitly allowed.
We can use 2 approaches to define the policy -
Allow Listing will restrict all except allowed in policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}
Deny listing will allow except explicitly denied.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
},
{
"Effect": "Deny",
"Action": "iam:*",
"Resource": "*"
}
]
}
6. Inline Policies:
Attached to a single identity (User, Group, Role). Use when the policy is unique and shouldn’t be reused. When we delete the identity, the policy is deleted with it.
7. Managed Policies:
Managed policies are separate permission resources that we can attach to multiple identities and manage in a central place.
AWS Managed: Created by AWS for most common use-cases. (e.g.,
AmazonS3FullAccess
)Customer Managed: You define it (recommended for control). When multiple identities need same access create your own in IAM Policy.
Permissions Boundaries vs SCPs
Feature | Permissions Boundary | SCP |
Applies to | IAM User/Role | AWS Account/OU |
Limits | Max permissions | All IAM permissions |
Use Case | Delegation, control | Multi-account governance |
IAM Policy Evaluation Logic
Explicit Deny > Allow > Implicit Deny
If there is a Deny, then denied.
If there is no Allow, then denied.
Policies from all sources (user, group, role) are merged
Denies override all allows.
Types of IAM Roles
Role Type | Purpose | How/When to Use | Example |
Service Role | Grant AWS services permissions | Use with EC2, Lambda, ECS, etc. | EC2 to write logs to CloudWatch |
Cross-account Role | Share access between AWS accounts | Used in centralized logging, multi-account strategy | Admin role in Shared Services account |
Federated Role | Used by external identities via STS | Integrate corporate directory | SAML or OIDC federation |
Role for Applications | Temporary credentials for apps | Use with mobile/web apps | Cognito + IAM role |
Service-linked Role | Required by AWS services | Automatically created | AWS Config or Elastic Beanstalk roles |
IAM Security Best Practices
Enable MFA for all users
Use roles instead of long-term credentials
Implement least privilege access
Enable Access Analyzer to spot unintended access
Tag identities for better management and automation
Summary & What’s Next
IAM is foundational. You now understand:
Different IAM entities
Policy types and their roles
Evaluation logic and best practices
Exam Tips:
Topic | Things to Remember |
Policy Evaluation | Explicit Deny > Allow > Implicit Deny |
MFA Policies | You can require MFA via conditions in policy |
Federation | Know difference between SAML, OIDC, and IAM Identity Center |
SCP | Does NOT grant permissions, only restricts |
Access Analyzer | Exam focuses on detecting unwanted access |
IAM Roles | Require trust policy and are assumed using STS |
IAM User Keys | Rotate regularly and avoid long-term usage |
Service-linked Roles | Auto-created by AWS services – don’t modify manually |
Session Duration | Can control using sts:DurationSeconds in trust policy |
Principal of Least Privilege | Always enforce minimum required access |
Coming Up:
Next, we’ll dive into AWS CloudTrail — your forensic lens into AWS.
Stay tuned for more in the "Mastering AWS Security Specialty" series!
To understand big picture of AWS Security Services, check “Choosing the Right AWS Security Services: A Solution Architect's Guide”
Subscribe to my newsletter
Read articles from Suman Thallapelly directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by

Suman Thallapelly
Suman Thallapelly
Hey there! I’m a seasoned Solution Architect with a strong track record of designing and implementing enterprise-grade solutions. I’m passionate about leveraging technology to solve complex business challenges, guiding organizations through digital transformations, and optimizing cloud and enterprise architectures. My journey has been driven by a deep curiosity for emerging technologies and a commitment to continuous learning. On this space, I share insights on cloud computing, enterprise technologies, and modern software architecture. Whether it's deep dives into cloud-native solutions, best practices for scalable systems, or lessons from real-world implementations, my goal is to make complex topics approachable and actionable. I believe in fostering a culture of knowledge-sharing and collaboration to help professionals navigate the evolving tech landscape. Beyond work, I love exploring new frameworks, experimenting with side projects, and engaging with the tech community. Writing is my way of giving back—breaking down intricate concepts, sharing practical solutions, and sparking meaningful discussions. Let’s connect, exchange ideas, and keep pushing the boundaries of innovation together!