This chapter covers Attribute-Based Access Control (ABAC) in AWS, a powerful authorization strategy that uses tags to define permissions based on user and resource attributes. ABAC is a key topic in the DVA-C02 exam under Domain 2: Security, Objective 2.1 (Implement access control using IAM policies and resource-based policies). Approximately 5-10% of exam questions touch ABAC, often comparing it to role-based access control (RBAC) or testing its implementation with IAM policies and condition keys. Mastering ABAC will help you design scalable, fine-grained access control for AWS environments.
Jump to a section
Attribute-Based Access Control (ABAC) is like a modern hotel key card system that grants room access based on attributes of the guest, the room, and the time. Imagine a hotel where each guest receives a key card encoded with attributes: their name, role (e.g., 'VIP', 'staff'), floor access level, and check-out time. Each door lock has a policy that evaluates these attributes at the moment of swiping. For example, a VIP guest with a card encoded for the 10th floor can access the executive lounge only if the current time is between 6 PM and 10 PM, and their role is 'VIP'. The lock does not check a list of allowed guests; it checks the attributes on the card against its own policy. If the guest tries to enter a restricted area, the lock denies access immediately based on missing attributes. This is precisely how AWS ABAC works: IAM policies use condition keys like aws:PrincipalTag, aws:ResourceTag, and aws:RequestTag to evaluate access at runtime. The policy is written once and applies to any principal or resource with matching tags, without needing to update the policy when new users or resources are added. The 'key card' is the principal's tags; the 'door lock' is the resource's tags and the policy conditions. When a request arrives, AWS evaluates the principal's tags, the resource's tags, and the request context against the policy, granting access only if the attributes satisfy the conditions.
What is ABAC and Why It Exists
Attribute-Based Access Control (ABAC) is an authorization strategy that defines permissions based on attributes (tags) associated with the principal (user or role), the resource, and the environment (e.g., time of day). Unlike Role-Based Access Control (RBAC) which assigns permissions to roles that users assume, ABAC uses policies with conditions that evaluate these attributes at runtime. This makes ABAC more dynamic and scalable because you can write a single policy that grants access to any resource that has matching tags, without needing to update the policy when new users or resources are added.
ABAC is particularly useful in large, multi-team AWS environments where resources and users are constantly changing. For example, a developer in the 'project-alpha' team should only access S3 buckets tagged with 'project-alpha'. With ABAC, you create one policy that grants access to S3 buckets where the bucket's 'project' tag equals the user's 'project' tag. When a new developer joins project-alpha, you tag them with 'project=alpha', and the policy automatically applies.
How ABAC Works Internally
ABAC relies on IAM policies with condition keys that evaluate principal, resource, and request attributes. The key condition keys are:
- aws:PrincipalTag: A tag on the IAM user or role making the request.
- aws:ResourceTag: A tag on the resource being accessed.
- aws:RequestTag: A tag passed in the request (e.g., when creating a resource).
- aws:TagKeys: The set of tag keys in the request.
When a request is made, AWS evaluates the policy. The policy might say: "Allow s3:GetObject if the resource tag 'project' equals the principal tag 'project'." At runtime, AWS retrieves the principal's tags (e.g., project=alpha), retrieves the resource's tags (e.g., project=alpha), and checks if they match. If they do, access is granted.
Key Components and Configuration
To implement ABAC, you need:
1. Tags on principals (IAM users/roles): Each principal must have tags that define their attributes. For example, department=engineering, project=alpha.
2. Tags on resources: Each resource must have tags that match the principal's tags. For example, an S3 bucket with project=alpha.
3. IAM policy with condition keys: The policy must use conditions like StringEquals to compare principal and resource tags. Example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*",
"Condition": {
"StringEquals": {
"aws:ResourceTag/project": "${aws:PrincipalTag/project}"
}
}
}
]
}Note the use of ${aws:PrincipalTag/project} – this is a policy variable that resolves to the value of the principal's project tag at runtime.
Policy Variables in ABAC
Policy variables are a critical feature for ABAC. They allow you to substitute the value of a principal tag or resource tag in a condition. The syntax is ${aws:PrincipalTag/tagkey} or ${aws:ResourceTag/tagkey}. AWS supports policy variables only in the Condition block, not in the Resource or Principal elements. This is a common exam trap: candidates think they can use policy variables in the Resource ARN, but that is not supported.
Defaults and Limits
You can have up to 50 tags per IAM user, role, or resource (applies to most AWS services).
Tag keys are case-sensitive.
Condition keys like aws:PrincipalTag are available only when the principal is an IAM user or role; they do not work for root user or account-level actions.
ABAC works with IAM policies, resource-based policies (like S3 bucket policies), and AWS Organizations service control policies (SCPs).
Verification Commands
To verify ABAC setup, use the IAM policy simulator or the AWS CLI. For example, to test a policy with a specific principal:
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:user/Alice \
--policy-input-list file://policy.json \
--action-names s3:GetObject \
--resource-arns arn:aws:s3:::example-bucket/object.txtYou can also use the --context-entries parameter to simulate principal and resource tags:
aws iam simulate-custom-policy \
--policy-input-list file://policy.json \
--action-names s3:GetObject \
--resource-arns arn:aws:s3:::example-bucket/object.txt \
--context-entries "ContextKeyName=aws:PrincipalTag/project,ContextKeyValues=alpha,ContextKeyType=string"Interaction with Related Technologies
ABAC integrates with:
- IAM Roles: You can tag roles and use ABAC to control which resources they access.
- S3 Bucket Policies: Use aws:PrincipalTag in bucket policies to grant cross-account access based on tags.
- AWS Organizations: Use ABAC in SCPs to restrict access based on tags across accounts.
- AWS STS: When assuming a role, the role's tags are used, not the original user's tags. This is a common exam point: if a user assumes a role, the principal tags are the role's tags, not the user's.
Step-by-Step: How ABAC Evaluates a Request
Principal makes a request: An IAM user or role sends an API call to AWS.
AWS gathers context: AWS collects the principal's tags (from the user or role), the resource's tags (from the resource), and request tags (if any).
Policy evaluation: AWS evaluates all applicable IAM policies (identity-based, resource-based, SCPs). For each policy, it checks the conditions.
Condition matching: For a condition like StringEquals: { "aws:ResourceTag/project": "${aws:PrincipalTag/project}" }, AWS retrieves the principal's project tag value and the resource's project tag value. If they match, the condition is satisfied.
Decision: If all conditions are satisfied and there is an explicit allow, access is granted. If there is no explicit allow or a deny, access is denied.
Common Pitfalls
Mismatched tags: If the principal or resource lacks the required tag, the condition fails and access is denied.
Case sensitivity: Tags are case-sensitive. Project=Alpha does not match project=alpha.
Policy variables in wrong place: Policy variables only work in Condition elements, not in Resource or Principal.
Role assumption: When a user assumes a role, the role's tags are used, not the user's. This can cause unexpected denials if the role does not have the same tags as the user.
Advanced: ABAC with Multiple Conditions
You can combine multiple conditions to create fine-grained access. For example, allow access only if the principal's department tag matches the resource's department tag AND the request is made during business hours:
{
"Condition": {
"StringEquals": {
"aws:ResourceTag/department": "${aws:PrincipalTag/department}"
},
"IpAddress": {
"aws:SourceIp": "10.0.0.0/8"
}
}
}ABAC vs. RBAC on the Exam
The exam often asks you to choose between ABAC and RBAC. Remember: - RBAC: Permissions are tied to roles. You create roles like 'Developer' and 'Admin', and assign users to roles. When a new project starts, you might need a new role. - ABAC: Permissions are tied to tags. You create one policy that uses tags, and you tag users and resources accordingly. When a new project starts, you just tag the new users and resources with the project tag.
The exam scenario will describe a growing environment with many projects and teams. The correct answer is usually ABAC because it scales better without requiring policy updates.
Tag the Principal
First, attach tags to the IAM user or role that will make requests. Tags are key-value pairs. For example, tag a user with `project=alpha` and `department=engineering`. You can do this via the AWS Management Console, CLI, or CloudFormation. Use the command: `aws iam tag-user --user-name Alice --tags Key=project,Value=alpha`. Each principal can have up to 50 tags. Tags are inherited by the principal's sessions, including temporary credentials from STS.
Tag the Resource
Next, tag the AWS resources that the principal will access. For example, tag an S3 bucket with `project=alpha`. This is done at resource creation or later. For S3: `aws s3api put-bucket-tagging --bucket example-bucket --tagging 'TagSet=[{Key=project,Value=alpha}]'`. Ensure the resource supports tagging; most AWS services do. Tags are case-sensitive.
Write the IAM Policy
Create an IAM policy that uses condition keys to compare principal and resource tags. The policy must include a `Condition` block with `StringEquals` or other condition operators. Use policy variables like `${aws:PrincipalTag/project}` to dynamically insert the principal's tag value. For example: `"Condition": { "StringEquals": { "aws:ResourceTag/project": "${aws:PrincipalTag/project}" } }`. Attach this policy to the principal (or to a group/role the principal uses).
Test the Policy
Use the IAM policy simulator to test the policy before deploying. Provide the principal ARN, the action, the resource ARN, and optional context entries for tags. The simulator will show whether access is allowed or denied. Also test with real API calls. For example, try to list objects in the S3 bucket: `aws s3 ls s3://example-bucket/`. If tags match, you get the list; if not, you get an access denied error.
Monitor and Audit
Use AWS CloudTrail to log API calls and verify that ABAC is working as expected. Check the `userIdentity` and `requestParameters` for tag information. Use AWS Config to monitor tag compliance. For example, create a Config rule that checks if resources have required tags. Regularly review IAM policies and tag schemas to ensure they align with your access control requirements.
Enterprise Scenario 1: Multi-Project S3 Access
A large company has dozens of projects, each with its own S3 bucket. They have hundreds of developers who move between projects. Using RBAC, they would need to create a role per project and update permissions whenever a developer changes projects. With ABAC, they tag each developer with project=project-name and each bucket with project=project-name. A single policy grants s3:GetObject and s3:PutObject to any bucket where the bucket's project tag matches the user's project tag. When a developer switches projects, an admin simply updates the user's tag. The policy does not change. This reduces administrative overhead and prevents accidental access to other projects' data. In production, they also add a condition to restrict access to corporate IP ranges using aws:SourceIp.
Enterprise Scenario 2: EC2 Instance Management by Team
A DevOps team manages EC2 instances for different application teams. Each instance is tagged with team=frontend or team=backend. The DevOps team wants to allow each application team to start/stop their own instances but not others. They create an IAM policy that grants ec2:StartInstances and ec2:StopInstances only if the instance's team tag equals the principal's team tag. They also add a condition to allow ec2:DescribeInstances for all instances (so teams can see all instances). This policy is attached to an IAM group for each team. When a new team member joins, they are added to the group and tagged with the correct team value. If an instance is mis-tagged, the team cannot manage it, which enforces tag accuracy.
Performance and Scalability
ABAC does not introduce significant performance overhead because tag evaluation is done at the IAM policy engine, which is designed for high throughput. However, there is a limit of 50 tags per principal/resource, and the policy size limit is 6,144 characters for identity-based policies. For very large environments with thousands of tags, consider using AWS Organizations tag policies to enforce consistent tagging. Common misconfigurations include: tagging inconsistencies (e.g., case differences), using policy variables in the Resource element (which is unsupported), and forgetting that role assumption changes the principal's tags to the role's tags.
DVA-C02 Objective Coverage
ABAC falls under Domain 2: Security, Objective 2.1: Implement access control using IAM policies and resource-based policies. The exam tests your ability to:
Design IAM policies that use condition keys for ABAC.
Differentiate between ABAC and RBAC.
Identify when ABAC is the best solution (scalable, dynamic access control).
Understand how policy variables work and where they can be used.
Recognize that tags are case-sensitive and must match exactly.
Common Wrong Answers and Traps
Using policy variables in the Resource element: Candidates often try to write Resource: "arn:aws:s3:::bucket-${aws:PrincipalTag/project}". This is invalid. Policy variables are only supported in the Condition block. The correct approach is to use a wildcard in Resource and a condition on tags.
Confusing principal tags with session tags: When a user assumes a role, the principal tags become the role's tags, not the user's. Candidates think the user's tags persist, but they do not. If the role lacks the required tag, access is denied.
Thinking ABAC requires no policy updates: While ABAC reduces policy updates, you still need to write the initial policy. The exam might present a scenario where a new project requires a new policy; the correct answer is ABAC because you only need to tag the new users and resources, not create a new policy.
Overlooking case sensitivity: The exam loves to test tag case. A condition with StringEquals fails if tags differ in case.
Exam Numbers and Terms
50 tags per principal/resource (common limit).
6,144 characters maximum policy size for identity-based policies.
Condition keys: aws:PrincipalTag, aws:ResourceTag, aws:RequestTag, aws:TagKeys.
Policy variable syntax: ${aws:PrincipalTag/tagkey}.
Condition operators: StringEquals, StringLike, ForAllValues:StringEquals (for multiple tags).
Edge Cases
Missing tags: If a principal or resource does not have a tag referenced in the condition, the condition evaluates to false (access denied).
Multiple tag values: Use ForAllValues:StringEquals to require all tags match, or ForAnyValue:StringEquals to allow if any tag matches.
Cross-account ABAC: Use resource-based policies with aws:PrincipalTag condition keys. The principal's tags are from the other account, so ensure the other account tags its users.
How to Eliminate Wrong Answers
If the question mentions "dynamic access control" or "scalable for many projects", ABAC is likely the answer.
If the question mentions "creating a new role for each project", that's RBAC, which is less scalable.
If an answer uses policy variables in the Resource, it's wrong.
If an answer says "use session tags to override principal tags", that is possible (via sts:TagSession) but not the core ABAC mechanism.
ABAC uses tags to grant permissions based on attributes of the principal, resource, and environment.
Policy variables (e.g., ${aws:PrincipalTag/project}) are only valid in the Condition block, not in Resource or Principal.
When a user assumes an IAM role, the role's tags become the principal tags, not the user's.
Tags are case-sensitive; 'Project=alpha' does not match 'project=alpha'.
ABAC is ideal for environments with many projects and users that change frequently, as it reduces policy maintenance.
Use the IAM policy simulator with context entries to test ABAC policies before deployment.
The maximum number of tags per IAM user/role/resource is 50.
ABAC works with identity-based policies, resource-based policies, and SCPs.
These come up on the exam all the time. Here's how to tell them apart.
ABAC (Attribute-Based Access Control)
Uses tags on principals and resources to determine access.
Single policy can serve many principals and resources by matching attributes.
Scales well in dynamic environments with frequent changes.
No need to create new roles for each project or team.
Policy evaluation uses condition keys like aws:PrincipalTag and aws:ResourceTag.
RBAC (Role-Based Access Control)
Uses roles with predefined permissions; users assume roles.
Each role requires a separate policy; adding new projects may require new roles.
Less scalable when teams and projects change often.
Requires creating and managing multiple roles and trust policies.
Permissions are static; role membership determines access.
Mistake
ABAC policies use policy variables in the Resource element to dynamically construct ARNs.
Correct
Policy variables are only supported in the Condition block, not in the Resource or Principal elements. To use ABAC, you specify a wildcard or specific ARN in Resource, and then use conditions to restrict based on tags.
Mistake
When a user assumes a role, the user's tags are still used for ABAC conditions.
Correct
When a user assumes a role, the principal becomes the role. The role's tags are used, not the user's. If you need to pass tags from the user, use `sts:TagSession` to set session tags, but those are separate from the role's tags.
Mistake
ABAC requires that every principal and resource have exactly the same tag keys and values.
Correct
ABAC policies can be written to match any subset of tags. You can require only one specific tag to match, or multiple tags. The policy defines which tags are checked. Not all tags need to be present; missing tags cause the condition to fail.
Mistake
ABAC is the same as RBAC but uses tags instead of roles.
Correct
RBAC uses roles as the primary mechanism; users assume roles to gain permissions. ABAC uses attributes (tags) directly on the principal and resource, and policies evaluate these attributes at runtime. ABAC does not require role assumption; the principal's own tags are evaluated.
Mistake
You can use ABAC to control access to any AWS service, including services that do not support tagging.
Correct
ABAC relies on tags. If a resource does not support tagging, you cannot use resource tags in conditions. However, you can still use principal tags and request tags for services that support them. Always check service documentation for tag support.
Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.
No, policy variables are only supported in the Condition block. You cannot use ${aws:PrincipalTag/project} in the Resource ARN. Instead, use a wildcard or specific ARN in Resource, and then add a condition that compares tags.
If the principal lacks the tag, the condition evaluates to false, and access is denied. This is because the condition cannot match a non-existent value. Ensure all principals have the required tags.
For cross-account access, you typically use resource-based policies (e.g., S3 bucket policy) that include conditions like `aws:PrincipalTag`. The principal's tags come from the other account. The resource-based policy must allow the principal, and the condition must match the principal's tags.
Yes, you can use ABAC conditions in SCPs to restrict access based on tags across all accounts in the organization. For example, you can deny access to resources that do not have a specific tag, or require that the principal's tag matches the resource's tag.
aws:PrincipalTag refers to tags attached to the IAM user or role making the request. aws:ResourceTag refers to tags on the resource being accessed. Both are used in conditions to compare attributes.
Use the IAM policy simulator with the `--context-entries` parameter to simulate principal and resource tags. For example: `aws iam simulate-custom-policy --policy-input-list file://policy.json --action-names s3:GetObject --resource-arns arn:aws:s3:::bucket/object --context-entries ContextKeyName=aws:PrincipalTag/project,ContextKeyValues=alpha,ContextKeyType=string`.
Session tags are tags that you can pass when assuming a role or federating a user using `sts:TagSession`. These tags are attached to the temporary session and can be used in ABAC conditions. However, they are separate from the role's tags; you can combine them using conditions like `aws:PrincipalTag` (which includes session tags) but note that session tags override role tags if they have the same key.
You've just covered Attribute-Based Access Control (ABAC) in AWS — now see how well it sticks with free DVA-C02 practice questions. Full explanations included, no account needed.
Done with this chapter?