Identity and Access Management · Topic 5 of 6

Conditions, ABAC and Delegation

Write precise IAM policies with condition keys, set operators, tag based access control, permission boundaries for delegation and PassRole limits.

  • 5 min
In a nutshell
  • Conditions combine with AND across keys and OR across values of one key.
  • IfExists handles missing keys, and ForAllValues can pass for an empty set, so use it with care.
  • aws:PrincipalOrgID simplifies cross account allow policies for a whole organization.

What it is

Conditions make a policy statement apply only in certain situations, such as from a specific network, with MFA, or when a resource tag matches a principal tag. They turn a broad permission into a precise one without writing a statement per resource.

This page covers the condition language, attribute based access control (ABAC), and how to let teams create their own roles safely.

Principaltags: project Alphacompared withConditionPrincipalTag equals ResourceTagResourcetags: project AlphaAllowedsame project

How it works

Condition structure

A condition block has an operator, a key and one or more values.

"Condition": {
  "StringEquals": { "aws:RequestedRegion": ["eu-west-1", "eu-central-1"] },
  "Bool": { "aws:SecureTransport": "true" }
}

The logic rules are easy to test.

  • Several operators or keys in one block combine with AND.
  • Several values for one key combine with OR.
  • Add IfExists to an operator to treat a missing key as a match, which matters in deny statements.
  • ForAnyValue and ForAllValues apply to keys with multiple values. ForAllValues is true when the key is absent or empty, so combine it with a check that the key exists.
  • Negated operators such as StringNotEquals in a deny statement are a common way to write an exception.

Useful global condition keys

KeyUse
aws:PrincipalOrgIDAllow only principals in your organization
aws:ResourceOrgIDAllow access only to resources in your organization
aws:SourceIp, aws:SourceVpc, aws:SourceVpceLimit by network location, not valid through service calls on your behalf
aws:RequestedRegionLimit which Regions can be used
aws:SecureTransportRequire TLS
aws:MultiFactorAuthPresentRequire MFA
aws:PrincipalTag/key, aws:ResourceTag/key, aws:RequestTag/keyABAC
aws:SourceArn, aws:SourceAccountStop the confused deputy problem for service principals
aws:ViaAWSService, aws:PrincipalIsAWSServiceAllow or exclude calls made by AWS services on your behalf
aws:CalledViaRestrict to calls made through a specific service

Network keys such as aws:SourceIp apply to the original caller. If an AWS service makes a call on the caller's behalf, the source is the service, so a deny based on IP can break service integrations unless you add aws:ViaAWSService.

Attribute based access control

ABAC grants access when tags match, so permissions scale without editing policies. One policy serves every project.

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": ["ec2:StartInstances", "ec2:StopInstances"],
    "Resource": "arn:aws:ec2:*:*:instance/*",
    "Condition": { "StringEquals": { "aws:ResourceTag/project": "${aws:PrincipalTag/project}" } }
  }]
}

A user tagged project=Alpha can start and stop only instances tagged project=Alpha. New projects need only new tags.

Compare the two models.

ModelStrengthWeakness
RBAC (role based)Simple to understand, one role per jobRoles multiply as teams and projects grow
ABAC (tag based)Scales with tags, fewer policiesDepends on tag governance and tag protection

ABAC fails if people can change tags. Protect tag keys used for authorisation, by denying tag changes except for a trusted role, and use aws:RequestTag and aws:TagKeys to control tagging at creation. Identity Center and federation can pass user attributes as session tags to feed the principal tag.

Safe delegation with permissions boundaries

Developers often need to create roles for their applications, but they must not create roles that exceed their own limits. Combine a permissions boundary with a condition on role creation.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["iam:CreateRole", "iam:AttachRolePolicy", "iam:PutRolePolicy"],
      "Resource": "arn:aws:iam::111122223333:role/app-*",
      "Condition": { "StringEquals": { "iam:PermissionsBoundary": "arn:aws:iam::111122223333:policy/DevBoundary" } }
    },
    {
      "Effect": "Deny",
      "Action": ["iam:DeleteRolePermissionsBoundary", "iam:DeleteUserPermissionsBoundary"],
      "Resource": "*"
    }
  ]
}

The first statement allows role creation only when the boundary is attached, and the second stops the boundary being removed. Developers can then create roles within the limit and cannot escape it.

Controlling PassRole

iam:PassRole lets a principal give a role to a service. Without limits, a user can pass an administrator role to a Lambda function or EC2 instance and use it to escalate. Limit the resource to specific role ARNs, and use iam:PassedToService to name the service.

{
  "Effect": "Allow",
  "Action": "iam:PassRole",
  "Resource": "arn:aws:iam::111122223333:role/app-lambda-*",
  "Condition": { "StringEquals": { "iam:PassedToService": "lambda.amazonaws.com" } }
}

Data perimeter conditions

A resource policy can restrict a bucket to your organization with aws:PrincipalOrgID, and an identity policy or SCP can limit users to resources in your organization with aws:ResourceOrgID. Together with network conditions, these form a perimeter that keeps data in and untrusted identities out.

What to remember for the exam

  • Conditions combine with AND across keys and OR across values of one key.
  • IfExists handles missing keys, and ForAllValues can pass for an empty set, so use it with care.
  • aws:PrincipalOrgID simplifies cross account allow policies for a whole organization.
  • ABAC compares aws:PrincipalTag and aws:ResourceTag, and needs strict control of who can change tags.
  • Permissions boundaries with an iam:PermissionsBoundary condition allow safe delegation of role creation.
  • Limit iam:PassRole by resource and with iam:PassedToService.
  • aws:SourceArn and aws:SourceAccount prevent the confused deputy problem for service principals.
  • aws:SourceIp does not describe the real client when an AWS service calls on your behalf.
Exam tip

When a question asks to scale permissions as teams and projects grow with minimal policy changes, ABAC with tags is the usual answer.

Common mistakes

Letting users edit the tags that grant access. An attacker can retag themselves into another project.

Using a plain deny on aws:SourceIp. AWS services calling for you fail, so add exceptions for service calls.

Granting iam:PassRole on all roles. This is a classic privilege escalation path.

Relying on ForAllValues alone. It is true for an empty set, so the check can pass when it should not.

Watch out

A boundary does not stop a user from granting access through a resource policy or other paths outside IAM identity policies, so combine boundaries with SCPs and careful delegation.

Check yourself

  • How do you let a developer create roles but only with a boundary?

    Allow iam:CreateRole with a condition that iam:PermissionsBoundary equals the required boundary, and deny removal of the boundary.

  • What does aws:PrincipalOrgID do in a bucket policy?

    It allows access only to principals that belong to the named AWS Organization, without listing each account.

  • Why protect the tags used by ABAC?

    If principals can change tags, they can give themselves access to other projects.

Topic 5 of 6 in Identity and Access Management

Test yourself on Identity and Access Management

The full AWS SCS-C03 question bank has 858 questions, with timed practice exams and an explanation for every answer.

This study guide is independent and is not affiliated with, endorsed by, or sponsored by AWS. Vendor names, certification names and exam codes are trademarks of their respective owners and are used for identification only.