Preventive guardrails stop whole classes of cloud mistakes and attacks before they happen, but a badly staged deny policy at the top of an organisation can break every account at once. Most teams know they should use service control policies, Azure Policy deny assignments or Google Cloud organisation policies; far fewer have a safe way to test them, roll them out in rings, grant exceptions that expire and roll back in minutes. This guide covers that lifecycle across AWS, Microsoft Azure and Google Cloud: what to block first, how each provider lets you simulate or audit before enforcing, how to handle exceptions and how to measure whether the guardrails hold. It is for cloud platform engineers, landing zone owners and security architects. Provider mechanics are covered in depth in the linked per-cloud guides; this page is the vendor-neutral rollout method.
Key takeaways
- Guardrails cap permissions, they never grant them. SCPs, RCPs and organisation policies set the maximum; identities still need their own grants.
- Always observe before you deny. Each cloud offers a way to see what a policy would block: audit or DoNotEnforce mode in Azure, dry run and Policy Simulator in Google Cloud, test OUs and CloudTrail AccessDenied review in AWS.
- Roll out in rings, top of the tree last. Start with a sandbox, then a pilot group of accounts, then production, and attach at the organisation root only when lower levels are clean.
- Exceptions need owners and expiry dates. An exception without an end date becomes a permanent hole nobody remembers.
- Know what guardrails do not cover. Management accounts and service-linked roles sit outside AWS SCPs, so they need their own controls.
What preventive guardrails are
A preventive guardrail is a policy set above individual accounts, subscriptions or projects that blocks a defined action or configuration everywhere beneath it, regardless of the permissions a local administrator holds. It complements detective controls, which find drift after the fact (see the Cloud Security Posture Management (CSPM) Guide), and proactive checks in pipelines, which reject a template before deployment.
| Cloud | Preventive mechanism | Where it attaches | Key behaviour |
|---|---|---|---|
| AWS | Service control policies (SCPs) | Organisation root, OUs, accounts | Maximum permissions for IAM users and roles in member accounts, root user included; no permissions granted. Default FullAWSAccess attached everywhere |
| AWS | Resource control policies (RCPs) | Organisation root, OUs, accounts | Maximum permissions on resources in member accounts, applied to principals inside and outside the organisation, for supported services such as S3, KMS, STS and Secrets Manager |
| Azure | Azure Policy assignments with deny, denyAction, modify or deployIfNotExists effects | Management groups, subscriptions, resource groups | Evaluated on create and update requests; enforcementMode controls whether the effect is applied |
| Google Cloud | Organisation policies using managed or custom constraints | Organisation, folders, projects | Inherited down the hierarchy unless overridden; dry run and Policy Simulator available for custom and managed constraints |
Per-provider detail is in the AWS Organizations and SCPs Guide, AWS Resource Control Policies and Data Perimeter Guide, Azure Policy and Management Groups Guide and Google Cloud Organization Policy Guide.
What to block first
Start with guardrails that protect the security tooling itself and that almost no legitimate workload needs. These have high value and low breakage risk. The list below is our recommended starting set; adapt it to your estate.
| Guardrail intent | Why first | Breakage risk |
|---|---|---|
| Prevent accounts leaving the organisation | An account that leaves escapes every guardrail and central log | Very low |
| Protect audit logging and detection services from being stopped or deleted | Attackers disable logging to hide (ATT&CK T1685 Disable or Modify Tools) | Low, if the security team's own roles are excepted |
| Restrict regions to those you operate in | Unused regions are where crypto-mining and shadow resources hide (T1496.001 Compute Hijacking) | Medium: global services and some managed services need care |
| Block long-lived credential creation where workload identity exists | Removes the most commonly leaked credential type | Medium: inventory existing users of keys first |
| Block public access to storage and unauthenticated function endpoints | Stops the most common data exposure and backdoor patterns | Medium: public websites need an exception path |
| Restrict sensitive encryption options not in use | Limits abuse such as customer-supplied key re-encryption of stored objects (T1486) | Low where the feature is unused |
Two live incidents show why the last two rows matter. In the Amazon AWS Crypto-Mining Campaign 2025, the attacker exposed an unauthenticated public function URL for persistence, and the page's own lesson is to block such URLs with SCPs. In the Codefinger S3 Ransomware 2025 campaign, stolen keys used customer-supplied encryption keys to lock data, and blocking that option where it is not needed removes the route. In both cases the guardrail is a customer-side setting.
Designing a guardrail that will not break production
- Deny list over allow list at first: AWS attaches
FullAWSAccessby default and warns that removing it without a replacement makes every action in member accounts fail. Adding targeted deny statements on top of it is the lower-risk pattern; an allow list of services suits sandbox or highly regulated OUs. - Build exceptions into the condition: exempt named break-glass and platform automation roles in the policy itself (for example by principal ARN or tag condition), so you do not have to detach the guardrail during an emergency. See the Break-Glass Account Guide.
- Remember inheritance: in AWS an account has only the permissions allowed by every parent above it, so a deny at any level wins even over AdministratorAccess. In Google Cloud, a live policy set on a child resource changes the effective result of an inherited dry-run policy, so test at the level where it will finally sit.
- Use the data you already have: AWS recommends checking IAM service last accessed data or CloudTrail logs to see which services an account actually uses before restricting them.
- Mind size and count limits: every character in an SCP counts toward its maximum size, and Azure allows up to 10 overrides and 10 resource selectors per assignment. Confirm current quotas in each provider's docs before designing a large set.
- Keep policy as code: store every guardrail, exception and assignment in version control with review and automated tests, the same discipline as the Policy-as-Code for Authorisation Guide describes for application authorisation.
Simulating and observing before enforcement
Each provider offers a way to see the impact of a guardrail before it blocks anything. Use it for every new policy and every material change.
| Cloud | Observe mode | Where results appear | Notes |
|---|---|---|---|
| AWS | Attach to a test OU or individual test accounts first, moving accounts in one or a few at a time | CloudTrail AccessDenied errors from the test accounts | AWS strongly recommends not attaching SCPs or RCPs to the root without thorough testing |
| Azure | enforcementMode set to DoNotEnforce, or an audit effect | Compliance results in Azure Policy; DoNotEnforce writes no deny entries to the Activity log | The Enroll mode enforces only for scopes that have enrolled, for staged rollout |
| Google Cloud | Dry-run policy (dryRunSpec) | Audit log cloudaudit.googleapis.com%2Fpolicy, entries where dryRunResult is DENIED and liveResult is ALLOWED | Supported for custom constraints, managed constraints and a few legacy constraints |
| Google Cloud | Policy Simulator for Organization Policy | Report of resources that would violate the proposed policy, linked to Cloud Asset Inventory | Checks existing resources; one organisation per run; results kept 14 days in the console |
Observation answers two different questions. A simulator over existing resources tells you what is already non-compliant; a dry run or audit over live traffic tells you which operations would start failing. You need both: the first shapes the remediation backlog, the second shapes the exception list.
Rolling out in rings
Our recommended sequence, used for each new guardrail or batch of related guardrails:
- Write and review: author the policy as code, with its intent, owner, exceptions and rollback step recorded in the pull request.
- Sandbox ring: enforce in a sandbox OU, management group or folder. Run the platform's smoke tests and a deployment from each main pipeline.
- Observe in production scope: assign the policy in audit, DoNotEnforce or dry-run mode at its final scope for one to two weeks, long enough to cover monthly jobs if your estate has them. Triage every would-be denial into fix, exception or accept.
- Pilot ring: enforce for a small set of production accounts or subscriptions with engaged owners. In Azure, resource selectors can limit evaluation to chosen regions or resource types and expand step by step; Enroll mode lets scope owners opt in.
- Broad ring: enforce for the rest of production, communicating the date and the exception route in advance.
- Root attachment: only for guardrails that must apply everywhere, and only once lower levels are clean.
- Rollback: keep a tested way back for each step: detach the policy, switch Azure enforcementMode back to DoNotEnforce, or remove the live spec in Google Cloud. Google Cloud notes that enforced policies can take up to 15 minutes to take effect, so expect a similar lag when rolling back and plan communications around it.
Exceptions that do not become permanent
Every guardrail programme needs an exception route; without one, teams pressure you to remove the guardrail. The ID.RA-07 outcome in NIST CSF 2.0 asks that changes and exceptions are managed, assessed for risk impact, recorded and tracked.
- Azure exemptions: two categories, Mitigated (the intent is met another way) and Waiver (non-compliance temporarily accepted), with an optional
expiresOndate. Expired exemptions are kept for record-keeping but no longer honoured, so delete them during reviews. Creating an exemption needs theexempt/Actionpermission on the assignment, so limit who holds it. - Excluded versus exempted: Azure
notScopesremoves a scope from evaluation entirely; an exemption keeps it visible in compliance reporting. Prefer exemptions so exceptions stay on the dashboard. - AWS and Google Cloud: express exceptions as conditions or as separate OUs and folders with their own policy, and record each one in a register with owner, reason, compensating control and end date, as we recommend for all three clouds.
- Review cadence: our recommendation is a monthly review of exceptions due to expire and a quarterly review of all of them.
Where identity fits
Guardrails are one of the few controls that limit non-human identities you cannot see. A guardrail blocking access key creation or requiring workload identity federation covers every pipeline and script, including ones nobody inventoried. At the same time, the platform automation that deploys guardrails is among the most privileged identities in the organisation; keep it in a separate account, limit who can change it and alert on its use outside the pipeline. See the Cloud Workload Identity Guide.
Not everything is covered. AWS SCPs do not affect users or roles in the management account or service-linked roles, and RCPs do not restrict resources in the management account. Keep workloads out of the management account and protect its root and recovery credentials separately. See Protecting Cloud Control-Plane Recovery Accounts and Credentials.
Decision guidance
- Preventive or detective: use a preventive guardrail when the action is never acceptable and easy to define (leave organisation, disable logging). Use a detective control where context decides (a public bucket for a website), and pair it with fast remediation.
- Organisation-wide or per environment: security-tooling protections belong at the top; workload restrictions such as allowed instance types belong at environment level so teams can move at different speeds.
- Small organisations: a handful of high-value deny guardrails at the root, tested in one sandbox account, gives most of the benefit. Landing zone accelerators provide tested starting sets; see the Cloud Landing Zone Security Guide.
- Large or regulated estates: run a guardrail platform team, a change advisory step for root-level changes, and a published catalogue of guardrails with owners and exception routes.
Detection and measurement
- Guardrail coverage: share of accounts, subscriptions and projects under the baseline guardrail set, which should reach close to all.
- Denials by guardrail: blocked attempts per week; a sudden spike can mean an attack or a broken deployment, and both need a look.
- Time in observe mode: days between audit assignment and enforcement; very long periods mean the backlog is not being worked.
- Open and expired exceptions: count, age and number past their end date.
- Rollbacks: number of guardrail rollbacks caused by production breakage, which should fall as testing matures.
- Changes outside the pipeline: any guardrail edit not made through version control, alerted in real time.
Framework mapping
| Guardrail activity | NIST CSF 2.0 | NIST SP 800-53 Rev 5 |
|---|---|---|
| Baseline guardrail set | PR.PS-01 | CM-2, CM-6, CM-7 |
| Permission ceilings for identities and resources | PR.AA-05 | AC-3, AC-6 |
| Simulation and staged rollout | PR.PS-01 | CM-3, CM-4 |
| Exception management | ID.RA-07 | CM-3 |
| Monitoring denials and drift | DE.CM-09 | CA-7 |
Common failure patterns
- Straight to the root: a new deny attached at the top without a test OU breaks deployments across every account.
- Removing the default allow: detaching
FullAWSAccesswithout a replacement allow policy makes every action in member accounts fail. - No exception for responders: a guardrail blocks the security team from the action needed during an incident, and the guardrail is detached under pressure.
- Audit mode forever: policies assigned in audit or dry run and never enforced give a false sense of coverage.
- Exceptions without end dates: waivers accumulate until the guardrail protects little.
- Assuming the management account is covered: workloads placed there sit outside SCPs.
Practitioner checklist
- Inventory the preventive mechanisms you use in each cloud and the scopes they attach to.
- Deploy the starting set first: stay in organisation, protect logging and detection, restrict regions.
- Keep every guardrail and exception in version control with owner, intent and rollback step.
- Observe each new policy in audit, DoNotEnforce or dry-run mode at its final scope before enforcing.
- Use Policy Simulator or equivalent to size the existing non-compliance backlog.
- Roll out sandbox, pilot, broad, then root, with a tested rollback at each ring.
- Build break-glass and platform automation exceptions into policy conditions.
- Give every exception an owner and an end date, and review them monthly.
- Keep workloads out of the management account and protect it separately.
- Alert on guardrail changes made outside the pipeline.
Standards and references
- AWS: Service control policies (SCPs)
- AWS: Resource control policies (RCPs)
- Microsoft Learn: Azure Policy assignment structure
- Microsoft Learn: Azure Policy definitions effect basics
- Microsoft Learn: Azure Policy exemption structure
- Google Cloud: Create an organization policy in dry-run mode
- Google Cloud: Test organization policy changes with Policy Simulator
Related NHI Mgmt Group resources: AWS Organizations and SCPs Guide · Azure Policy and Management Groups Guide · Google Cloud Organization Policy Guide · Cloud Landing Zone Security Guide · Cloud Security Posture Management (CSPM) Guide