All notes

“Allowed by the SCP” does not mean “allowed”

A service control policy defines the maximum permissions available inside an AWS member account. An action passing the SCP layer still needs a valid grant path and must survive every other applicable permission limit and explicit deny.

about 16 minutes min read

An engineer assumes a role in an AWS member account.

The account sits beneath an organisational unit with the AWS-managed FullAWSAccess service control policy attached.

The engineer tries to list an S3 bucket.

AWS returns:

AccessDenied

The first reaction may be:

But S3 is allowed by the SCP.

That statement can be completely true.

The request can still be denied.

The misunderstanding comes from treating an SCP as a permission grant.

It is not one.

A service control policy defines the maximum permissions that may remain available to principals in affected AWS member accounts. It does not grant those permissions.

The request still needs an applicable grant path, such as an identity-based policy or resource-based policy. It must also survive every applicable limiting policy, explicit deny, request condition and service-specific rule.

“Allowed by the SCP” means the organisation has left the action inside the permitted ceiling. It does not mean the caller has been authorised to perform it.

An SCP answers:

May this action remain available
inside this organisational scope?

It does not answer:

May this principal perform
this action on this resource
under these conditions now?

That second question belongs to the complete AWS authorization system.

Authorization needs a grant path

AWS requests begin without permission.

Some applicable policy path must grant the requested action.

Possible grant sources include:

IDENTITY-BASED POLICY

permission granted to
a user, role or session


RESOURCE-BASED POLICY

permission granted by
the target resource

The request may then be restricted by:

PERMISSIONS BOUNDARY

maximum identity permission


SESSION POLICY

maximum permission for
this temporary session


SCP

maximum permission available
to affected member-account principals


RCP

maximum permission accepted
by supported resources

An explicit deny in any applicable policy overrides a matching allow.

The complete model is therefore not one fixed pipeline.

                         REQUEST CONTEXT
                               │
              ┌────────────────┼────────────────┐
              │                │                │
              ▼                ▼                ▼
        GRANT SOURCES       LIMITERS      EXPLICIT DENIES
              │                │                │
              ├── identity     ├── boundary     ├── identity
              └── resource     ├── session      ├── resource
                               ├── SCP          ├── boundary
                               └── RCP          ├── session
                                                ├── SCP
                                                └── RCP
              │                │                │
              └────────────────┼────────────────┘
                               ▼
                    SERVICE-SPECIFIC EVALUATION
                               │
                      ┌────────┴────────┐
                      ▼                 ▼
                   ALLOWED            DENIED

The principal type, account relationship, resource and service determine exactly how these policy categories combine.

Identity and resource policies may form a grant path.

Limiting policies generally intersect with that path.

Explicit denies remain decisive.

No single green light necessarily represents the final decision.

An SCP is a filter, not a grant

Consider an SCP containing:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}

The policy leaves S3 actions available within its scope.

It does not give an IAM role permission to use S3.

Suppose the role has no identity-based S3 permission and no applicable resource-based grant.

SCP:
    S3 remains available

Grant path:
    no S3 permission

Result:
    denied

The SCP does not fill the missing permission.

It merely refrains from removing it.

What the SCP layer actually decides

FullAWSAccess does not mean administrator access

When SCPs are enabled, AWS Organizations uses an AWS-managed policy named FullAWSAccess.

Its purpose is to leave services and actions available at the SCP layer until the organisation introduces narrower controls.

It does not mean:

Every principal has
full AWS access.

It means:

The SCP layer is not currently
filtering AWS actions out of
the maximum available set.

An IAM role with no policies still has no useful authority.

A role allowed only to read CloudWatch metrics remains limited to those actions.

A role with broad IAM permissions may exercise broad authority because the SCP is not narrowing it, but the authority comes from IAM.

