skip to content

You attach a service control policy that allows `s3:*` to an OU in AWS Organizations, but principals in those accounts still cannot call Amazon S3. Why did nothing change, and what does an SCP actually do?

level: middleimportance: must knowfreq 72%

answer

  1. ceiling, not a grant
  2. allowed to be allowed
  3. FullAWSAccess is still attached
  4. Deny beats AdministratorAccess
  5. union at a node, intersect down the tree

basics

~20 s

A service control policy only sets a ceiling on what an account may be allowed to do; it never grants anything. Allowing s3:* merely leaves S3 inside the ceiling — some IAM policy still has to actually grant the S3 permission.

solid answer

~50 s

SCPs are a maximum-permissions filter, not a grant. For a call in a member account to succeed it must be allowed by IAM inside that account **and** permitted by every SCP on the path from the organization root down to the account. An SCP that allows `s3:*` moves only the second half of that test: it says S3 is inside the ceiling. Nobody has been given S3 permission, so the request still fails on the implicit deny in IAM. There is usually a second reason nothing changed: the default `FullAWSAccess` SCP is still attached to the same node, and SCPs attached at the *same* node are unioned — so the ceiling was already "everything" and adding a narrower allow made no difference. The mirror image is the case that does bite: a Deny in an SCP beats even `AdministratorAccess`, because the ceiling applies no matter how generous the identity policy is.

code

json · 11 lines
json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3",
      "Effect": "Allow",
      "Action": "s3:*",
      "Resource": "*"
    }
  ]
}

go deeper

for a junior

Memorise the one-liner: an SCP can only take permissions away, never give them. If the SCP allows something, IAM in the account still has to grant it separately.

for a middle

Explain both halves of the test — the IAM allow inside the account and the ceiling from every SCP above it — and know that policies at one node are unioned while levels are intersected, which is why FullAWSAccess neutralises an allow-list.

for a senior

Diagnose it: recognise the explicit-deny-in-a-service-control-policy wording, check management-account and service-linked-role exemptions, and make sure developers have a way to see the ceiling instead of filing a ticket per denial.

for a principal

Decide how much governance belongs in SCPs at all. They are absolute and invisible from inside the account, so every Deny you add trades a real safety guarantee against a slower, more confusing failure mode for teams you do not talk to daily.

## The model in one sentence An SCP defines **what the accounts under it are allowed to be allowed to do**. It is a ceiling, not a floor, and no principal ever gets a permission from it. That awkward phrasing is the whole concept. Permissions in a member account still come from IAM inside that account. The SCP only decides whether the permission IAM granted is even eligible to take effect. ## Why the allow-only SCP did nothing Two independent reasons, and candidates who name both are visibly ahead: **1. Allow in an SCP is not a grant.** An `Effect: Allow` statement in an SCP does not add anything to any principal. It only widens the set of actions that the ceiling permits. If no IAM identity policy in the account allows `s3:GetObject`, the request is denied by IAM's implicit deny, and the SCP never gets a chance to matter. ```json { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:*", "Resource": "*" } ] } ``` This document grants exactly nobody anything. **2. `FullAWSAccess` is probably still attached.** Every root and every newly created OU starts with the AWS-managed `FullAWSAccess` SCP attached, which allows `*` on `*`. Multiple SCPs attached to the **same** node are combined as a **union** of their Allow statements; the results of successive **levels** are then intersected as you walk down the tree. So attaching an allow-`s3:*` policy next to `FullAWSAccess` leaves the ceiling at everything. An allow-list SCP only restricts anything once `FullAWSAccess` is detached from that node — which is the step most people forget. ## What is inside the ceiling and what is not SCPs apply to IAM users and roles in **member accounts**, including each member account's root user. They do **not** apply to: - Principals in the **management account** — it is exempt. - **Service-linked roles**, so AWS services can keep doing their internal work regardless of what you deny. - Principals **outside your organization**, even when they access your resources. A cross-account role from a partner account is governed by *their* organization, not yours. That last point is the reason a separate policy type exists to bound access to *resources* rather than to *principals*. ## Deny is where SCPs actually change outcomes Because Allow in an SCP is inert on its own, almost all useful SCP work is done with `Effect: Deny`. A Deny in an SCP cannot be escaped by any IAM policy in the account: ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "NoBucketDeletes", "Effect": "Deny", "Action": "s3:DeleteBucket", "Resource": "*" } ] } ``` An account administrator holding `AdministratorAccess` still cannot delete a bucket, and cannot grant themselves out of it, because they cannot edit an SCP from inside a member account. That asymmetry — Deny is absolute, Allow is inert — is the single most useful thing to be able to state cleanly. ## How this looks when it goes wrong in production The symptom is an `AccessDenied` that no amount of IAM editing fixes. AWS is helpful here: when an SCP is the cause, the error message says the action was denied **with an explicit deny in a service control policy**, as opposed to the wording used for a plain missing permission. Reading that sentence carefully saves hours, because it tells you the fix is in the organization, not in the account. The corollary for troubleshooting: an engineer inside a member account often cannot even *see* the SCPs that are blocking them, since reading them requires access in the management account or a delegated administrator. Any organization that leans on SCPs needs a way for developers to find out what the ceiling is, or every SCP denial becomes a support ticket. ## The mental checklist When someone says "the SCP isn't working", ask in this order: is it an Allow-only policy (then it does nothing on its own)? Is `FullAWSAccess` still attached at the same node (then the ceiling is unchanged)? Is the principal in the management account or a service-linked role (then it is exempt)? Is the account in the OU you think it is? Almost every case is one of those four.

  • So when is an Allow statement in an SCP ever useful?
    Only in allow-list mode. Once you detach `FullAWSAccess` from a node, that node's ceiling becomes exactly the union of the Allow statements you attached there, so the Allow list defines the ceiling instead of merely restating it. Alongside `FullAWSAccess` it is inert. This is why deny-list SCPs, which keep `FullAWSAccess` and add targeted Deny statements, are the far more common design.
  • An engineer in a member account gets AccessDenied and swears their IAM policy is correct. How do you confirm an SCP is the cause?
    Read the error text. When an SCP blocks a call, the message states that it was denied with an explicit deny in a service control policy, which is different wording from a plain missing permission. Then check the SCPs on the path from the root to that account, which usually needs management-account or delegated-administrator access — worth automating a lookup for, or every denial becomes a ticket.
  • Do SCPs stop an AWS service itself from acting inside a member account?
    Not through service-linked roles — they are exempt, so services can keep performing their own internal operations regardless of what you deny. SCPs also do not reach principals outside your organization, so a partner account assuming a role in your account is bounded by their organization's policies, not yours. Bounding access to your resources from outside needs a resource-side control instead.

saying these in an interview costs you the question

  • Thinks an SCP grants permissions to principals
  • Forgets FullAWSAccess is attached by default
  • Says an account admin can override an SCP Deny
  • Believes SCPs apply to principals from other organizations
  • Assumes an Allow-only SCP narrows anything

context