Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

ClickOps & Cloud Setup

AWS Organizations and Azure Management Groups: Guardrails with SCPs and Policy

Service control policies and Azure Policy set the outer limit of what any identity in an account can do. We design the organisation or management group tree, then attach a small set of tested deny rules, such as blocking unapproved regions and protecting logging, so mistakes cannot exceed those limits.

Key takeaways

  • SCPs do not grant permissions; they define the maximum permissions available in an account.
  • A handful of well-chosen deny policies gives more protection than dozens of complicated ones.
  • Policies attach to organisational units, so the OU tree should mirror where your rules actually differ.
  • Every guardrail is tested in a sandbox before reaching production, because a wrong SCP can lock out your own team.
  • On Azure, management groups with Azure Policy and RBAC play the same role.

Guardrails are what stay true when people make mistakes

IAM answers the question “what is this person allowed to do?” Guardrails answer a different one: “what is nobody allowed to do here, whatever their role?” In AWS, that second job belongs to service control policies. In Azure, it belongs to Azure Policy applied through management groups.

The distinction matters because people with broad permissions are exactly the people most likely to cause a large mistake or to have their credentials stolen. A guardrail still holds in both cases. This page explains how we design and roll them out as part of a landing zone, on top of the account structure.

What an SCP is, and what it is not

An SCP does not give anyone permission. It filters. The effective permissions in an account are the intersection of what the SCPs allow and what IAM grants. A deny in an SCP wins over everything. Two consequences follow:

  1. A new organisation starts with an allow-all policy attached (FullAWSAccess). You build protection by adding denies, not by removing that default, unless you deliberately adopt an allow-list model.
  2. SCPs never apply to the management account, and they do not affect service-linked roles.

The hierarchy

Policies inherit down the tree, so the tree decides how much policy work you do. A shallow structure such as Security, Infrastructure, Workloads (production and non-production) and Sandbox lets you attach the universal rules at the root, stricter ones to production, and looser ones to the sandbox. Deep trees become hard to explain. On Azure, a similar tree of management groups sits above subscriptions, and policy assignments flow the same way.

A starting set of guardrails

The following are common to nearly every estate we build. Each should be adapted to the services you use.

  • Protect the audit trail: deny stopping, deleting or modifying CloudTrail trails and Config recorders created by the baseline.
  • Constrain regions: deny actions outside the regions you operate in, with exceptions for global services.
  • Protect the baseline: deny changes to the roles and stacks the landing zone installs.
  • No leaving the organisation: deny organizations:LeaveOrganization.
  • No IAM users with keys: deny creating access keys for users, pushing everyone to roles and SSO.
  • Block root use in member accounts: deny all actions when the principal is root.

An example: region restriction

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyOutsideApprovedRegions",
      "Effect": "Deny",
      "NotAction": [
        "iam:*",
        "organizations:*",
        "route53:*",
        "cloudfront:*",
        "support:*",
        "sts:*",
        "budgets:*",
        "ce:*"
      ],
      "Resource": "*",
      "Condition": {
        "StringNotEquals": {
          "aws:RequestedRegion": ["eu-west-1", "us-east-1"]
        }
      }
    }
  ]
}

The list of exempt global services is the part teams get wrong. If it is too short, ordinary operations fail; too long, and the guardrail is porous. We build it from CloudTrail data and test, which is why the sandbox stage exists. Control Tower offers a managed region deny control that handles much of this for you, which is one reason we often start there.

Managing them in Terraform

resource "aws_organizations_policy" "deny_regions" {
  name    = "deny-unapproved-regions"
  type    = "SERVICE_CONTROL_POLICY"
  content = file("${path.module}/policies/deny-regions.json")
}

resource "aws_organizations_policy_attachment" "workloads" {
  policy_id = aws_organizations_policy.deny_regions.id
  target_id = aws_organizations_organizational_unit.workloads.id
}

Policies live in version control and change through reviewed pull requests, using the pipeline approach described on our Terraform code page.

Detective controls complement preventive ones

SCPs stop things; they do not tell you what almost happened. Pair them with AWS Config rules and Security Hub findings, set up in the security baseline, so that denied calls and configuration drift are visible. A sudden run of AccessDenied events from one principal is a useful signal.

Azure Policy in practice

Azure Policy definitions with a Deny effect block creation of non-compliant resources, for example storage accounts allowing public blob access, resources in unapproved locations or virtual machines without required tags. Audit and DeployIfNotExists effects detect and remediate rather than block. A typical design uses initiatives (groups of policies) assigned at management groups, and starts in audit mode to learn the impact before switching to deny.

