9.2 Permission Boundaries & Safe Admin Delegation

Key Takeaways

  • Safe delegation allows engineering and DevOps teams to create and manage application IAM roles autonomously without granting full administrative privileges or risking privilege escalation.

  • To prevent privilege escalation, delegated role creation must enforce the iam:PermissionsBoundary condition key on iam:CreateRole, iam:CreateUser, iam:PutRolePolicy, and iam:AttachRolePolicy.

  • Anti-tampering guardrails must explicitly deny delegated administrators the ability to delete or modify the boundary policy (iam:DeleteRolePermissionsBoundary, iam:CreatePolicyVersion, iam:DeletePolicy).

  • Permission boundaries define the maximum permissions ceiling for IAM identities but never grant permissions directly; an identity-based policy is still required to perform actions.

  • Permission boundaries never grant access. In the same account they also limit resource-based policies that name the role ARN, but not grants to an IAM user ARN or role session ARN, and they can't be attached to the root user or service-linked roles.

Last updated: September 2026

9.2 Permission Boundaries & Safe Admin Delegation

In modern cloud engineering, modernizing deployment velocity requires decentralizing administrative tasks. Continuous integration and continuous delivery (CI/CD) pipelines, serverless architectures, and containerized microservices frequently require creating new IAM roles for AWS Lambda functions, Amazon ECS tasks, and automated deployment jobs. However, granting engineers unrestricted iam:CreateRole and iam:AttachRolePolicy permissions introduces catastrophic privilege escalation risks.

An IAM Permission Boundary is an advanced authorization control that establishes the absolute maximum permissions an identity-based policy can grant to an IAM entity. By pairing permission boundaries with conditioned IAM policies, enterprise security teams achieve safe administrative delegation—allowing developers to provision and manage their own application roles without the ability to escalate privileges to full account administrator.


The Delegation Dilemma & Privilege Escalation Vectors

When security teams attempt to delegate role creation naively, they encounter a critical vulnerability: the Unbounded Role Creation Exploit.

Consider an IAM policy that allows a developer to perform iam:CreateRole and iam:AttachRolePolicy so they can configure IAM roles for their microservices. Without boundary guardrails, the developer can execute the following privilege escalation sequence:

Loading diagram...
  1. The developer invokes iam:CreateRole to create an arbitrary role named BackdoorAdminRole with a trust policy allowing themselves to assume it.
  2. The developer invokes iam:AttachRolePolicy, attaching the AWS-managed AdministratorAccess policy to BackdoorAdminRole.
  3. The developer assumes BackdoorAdminRole using sts:AssumeRole.
  4. The developer now possesses unrestricted *:* administrative permissions, bypassing all original organizational constraints, altering audit logs, or modifying production infrastructure.

To prevent this, security architects implement Permission Boundaries as non-bypassable guardrails.


Mechanics of IAM Permission Boundaries

A permission boundary is a standard customer-managed IAM policy that is applied to an IAM user or role to define its maximum allowable permissions. It does not grant permissions by itself; rather, it functions as an authorization filter.

Loading diagram...

Mathematical Intersection Model

The effective permissions of any principal subject to a permission boundary represent the strict intersection of the identity-based policy and the boundary:

Effective Permissions = Identity Policy ∩ Permission Boundary

  • If an action is permitted by the identity policy but omitted from the boundary, the action is implicitly denied.
  • If an action is permitted by the boundary but omitted from the identity policy, the action is implicitly denied.
  • If an action is explicitly denied in either the identity policy or the boundary, the action is explicitly denied.
  • Both policies must explicitly allow the action for access to be granted.

The Three-Tier Safe Delegation Architecture

Enterprise delegation relies on a synchronized three-tier policy framework comprising the Delegator Policy, the Permission Boundary Policy, and the Delegated Workload Policy:

Loading diagram...

1. The Delegator Policy (Attached to DevOps Engineers)

