Boundaries, SCPs, and delegation

Lesson 5 of 5 in Policy Evaluation.

Four policy types exist whose only job is to cap. None of them grants anything, all of them can veto, and the exam separates them by three questions: what do they cap, where do they attach, and who do they apply to?

  • Permissions boundary — caps what an identity's own policies can grant. Attached to a user or role.
  • SCP — caps the principals in member accounts. Attached to the organization root, an OU, or an account.
  • RCP — caps access to your resources, whoever is calling. Attached to the organization root, an OU, or an account.
  • Session policy — caps one session. Passed at assume-role time.

The clean way to hold them: a boundary and a session policy are about the principal, from the inside; an SCP is about your principals, from above; an RCP is about your resources, from above. The first three limit what your identities can do. The fourth limits what can be done to your things.

The four capping policy types, side by side
Permissions boundarySCPRCPSession policy

What it caps

What one identity’s policies can grant

What principals in member accounts may do

What may be done to resources in your accounts, by any caller

What one session may do

Where it attaches

An IAM user or role

Organization root, OU, or account

Organization root, OU, or account

Nowhere — passed as a parameter on the STS call

Can it grant?

No

No

No

No

Who it does not apply to

Service-linked roles; it also does not limit access granted to the principal by a resource-based policy

The management account, and service-linked roles

Resources in the management account, service-linked roles, and AWS managed KMS keys (and kms:RetireGrant is unaffected)

Any session you did not pass it to

Typical use

Delegating IAM safely: developers may create roles, but none more powerful than the boundary

Region restriction, denying root actions, blocking services the organization does not use, requiring encryption

A data perimeter: deny all access to your buckets, keys, queues and secrets unless aws:PrincipalOrgID matches, with carve-outs for named AWS service principals

One role, many narrowly-scoped sessions — a multi-tenant broker, or a per-stack pipeline run

Visible to the account admin?

Yes — attached to the entity

Only from the management or delegated-admin account

Only from the management or delegated-admin account

No — it exists only in the code that called AssumeRole

Nested ceilings — read bottom-up; each tier can only lower the one below

  1. Identity and resource policies — the only layer that grants

    Everything a principal can do originates here: an identity-based policy, or — for the services that have one — a resource-based policy. If the Allow is not here, no ceiling above can create it. This is the tier people edit when they should be looking upward.

  2. Session policy — this session only, passed at runtime

    The narrowest and shortest-lived ceiling: intersection with the role’s policy, for one session. Because it is invisible afterwards, a denial it causes is diagnosed by reading the calling code, not the IAM console.

  3. Permissions boundary — attached to the user or role

    A durable cap on what the identity’s own policies can grant. Effective permissions = identity policy ∩ boundary. It does not limit what a resource-based policy grants to the principal, and it does not apply to service-linked roles.

  4. Service control policy — organization-wide, on your principals

    The account-level ceiling. Every request by a principal in a member account must survive every SCP in its OU path. It does not touch the management account or service-linked roles — which is exactly why the management account should hold no workloads.

  5. Resource control policy — organization-wide, on your resources

    The newest tier, and the other direction: it constrains access to your resources whoever the caller is, including principals outside your organization. The canonical use is a data perimeter — deny unless aws:PrincipalOrgID matches, with carve-outs for named AWS service principals. Resources in the management account are excluded.

The pattern that makes permissions boundaries worth the trouble is safe delegation of IAM. The problem: developers need to create roles for their Lambda functions and ECS tasks, but iam:CreateRole plus iam:AttachRolePolicy is effectively administrator access — they would simply create a role with AdministratorAccess and assume it. The answer is not to refuse; it is to require that every role they create carries a boundary you control.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CreateRolesOnlyWithTheBoundary",
      "Effect": "Allow",
      "Action": ["iam:CreateRole", "iam:PutRolePermissionsBoundary"],
      "Resource": "arn:aws:iam::111122223333:role/teams/payments/*",
      "Condition": {
        "StringEquals": {
          "iam:PermissionsBoundary": "arn:aws:iam::111122223333:policy/TeamBoundary"
        }
      }
    },
    {
      "Sid": "ManagePoliciesOnThoseRolesOnly",
      "Effect": "Allow",
      "Action": ["iam:AttachRolePolicy", "iam:PutRolePolicy", "iam:DeleteRole", "iam:PassRole"],
      "Resource": "arn:aws:iam::111122223333:role/teams/payments/*"
    },
    {
      "Sid": "NeverRemoveOrEditTheBoundary",
      "Effect": "Deny",
      "Action": [
        "iam:DeleteRolePermissionsBoundary",
        "iam:CreatePolicyVersion",
        "iam:SetDefaultPolicyVersion",
        "iam:DeletePolicy"
      ],
      "Resource": [
        "arn:aws:iam::111122223333:role/teams/payments/*",
        "arn:aws:iam::111122223333:policy/TeamBoundary"
      ]
    }
  ]
}

Four things are doing work here. The condition on iam:PermissionsBoundary means a CreateRole call that does not attach your boundary simply fails — the developer cannot create an unbounded role. The IAM path role/teams/payments/* confines them to their own namespace, so they cannot modify the security team's roles. The Deny on iam:DeleteRolePermissionsBoundary stops them from removing the cap afterwards. And the Deny on the boundary policy's own versions stops them from editing the boundary into something permissive — the escalation path people forget.

The same shape appears in exam stems as "allow the team to manage their own roles without being able to escalate". The answer is always: boundary, required by condition, plus path scoping, plus a deny on tampering.

Why SCPs do not protect the management account

SCPs affect only IAM users and roles in member accounts. The management account is explicitly out of scope, so an SCP denying ec2:* across the organization does not stop the management account from launching instances, and its root user remains unrestricted. The architectural consequence is the one the exam cares about: put no workloads in the management account, and give it only organization administration. Service-linked roles are also exempt, which is how AWS services keep functioning under restrictive SCPs.

The RCP exclusion list, precisely

RCPs do not restrict: any action on resources in the management account; the effective permissions of any service-linked role (including its trust policy); AWS managed KMS keys; and kms:RetireGrant. There is also a structural difference from SCPs that the exam can turn into a question: an SCP applies across all AWS services, while an RCP applies only to the services that support it — a large and steadily growing subset as of October 2026, so confirm the current list in the AWS Organizations documentation before designing a perimeter that depends on a particular service being covered. Like SCPs, RCPs grant nothing: you still need identity or resource policies to allow the access.

What a boundary does not cap

A permissions boundary limits what the identity-based policies attached to that principal can grant. It does not limit permissions granted to the principal by a resource-based policy — a bucket policy naming the role still works, even for an action outside the boundary. It also does not apply to service-linked roles. Those two exceptions are the honest limits of boundaries as a containment control, and they are worth knowing before you promise an auditor a boundary is a hard ceiling.

Allow-list versus deny-list SCPs

Two authoring styles. Deny-list keeps the default FullAWSAccess attached and adds Deny statements — simple, composable, and the common choice. Allow-list replaces FullAWSAccess with a policy naming only permitted services; stricter, but every new service needs a policy change and every OU in the path must allow the action, which makes inheritance easy to get wrong. The exam usually expects a deny-list with condition keys (aws:RequestedRegion, ec2:Encrypted, aws:PrincipalArn exclusions for break-glass roles).

Key terms: Permissions boundary, Service control policy (SCP), Resource control policy (RCP), Session policy, IAM path

Interactive checkpoint quiz (2 questions) — open this page in a browser to take it.