Decisions and trade-offs

Deny list or allow list? Allow-list SCPs are tighter but need constant maintenance as new services appear. Most teams are better served by a deny list covering the dangerous actions.

How many policies? SCPs have size and attachment limits, and each extra one is something to understand. Fewer, clearer policies win.

Tag enforcement. Requiring tags at creation helps cost allocation, but blocks automation that is not tag-aware. We often enforce tags with tag policies and Config rather than SCP denies.

When not to add one. If a rule would prevent legitimate work more often than it prevents harm, handle it with monitoring and review instead.

Rolling a new guardrail out safely

The order of operations is what separates a guardrail from an outage. We follow the same sequence each time. First, we search CloudTrail for the actions the new rule would deny, over a representative period, so we know in advance what it will affect. Second, we attach it to the sandbox OU and deliberately attempt the forbidden action, confirming that it fails with the expected message. Third, we run a normal deployment and a normal day of developer activity in a non-production account to confirm nothing legitimate breaks. Only then does it reach production, ideally at a quiet moment with someone watching denied-call events. If a problem appears, detaching the policy is a one-line change that takes effect quickly, and the rollback is rehearsed rather than improvised.

Common failure modes

  • Locking yourself out. An overly broad deny blocks the very role you need to fix it. We keep a tested break-glass role excluded by condition.
  • Untested region lists. Global service calls routed to us-east-1 start failing.
  • Policy drift. Someone edits a policy in the console. We manage them as code and detect changes.
  • Exceptions that never expire. We record each with an owner and a review date.

Delivery and handover

We deliver the OU or management group tree, policies in code, a table describing each rule’s purpose and a procedure for requesting an exception. Your team learns how to test a change in the sandbox OU. If you want regular review of guardrails alongside the rest of your platform, that fits naturally under our Managed DevOps service.

How to tell it is working

  • A deliberate attempt to stop CloudTrail in a workload account fails.
  • Resources cannot be created in unapproved regions.
  • Denied-call events are reviewed rather than ignored.
  • Every exception has an owner and an expiry.

To design guardrails for your own organisation, contact us.

References

How we deliver it

  1. 01

    Decide what must never happen

    We list non-negotiables such as disabling CloudTrail, leaving approved regions, removing the baseline or making data public.

  2. 02

    Shape the hierarchy

    A shallow OU or management group tree is agreed so policies attach where rules genuinely differ.

  3. 03

    Write and review the policies

    Each deny rule is drafted with the narrowest condition possible and documented with its reason.

  4. 04

    Test in a sandbox OU

    Policies are attached to a test OU first, and we confirm both that bad actions fail and that normal work succeeds.

  5. 05

    Roll out gradually

    Attachment moves from sandbox to non-production to production, with a rollback ready at each step.

  6. 06

    Maintain and review

    Exceptions are tracked, new services are assessed, and policies are reviewed on a regular schedule.

Tools and technologies

AWS OrganizationsService Control PoliciesAWS Control Tower controlsTerraformIAM Access AnalyzerAzure Management GroupsAzure PolicyAzure RBACCloudTrail

Frequently asked questions

What is a service control policy?
An SCP is an Organizations policy that sets the maximum permissions for accounts under it. It never grants access by itself. If an SCP denies an action, no IAM policy in that account can allow it, including an administrator's, which makes SCPs ideal for non-negotiable rules.
Do SCPs apply to the root user?
Yes for member accounts: SCPs restrict the root user of member accounts too. They do not apply to the management account at all. That is one more reason to keep workloads out of the management account and to harden its root login separately.
Which SCPs should every organisation have?
A sensible starting set denies leaving the organisation, disabling or editing CloudTrail and Config, deleting the baseline roles, creating IAM users with access keys, and using regions you do not operate in. Add controls for public storage and unencrypted resources as your maturity grows.
Can SCPs break production?
Yes, if they are attached untested. A deny that is too broad can block deployments or break services that call APIs in other regions. We test in a sandbox OU, review CloudTrail for denied calls, and roll out in stages with a quick path to detach a policy.
What is the Azure equivalent of an SCP?
Azure Policy assigned at management group or subscription level, with deny effects, comes closest. It evaluates resource properties at creation. Azure RBAC deny assignments exist but are limited. Together with a management group hierarchy, policy gives you consistent preventive controls.

Talk to an engineer about aws organizations scp

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.