The Delegator Policy grants developers the ability to create roles, attach policies, and pass roles to compute services, but conditions those actions strictly on the presence of the boundary policy.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowRoleCreationWithBoundary",
      "Effect": "Allow",
      "Action": [
        "iam:CreateRole"
      ],
      "Resource": "arn:aws:iam::111122223333:role/app-roles/*",
      "Condition": {
        "StringEquals": {
          "iam:PermissionsBoundary": "arn:aws:iam::111122223333:policy/AppPermissionBoundary"
        }
      }
    },
    {
      "Sid": "AllowPolicyAttachmentToBoundedRoles",
      "Effect": "Allow",
      "Action": [
        "iam:AttachRolePolicy",
        "iam:PutRolePolicy",
        "iam:DetachRolePolicy",
        "iam:DeleteRolePolicy"
      ],
      "Resource": "arn:aws:iam::111122223333:role/app-roles/*",
      "Condition": {
        "StringEquals": {
          "iam:PermissionsBoundary": "arn:aws:iam::111122223333:policy/AppPermissionBoundary"
        }
      }
    },
    {
      "Sid": "PreventBoundaryTampering",
      "Effect": "Deny",
      "Action": [
        "iam:DeleteRolePermissionsBoundary",
        "iam:PutRolePermissionsBoundary",
        "iam:DeleteUserPermissionsBoundary",
        "iam:PutUserPermissionsBoundary"
      ],
      "Resource": "*"
    },
    {
      "Sid": "PreventBoundaryPolicyModification",
      "Effect": "Deny",
      "Action": [
        "iam:CreatePolicyVersion",
        "iam:DeletePolicyVersion",
        "iam:DeletePolicy",
        "iam:SetDefaultPolicyVersion"
      ],
      "Resource": "arn:aws:iam::111122223333:policy/AppPermissionBoundary"
    },
    {
      "Sid": "AllowPassRoleToApprovedServices",
      "Effect": "Allow",
      "Action": "iam:PassRole",
      "Resource": "arn:aws:iam::111122223333:role/app-roles/*",
      "Condition": {
        "StringEqualsIfExists": {
          "iam:PassedToService": [
            "lambda.amazonaws.com",
            "ecs-tasks.amazonaws.com"
          ]
        }
      }
    }
  ]
}