SCP Grant path Result
FullAWSAccess No S3 grant S3 request denied
FullAWSAccess Allow s3:GetObject Request may proceed
Deny s3:GetObject Allow s3:GetObject Request denied
Allow only S3 Allow EC2 administration EC2 request denied
Allow only S3 Allow s3:GetObject S3 request may proceed

“May proceed” matters.

Another boundary, resource condition, RCP or explicit deny may still block the request.

An explicit deny wins

Suppose a role has IAM permission to create an internet gateway.

{
  "Effect": "Allow",
  "Action": "ec2:CreateInternetGateway",
  "Resource": "*"
}

The Production OU has an SCP denying the action.

{
  "Effect": "Deny",
  "Action": "ec2:CreateInternetGateway",
  "Resource": "*"
}

The result is denial.

The account administrator cannot repair it by attaching a broader IAM policy.

They cannot grant authority beyond the organisational ceiling.

The deny belongs to a higher administrative boundary.

SCP allows must survive the hierarchy

SCPs may be attached to:

  • the organisation root
  • parent OUs
  • child OUs
  • an individual member account

Under an allow-list strategy, the action needs appropriate allow coverage throughout the applicable path.

Root:
    allows S3

Workloads OU:
    allows S3

Production OU:
    does not allow S3

bfstore-prod:
    allows S3

S3 remains unavailable in bfstore-prod.

The account-level allow cannot reopen an action filtered out by an ancestor.

For deny statements, one applicable deny along the path is enough to block the request.

The tree is part of permission evaluation.

Check whether the SCP applies

SCPs constrain principals in affected member accounts, including their root users.

They do not constrain users or roles in the management account.

They also do not restrict service-linked roles.

AWS documents a small number of additional exceptions for specific tasks.

A troubleshooting check should therefore begin with:

Is the principal in
an affected member account?

Is it using a
service-linked role?

Is this one of the documented
SCP exceptions?

A correct SCP cannot explain a request made by a principal outside its scope.

First obtain the session, then authorize the action

Role assumption and the eventual service request are separate authorization events.

Event one: obtain temporary credentials

AssumeRole
    │
    ├── caller permission
    ├── target trust policy
    ├── request conditions
    └── optional session policy
        │
        ▼
temporary credentials

The caller may need permission to request the role.

The target role must trust the caller and request context.

If assumption succeeds, AWS issues a role session.

Event two: use the session

Service API request
    │
    ├── session principal
    ├── identity or resource grant
    ├── permissions boundary
    ├── session limit
    ├── SCP and RCP
    └── service-specific rules

The trust policy usually explains whether the session could be created.

It does not normally explain why a later S3, CloudWatch or EKS request failed after assumption succeeded.

Troubleshooting should ask two different questions:

Could the principal
obtain the session?

and:

Could that session
perform the action?

Why an SCP-allowed request still fails

The permission was never granted

The simplest case is a missing grant.

SCP:
    action remains available

Identity or resource policy:
    no applicable allow

Result:
    denied

The SCP allow keeps permission possible.

It does not create it.

The permissions boundary is narrower

Suppose the role policy allows:

s3:GetObject
s3:PutObject

Its permissions boundary allows only:

s3:GetObject

The effective identity permission is narrower.

ROLE POLICY

GetObject
PutObject


BOUNDARY

GetObject


EFFECTIVE IDENTITY PERMISSION

GetObject

The SCP has not denied PutObject.

The role boundary has prevented the identity policy from granting it.

These layers solve different problems:

ORGANISATION CEILING

what affected principals
may ever be allowed to do


ROLE CEILING

what this IAM identity
may ever be allowed to do


IDENTITY POLICY

what the identity is
currently granted

The session is narrower

A role may support broad operations.

A particular temporary session may receive a session policy that narrows it.

ROLE

read and limited mutation


INVESTIGATION SESSION

read-only

The SCP may leave mutation available.

This session still cannot use it.

The resource rejects the request

A resource policy may grant or deny access directly on resources such as:

  • S3 buckets
  • KMS keys
  • SQS queues
  • Secrets Manager secrets
  • IAM roles

A clear explicit-deny example is:

SCP:
    S3 remains available

Identity policy:
    GetObject allowed

Bucket policy:
    explicitly denies requests
    outside the approved VPC endpoint

Request:
    uses another endpoint

Result:
    denied

For cross-account access, the target resource may also need to grant the caller account or principal.

SCP:
    S3 remains available

Caller policy:
    GetObject allowed

Target bucket policy:
    no cross-account grant

Result:
    denied

The SCP does not certify that the resource accepts the caller.

An RCP limits the resource

A resource control policy can constrain access to supported resources in member accounts.

The caller may have an identity grant.

The SCP may leave the action available.

The resource may still sit beneath an RCP that does not allow the request.

The final result is denial.

A bfstore example

Mariam uses an IAM Identity Center permission set named:

ProductionInvestigator

The generated role in bfstore-prod has identity permissions allowing:

  • CloudWatch log reads
  • read-only EKS inspection
  • deployment-history reads
  • selected service descriptions

The role has a permissions boundary that leaves those investigation actions available but does not allow:

  • secret-value retrieval
  • IAM mutation
  • infrastructure deletion

The Production OU has SCPs that leave the investigation services available but explicitly deny:

  • disabling central logging
  • leaving approved Regions
  • changing organisation-managed security configuration

The session lasts one hour.

A request to view application logs can succeed because:

Identity policy:
    allows log read

Permissions boundary:
    leaves log read available

SCP:
    leaves log read available

No applicable explicit deny:
    found

A request to retrieve a production database password fails because the permissions boundary does not allow that action.

A request to disable central logging fails because the SCP explicitly denies it.

A request to delete an EKS cluster fails because no identity grant provides that permission.

DELETE CLUSTER

denied because no grant exists


READ DATABASE PASSWORD

denied because the boundary
does not leave it available


DISABLE CENTRAL LOGGING

denied by the SCP

The user sees three denials.

They come from three different policy layers.

Calling all three “an SCP problem” would send the investigation into the wrong cupboard.

Diagnose the failed request

When AWS returns AccessDenied, start with the complete error.

For many requests, AWS may provide additional context such as:

no identity-based policy allows

explicit deny in an SCP

no SCP allows

permissions-boundary denial

session-policy denial

RCP denial

Enhanced messages are useful evidence.

They are not universal. Some services and cross-account scenarios provide less detail.

Then follow the request.

Identify the authorization event

Did role assumption fail?

or

Did a later service action fail?

Identify the principal

  • Which user, role or session made the request?
  • Is it the expected identity?
  • Which account owns it?
  • Does an SCP apply to that principal category?

Identify the action and resource

  • Which exact API action failed?
  • Which resource was targeted?
  • Which Region and request conditions applied?

Find the grant path

  • Does an identity policy allow the action?
  • Does a resource policy provide a required grant?
  • For role assumption, does the trust policy accept the caller?

Check limiting layers

  • Which permissions boundary applies?
  • Was a session policy supplied?
  • Which SCPs apply from root to account?
  • Does an RCP affect the target resource?

Look for explicit denies

Check applicable:

  • identity policies
  • resource policies
  • boundaries
  • session policies
  • SCPs
  • RCPs

Check service-specific requirements

Some services require additional permissions, key policies, resource grants or conditions that are not obvious from the original API call.

WHICH EVENT FAILED?
    │
    ▼
WHO CALLED?
    │
    ▼
WHAT ACTION AND RESOURCE?
    │
    ▼
WHERE IS THE GRANT?
    │
    ▼
WHICH LIMITS APPLY?
    │
    ▼
IS THERE AN EXPLICIT DENY?

This is slower than blaming the SCP immediately.

It is considerably faster than editing the wrong policy six times.

Prove the intended policy behaviour

Policy-analysis tools are useful.

They do not reproduce every AWS authorization path.