Critical Policy Statement Rationale

  • Statement 1 (AllowRoleCreationWithBoundary): Allows iam:CreateRole strictly under the path /app-roles/* and enforces the iam:PermissionsBoundary condition key. If a developer attempts to run aws iam create-role without --permissions-boundary, the API call fails immediately with AccessDenied.
  • Statement 2 (AllowPolicyAttachmentToBoundedRoles): Restricts policy attachment. Even if a role was created with a boundary, developers must not be allowed to attach policies to unbounded roles (such as existing security administration roles).
  • Statement 3 (PreventBoundaryTampering): Explicitly denies removing or changing the boundary once a role is created.
  • Statement 4 (PreventBoundaryPolicyModification): Crucial security safeguard. If a developer has permission to create a new default policy version (iam:CreatePolicyVersion) for the boundary policy, they could simply edit the boundary to allow *:*. Denying modification APIs on the boundary ARN closes this backdoor.
  • Statement 5 (AllowPassRoleToApprovedServices): Restricts iam:PassRole so developers can only pass bounded roles to specific services like AWS Lambda and Amazon ECS, preventing them from passing roles to unauthorized compute instances.

2. The Permission Boundary Policy (AppPermissionBoundary)

The boundary policy defines the broad capabilities application workloads are permitted to use, while establishing permanent enterprise guardrails:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowApplicationServices",
      "Effect": "Allow",
      "Action": [
        "s3:*",
        "dynamodb:*",
        "sqs:*",
        "sns:*",
        "logs:*"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DenySecurityServicesModification",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:DeleteTrail",
        "cloudtrail:StopLogging",
        "cloudtrail:UpdateTrail",
        "guardduty:DeleteDetector",
        "guardduty:DisassociateFromMasterAccount",
        "securityhub:DisableSecurityHub",
        "config:DeleteConfigRule"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DenyIAMManagement",
      "Effect": "Deny",
      "Action": [
        "iam:*",
        "organizations:*"
      ],
      "Resource": "*"
    }
  ]
}

Even if a developer attaches AdministratorAccess (*:*) to an application role, the role can never modify CloudTrail, disable GuardDuty, alter AWS Config rules, or execute IAM API calls because those actions are explicitly denied by the boundary.


Boundary Limitations & Architectural Edge Cases

Understanding where permission boundaries do not apply is a major focus of specialty certification scenarios:

  1. Resource-Based Policies Depend on the Principal Named: In the same account, a bucket or queue policy that names the role ARN is still limited by the role's boundary. A policy that names a role session ARN or an IAM user ARN grants access directly, even if the boundary omits the service. Cross-account access always needs the boundary (and identity policy) to allow the action.
  2. Boundaries Do Not Grant Access: Attaching a permission boundary granting s3:* to a role that has no identity policies attached results in zero access. A matching identity-based policy must be attached.
  3. Root User and Service-Linked Roles: Permission boundaries cannot be attached to the AWS account root user, nor do they apply to AWS service-linked roles created by AWS services to manage infrastructure.
  4. Cross-Account Roles: When a principal in Account A assumes a cross-account role in Account B, any permission boundary attached to the principal in Account A has no effect on actions performed in Account B. The role in Account B is evaluated based on its own policies and any boundary attached directly to the Account B role.

Specialty Exam Pitfalls & Architectural Traps

  1. The Policy Versioning Escalation Trap: When constructing delegation policies, never grant iam:CreatePolicyVersion on all policies. If a delegated user has iam:CreatePolicyVersion on *, they can update the boundary policy itself to add AdministratorAccess, bypassing all protections. Always deny policy versioning and deletion on the boundary policy ARN.
  2. The iam:PassRole Without Boundary Trap: Granting iam:PassRole with Resource: "*" allows an engineer to create a Lambda function or EC2 instance and attach a pre-existing administrative role (e.g., OrganizationAccountAccessRole), thereby executing arbitrary code as full administrator. Always restrict iam:PassRole to roles within the approved path /app-roles/* that carry the boundary.
  3. Confusing Permission Boundaries with SCPs: Service Control Policies apply account-wide across all principals (except the management account) and are managed at the AWS Organizations level. Permission boundaries are attached individually to specific IAM users and roles within an account. SCPs enforce compliance across accounts; boundaries enable safe delegation within an account.
  4. The iam:PutRolePolicy Backdoor: Security engineers often enforce boundaries on iam:CreateRole but forget to condition iam:PutRolePolicy (inline policies) and iam:AttachRolePolicy (managed policies). Without conditioning policy attachment APIs, an engineer can create a bounded role, delete its boundary (if not denied), or attach policies to unmonitored existing roles.
Loading diagram...
Safe IAM Delegation Workflow & Permission Boundary Ceiling
Test Your Knowledge

A security architect must delegate IAM role creation to a software development team so they can provision roles for AWS Lambda functions and Amazon ECS tasks. The security policy dictates that developers must never be able to grant permissions beyond Amazon S3, Amazon DynamoDB, and Amazon SQS, and must never be able to escalate their own privileges. Which implementation strategy satisfies these requirements?

A

Create an IAM user group for developers with an attached policy allowing iam:* on Resource: arn:aws:iam:::role/dev-, and use AWS CloudTrail to alert security if admin policies are attached.

B

Create a Customer Managed Policy defining the maximum allowed permissions for S3, DynamoDB, and SQS. Attach an IAM policy to developers allowing iam:CreateRole with a StringEquals condition requiring the iam:PermissionsBoundary to match the managed policy ARN, and deny iam:DeleteRolePermissionsBoundary.

C

Configure a Service Control Policy (SCP) on the development Organizational Unit allowing only S3, DynamoDB, and SQS actions, and grant developers unrestricted iam:CreateRole permissions.

D

Require developers to write AWS CloudFormation templates in a private Git repository, and configure a central administrator to manually review and deploy all role resources.

Test Your Knowledge

A developer has been granted delegated IAM role management permissions protected by an IAM Permission Boundary named 'DevAppBoundary'. The developer's IAM user policy contains statements allowing iam:CreateRole and iam:AttachRolePolicy conditioned on the boundary ARN, and explicitly denies iam:DeleteRolePermissionsBoundary. However, the developer discovers they can still escalate privileges to full account administrator. Which missing restriction allowed this privilege escalation?

A

The developer policy omitted an explicit Deny for sts:AssumeRole on roles outside the development path.

B

The developer policy did not include an AWS Organizations SCP preventing account modification.

C

The permission boundary policy did not include an explicit Allow statement for AWS CloudTrail.

D

The developer policy allowed iam:CreatePolicyVersion and iam:SetDefaultPolicyVersion on the DevAppBoundary policy ARN.

Test Your Knowledge

An enterprise microservice runs as an Amazon ECS task with an attached task role. The task role has an IAM permissions boundary that allows Amazon DynamoDB and Amazon SQS operations but omits Amazon S3, and its identity-based policy allows s3:GetObject. The microservice downloads configuration objects from an Amazon S3 bucket in the same AWS account. The bucket policy grants s3:GetObject with Principal set to the task role's ARN (arn:aws:iam::111122223333:role/ConfigReaderTaskRole). What is the outcome when the microservice calls s3:GetObject?

A

The request succeeds because permissions boundaries only filter identity-based policies and never restrict permissions granted by resource-based policies.

B

The request fails with AccessDenied because a resource-based policy that grants access to an IAM role ARN is still limited by an implicit deny in that role's permissions boundary.

C

The request fails because cross-service access between ECS and S3 requires an IAM role trust policy modification.

D

The request succeeds only if the Amazon S3 bucket policy contains a PrincipalOrgID condition key matching the organization.

Test Your Knowledge

A DevOps engineer creates a new IAM role for a data processing Lambda function. The engineer attaches an identity-based policy granting full Amazon EC2 and Amazon S3 permissions (ec2:* and s3:). As mandated by security governance, the engineer attaches a permission boundary policy named 'DataBoundary' that allows only s3:GetObject, s3:PutObject, and dynamodb:. When the Lambda function runs, it attempts to execute s3:PutObject and ec2:DescribeInstances. Which actions will be permitted?

A

Both s3:PutObject and ec2:DescribeInstances will be permitted because identity-based policies define active grants.

B

Neither action will be permitted because the permission boundary does not include ec2:*.

C

Only s3:PutObject will be permitted, while ec2:DescribeInstances will be implicitly denied.

D

Only ec2:DescribeInstances will be permitted, while s3:PutObject will be denied because S3 requires bucket policies.

Sections you finish are checked off in the contents.