Simulation may have limitations involving:

  • cross-account access
  • resource-based role permissions
  • SCP conditions
  • RCPs
  • service-specific authorization
  • the real runtime and request context
SIMULATOR

useful for selected
policy reasoning


REPRESENTATIVE TEST

required for complete
authorization behaviour

An SCP test should define both:

EXPECTED SUCCESS

operation should remain possible

and:

EXPECTED DENIAL

operation must remain unavailable

A useful test records:

  • principal
  • account
  • OU path
  • action
  • resource
  • request context
  • expected result
  • observed result
  • relevant grant
  • relevant SCP or RCP
  • other limiting policies

This separates two questions:

  1. Did the SCP leave or remove the action as intended?
  2. Did the complete authorization system produce the expected final decision?

A failed success test may indicate a missing identity grant rather than a broken SCP.

An unexpectedly successful denial test may indicate that the wrong principal, account, resource or condition was exercised.

Important policy changes should therefore move through:

STATIC ANALYSIS
      │
      ▼
POLICY REASONING
      │
      ▼
REPRESENTATIVE ACCOUNT TEST
      │
      ▼
STAGED OU ROLLOUT
      │
      ▼
PRODUCTION VERIFICATION

Questions I now ask

Principal

Which principal and session
made the request?

Request

Which action, resource and
context were evaluated?

Grant

Where does the applicable
permission grant come from?

Identity limits

Which permissions boundary
or session policy applies?

Organisation limits

Which SCPs apply along
the complete hierarchy path?

Resource limits

Does an RCP or resource policy
affect the target?

Denial

Is there an explicit deny
or service-specific requirement?

Test

Did the test isolate SCP behaviour
or only observe the final decision?

These questions replace one misleading binary:

SCP says allow,
therefore access should work.

The mental model I am keeping

My earlier model was:

SCP ALLOWS ACTION
        │
        ▼
ACTION ALLOWED

The stronger model is:

                         AWS REQUEST
                              │
                              ▼
                        REQUEST CONTEXT
                              │
              ┌───────────────┼───────────────┐
              │               │               │
              ▼               ▼               ▼
          GRANT PATH       LIMITERS       EXPLICIT DENIES
              │               │               │
              ▼               ▼               ▼
        identity or       boundary,       any applicable
        resource policy   session,        deny statement
                          SCP or RCP
              │               │               │
              └───────────────┼───────────────┘
                              ▼
                   SERVICE-SPECIFIC EVALUATION
                              │
                 ┌────────────┴────────────┐
                 │                         │
                 ▼                         ▼
              ALLOWED                    DENIED

The grant path answers:

Where does the principal
receive authority?

The permissions boundary answers:

How far may this IAM identity's
permissions extend?

The session policy answers:

How much authority may
this temporary session use?

The SCP answers:

Which permissions may remain
available to affected principals
in this account or OU?

The RCP and resource policy answer:

Which requests may
this resource accept?

The request context answers:

Which principal, resource,
network, Region, tags
and conditions apply?

An SCP is powerful because it can prevent member-account administrators from granting selected authority.

It is not powerful because it grants authority itself.

An SCP allow keeps a permission inside the realm of possibility. A valid grant path must still turn that possibility into authority.

FullAWSAccess is not an administrator role.

An SCP allow is not an entitlement.

An AccessDenied response is a result, not a diagnosis.

“Allowed by the SCP” is useful evidence.

It is just not the verdict.

References and further reading

  1. AWS Organizations: Service control policies
  2. AWS Organizations: SCP evaluation
  3. AWS IAM: Policy evaluation logic
  4. AWS IAM: How AWS evaluates policies
  5. AWS IAM: Permissions boundaries
  6. AWS IAM: Troubleshooting access denied
  7. AWS IAM: Testing policies with the simulator
  8. AWS Organizations: SCP examples and testing guidance
  9. AWS Organizations: Resource control policies
  10. AWS IAM Identity Center: Permissions boundaries for permission sets