April 30, 2025

A Comprehensive Guide to AWS Service Control Policies (SCP)

Sahara Armen

Tamnoon CloudPro

Share:

To get allow/deny validation scenarios (complete with AWS CLI and boto3 code samples!) for each of the SCPs in this guide, visit our interactive SCP explorer.

Mastering AWS SCPs: Your Go-To Guide for Cloud Security

AWS Service Control Policies (SCPs) sit at the heart of any serious cloud governance strategy. They define what actions are off-limits—before any IAM permissions even come into play—giving your organization a centralized way to enforce security across every AWS account you manage.

For technical founders building in complex environments, SCPs provide a way to scale secure practices without slowing down teams. They offer peace of mind that your baseline controls are enforced no matter who spins up a new service or account.

This guide walks you through what SCPs are, how they work, and why they’re essential for long-term cloud security. Whether you’re locking down access to sensitive data or setting up a tightly scoped dev environment, SCPs give you the tools to do it right.

What Are AWS SCPs?

Service Control Policies (SCPs) are permission boundaries applied at the organization level in AWS. They don’t grant permissions—instead, they define what’s allowed or denied, acting as a filter between your AWS accounts and the services they can access. Think of them as a master control layer that applies across your entire AWS Organization, regardless of what individual IAM roles or policies permit.

Each SCP uses a JSON-based syntax similar to IAM policies. You define Allow or Deny effects, the relevant Actions, target Resources, and optional Conditions

For example, you might deny the ability to disable CloudTrail, block access to regions outside the EU, or prevent S3 bucket deletion. These policies can be attached to the root, an Organizational Unit (OU), or individual accounts—wherever they live, their effects cascade down the hierarchy unless overridden by another attached SCP.

How SCPs Work Inside AWS Organizations

SCPs operate in tandem with IAM policies, but from a higher vantage point. They’re evaluated before IAM comes into the picture. Here’s how that hierarchy looks in practice:

  • SCPs define the maximum scope: No IAM policy can override an SCP. If the SCP blocks an action, it doesn’t matter if the IAM policy allows it—the action won’t go through.
  • IAM policies handle permissions inside the boundary: IAM still determines who can do what, but only within the limits set by the SCPs.

This dual-layer model gives you both granularity and control. It’s especially useful in environments where different teams operate independently across accounts, but you still want to enforce certain non-negotiables like mandatory encryption, limited region use, or strict data access policies.

Example: Denying S3 Public Access

Here’s a simplified SCP that prevents any account from creating public S3 buckets:

				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyPublicReadACL",
      "Effect": "Deny",
      "Action": "s3:PutBucketAcl",
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "s3:x-amz-acl": "public-read"
        }
      }
    }
  ]
}

				
			

This policy blocks any attempt to set a bucket’s ACL to public-read, regardless of what IAM allows. It’s a simple but effective way to avoid accidental data exposure.

Key Characteristics of SCPs

  • Inheritability: Attach an SCP at the root, and its rules apply to every OU and account underneath—unless explicitly narrowed or overridden.
  • No effect on the management account: SCPs don’t apply to the AWS Organization’s management account, only to member accounts.
  • No retroactive enforcement: SCPs don’t undo past actions. They only affect permissions going forward.
  • No effect on service-linked roles: These roles, often created by AWS services for internal use, operate outside SCP constraints.

By introducing SCPs into your architecture, you gain a powerful way to enforce consistency across environments. You also reduce the risk of misconfigurations—accidental or otherwise—that could lead to expensive or embarrassing security incidents. For fast-moving teams, SCPs act like guardrails: invisible most of the time, but critical when someone veers off track.

The Most Basic SCP Policy

The following policy is perhaps the most basic policy in the SCP world:

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


				
			

Its official name is FullAWSAccess, and it contains the most dangerous combination in cloud security: Effect “Allow” with wildcard Action (“*”) and wildcard Resource (“*”) – essentially granting unlimited permissions to perform any action on any resource within AWS.

All discussions about AWS Service Control Policies (SCPs) should indeed begin with this fundamental example, as it represents the antithesis of the principle of least privilege. This permissive policy is the security equivalent of leaving all your doors unlocked with a “come on in” sign – it’s precisely what SCPs were designed to prevent. Understanding how to properly restrict this mother of all policies through well-crafted SCPs is the foundation of AWS Organizations security governance, and the starting point for implementing effective defense-in-depth strategies in multi-account environments.

Since this is the very first policy enabled when you “turn on the lights”, it’s important you understand what it looks like and what it enables.

Moving on…

Common Types of SCPs for Cloud Security

SCPs map directly to your organization’s risk model. The way you structure them—whether to block, permit, or layer controls—determines how flexible or restrictive your cloud environment becomes. Instead of granting permissions, SCPs set the outer boundary of what’s even possible, forcing every IAM permission to live within that boundary.

Deny-Based Policies: Guardrails First

Deny policies are the foundation of many cloud governance strategies because they allow teams to define non-negotiable boundaries without cataloging every permissible action. These are ideal for enforcing compliance or operational standards that shouldn’t vary between environments, such as requiring encryption, preserving audit trails, or preventing the use of deprecated services.

For instance, to protect logging infrastructure, you could block any attempt to alter or delete CloudTrail resources:

				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "BlockCloudTrailTampering",
      "Effect": "Deny",
      "Action": [
        "cloudtrail:DeleteTrail",
        "cloudtrail:UpdateTrail",
        "cloudtrail:StopLogging"
      ],
      "Resource": "*"
    }
  ]
}



				
			

This ensures audit continuity regardless of IAM role misconfigurations or compromised credentials. It’s a simple way to enforce an immutable logging layer across the org.

Deny-based SCPs also help with enforcing boundaries that aren’t always obvious, like limiting the use of legacy endpoints or preventing access to unapproved services. For example, to block usage of a high-risk service like IAM Access Analyzer outside a security account, you can scope access based on the calling principal’s ARN:

				
					{
  "Effect": "Deny",
  "Action": "access-analyzer:*",
  "Resource": "*",
  "Condition": {
    "StringNotLike": {
      "aws:PrincipalArn": "arn:aws:iam::*:role/SecurityOps*"
    }
  }
}



				
			

This narrows access to specific roles while keeping the service available where it’s needed.

Allow-Based Policies: Locking It Down

Allow-list SCPs take a default-deny stance across the board—nothing runs unless it’s explicitly permitted. They’re common in high-compliance environments where only vetted workflows should exist. Because these policies don’t inherit permissions from higher levels unless explicitly redefined, they require meticulous planning and ongoing maintenance.

Here’s an example that allows only read-only access to a subset of AWS services:

				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowBasicReadOnly",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "ec2:DescribeInstances",
        "rds:DescribeDBInstances"
      ],
      "Resource": "*"
    }
  ]
}




				
			

This policy is ideal for analytics, security review, or billing teams who don’t need write access but still require visibility into cloud resources. The challenge with allow lists lies in their rigidity: if a required action isn’t explicitly permitted, it breaks silently. That’s why many teams test allow-list SCPs in isolated OUs before rolling them out more broadly.

A keen observer might note that this allow-based SCP approach has limitations when controlling EC2 instance types. The ec2:InstanceType condition in SCPs has proven unreliable, even when using StringNotEqualsIfExists to avoid false negatives.

Instead of relying solely on an allow-list SCP with specific instance types, a more effective approach uses two complementary controls:

1. Coarse-Grained SCP (Organizational Level)
				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowEC2RunInstancesOnly",
      "Effect": "Allow",
      "Action": [
        "ec2:RunInstances",
        "ec2:DescribeInstances",
        "ec2:DescribeInstanceStatus",
        "ec2:DescribeInstanceTypes"
      ],
      "Resource": "*"
    },
    {
      "Sid": "DenyOtherEC2Actions",
      "Effect": "Deny",
      "NotAction": [
        "ec2:RunInstances",
        "ec2:DescribeInstances",
        "ec2:DescribeInstanceStatus",
        "ec2:DescribeInstanceTypes"
      ],
      "Resource": "*"
    }
  ]
}

				
			

Which establishes a coarse boundary by:

  • Explicitly allowing only EC2 instance creation and describing operations
  • Denying all other EC2 actions not specifically permitted

This policy should be paired with a:

2. Fine-Grained IAM Policy (Account Level)
				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": "arn:aws:ec2:*:*:instance/*",
      "Condition": {
        "StringEquals": {
          "ec2:InstanceType": [
            "t3.micro",
            "t3.small",
            "t3.medium"
          ]
        }
      }
    },
    {
      "Effect": "Allow",
      "Action": "ec2:RunInstances",
      "Resource": [
        "arn:aws:ec2:*:*:subnet/*",
        "arn:aws:ec2:*:*:network-interface/*",
        "arn:aws:ec2:*:*:security-group/*",
        "arn:aws:ec2:*:*:volume/*",
        "arn:aws:ec2:*:*:key-pair/*",
        "arn:aws:ec2:*:*:image/*"
      ]
    }
  ]
}

				
			

That provides fine-grained control by:

  • Allowing only specific instance types (t3.micro, t3.small, t3.medium)
  • Granting necessary permissions for associated resources (subnets, network interfaces, etc.)

This approach acknowledges that SCPs are best used as coarse-grained controls to establish broad boundaries, while IAM policies handle the more granular permission requirements.

Going back on topic, allow policies also requires consistent application across the organizational hierarchy. Miss a level, and the policy won’t apply as intended. This makes automation and strict versioning essential when adopting this model at scale.

Hybrid Strategies: Layered Security

A layered approach gives you the best of both worlds: coarse-grained protection from deny policies, with surgical precision applied via allow lists where needed. This is especially useful in organizations with varied workloads, ranging from experimental dev environments to tightly controlled production systems.

Start by applying a deny-list policy at the root that enforces non-negotiables like region restrictions or encryption requirements. Then, attach allow-list SCPs to specific OUs to gate access to high-risk operations or expensive services.

For example, to limit instance types in a development OU:

				
					{
  "Effect": "Deny",
  "Action": "ec2:RunInstances",
  "Resource": "*",
  "Condition": {
    "StringNotLike": {
      "ec2:InstanceType": [
        "t3.micro",
        "t3.small",
        "t3.medium"
      ]
    }
  }
}
				
			

This ensures dev teams can test workloads without accidentally launching costly compute instances. The layered strategy also makes troubleshooting easier: violations are either a policy gap (missing allow) or a hard block (explicit deny), which helps maintain operational clarity as environments scale.

Where Do AWS SCPs Fit Into Cloud Security?

SCPs function as a structural layer of control, not just a permission mechanism. They’re embedded into the AWS Organizations framework and apply globally across member accounts in a way that no IAM policy can replicate. Their real impact shows up when you scale—multiple teams, multiple services, multiple accounts—and need a way to enforce non-negotiables without micromanaging each team’s IAM structure.

Rather than shaping what specific users can or can’t do, SCPs shape how accounts behave at an architectural level. That means you can enforce global conditions on resource usage, geographical boundaries, or even cost controls by blocking high-cost services in non-production environments. This makes SCPs especially useful for large organizations with decentralized ownership of accounts, where central security teams must ensure consistency without directly owning every permission decision.

How SCPs Shape Account Behavior

SCPs apply at the account level, regardless of how access is granted—whether through IAM roles, Identity Center permission sets, or federated identities. This makes them ideal for enforcing baseline controls where IAM policy sprawl would otherwise introduce risk. For example, you can ensure all S3 uploads include server-side encryption without needing to inspect or update every bucket policy across hundreds of accounts.

  • Enabling environment-specific boundaries: Attach environment-specific SCPs to development or staging OUs that block access to production-only services. This prevents accidental dependency on restricted services and keeps environments isolated by design.
  • Automating incident readiness: Prepare “kill switch” SCPs in advance that restrict sensitive operations like modifying KMS keys or deleting CloudWatch logs. These can be attached during a suspected breach to lock down critical paths while the investigation proceeds.
  • Enforcing policy through hierarchy: SCPs support inheritance across nested OUs, which allows you to apply broad governance at higher levels and progressively add tighter controls at lower tiers. For example, a security OU might inherit the org-wide SCPs and then apply additional restrictions for services like IAM, KMS, or CloudTrail.

Each of these behaviors aligns with AWS Organizations’ hierarchical model, allowing you to design your governance in tandem with your account structure. This makes SCPs more than just a security tool—they’re a permission design primitive.

SCPs also integrate naturally into your operational tooling. For instance, you can combine CloudTrail logs with SCP enforcement to track denied actions and identify misaligned IAM permissions. Similarly, by linking SCP deployment to infrastructure-as-code pipelines, you can validate new policies against sandbox environments before enforcing them org-wide—just like we offer at Tom Granot. SCPs aren’t just a static security layer. They’re dynamic components of a well-governed cloud architecture.

How to Get Started with AWS SCPs

Deploying SCPs across an AWS Organization demands more than toggling a feature in the console. It’s a deliberate move that wires your security model directly into your infrastructure governance. Rushed implementation leads to confusion, blocked automation, and policy sprawl. It’s worth slowing down to get it right.

Define the Control Objectives First

Start by pinpointing what you want to prevent, not what you want to allow. Think operationally: what’s caused issues in the past? What’s non-compliant with your regulatory requirements? What are the top security scenarios you never want to see happen again? These concerns translate directly into your first wave of SCPs.

For example, disallowing access to unapproved regions supports data residency compliance. Blocking the ability to delete CloudTrail logs ensures auditability. Restricting IAM user creation protects against privilege sprawl. These decisions should reflect real-world events, not theoretical models, and they should map cleanly to specific OUs or environments.

Don’t treat every account the same. A test sandbox should have looser constraints than a production billing account. Start at the root with your non-negotiables—then layer stricter controls as you move down into specific workloads.

Build and Test SCPs in Isolation

No matter how well you plan, the first few SCPs will break something. That’s expected. Use a dedicated staging OU to test new policies in isolation before rolling them out to production accounts. This avoids surprises that lock out developers or break CI pipelines.

CloudTrail logs are invaluable here. By filtering for ServiceEventDenied or OrganizationsPolicyChanges, you can spot where SCPs are stopping actions and trace those back to specific policy statements. This gives you a feedback loop between policy design and real-world outcomes.

Start simple. Deny actions outside of approved regions, or block mass deletion of resources. Then incrementally add complexity—conditions, tag-based restrictions, or resource-level controls. Monitor how your tools and teams respond, and document what gets blocked and why. That context is critical for long-term maintainability.

Here’s one to start with: deny all resource operations outside of specific AWS regions.

				
					{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:RequestedRegion": [
        "us-east-1",
        "eu-west-1"
      ]
    }
  }
}

				
			

This will catch any outlier deployments or misconfigured defaults. But services that don’t explicitly set a region might also get caught, so simulate and observe before enforcing.

Use Policy Generation and Validation Tools

Manually writing JSON for SCPs at scale is a fast track to mistakes. Use tools that abstract away boilerplate and help you focus on intent. A visual policy editor or JSON schema validator can catch malformed condition blocks, missing actions, or inconsistent structure—before those problems hit production.

Treat policies like code. Store them in version control. Review changes through pull requests. Deploy using IaC pipelines with validation steps like syntax checks, policy simulations, or even dry-run deployments in test accounts.

Also, test for unintended consequences. A deny that blocks s3:PutObject without narrowing by condition might break backups. A condition that filters on aws:PrincipalOrgID assumes all principals have that attribute, which external roles won’t.

To avoid these traps:

  • Build a library of reusable policy fragments.
  • Test changes in a known-safe sandbox.
  • Monitor AccessDenied events post-deployment and trace them back to SCP conditions.

When you treat SCPs as part of your infrastructure lifecycle, not a one-time config, they scale with your organization instead of slowing it down.

Step 1: Align SCP Strategy with Organizational Goals

SCPs only work well when they reflect the actual risk profile and structure of your business. Misaligned policies tend to either block legitimate workflows or leave gaps that aren’t obvious until something breaks. Before writing a single line of policy, you need clarity on what your organization is trying to protect, what it’s willing to restrict, and where flexibility is required.

Start by reviewing your most sensitive assets and workflows. 

  • Where does your customer data live? 
  • Which accounts run production workloads? 
  • Which environments are often used for experimentation or onboarding? 

These distinctions help you scope your SCPs with intention. The tighter the control needed, the more precise your policy logic should be. This is where the OU structure in AWS Organizations becomes your enforcement map. Each policy should match a business context, not just a technical one.

Choose the Right Control Model: Deny or Allow

The decision to use a deny-list or allow-list model comes down to how much you trust the underlying IAM implementation in each account and how tightly you need to constrain behavior.

Deny-list approach 

Useful when you want to hard-block known problematic behaviors without interfering with day-to-day operations. For example, you can prevent IAM users from creating access keys unless they belong to a specific role pattern.

				
					{
  "Effect": "Deny",
  "Action": "iam:CreateAccessKey",
  "Resource": "*",
  "Condition": {
    "ArnNotLike": {
      "aws:PrincipalArn": "arn:aws:iam::*:role/Automation*"
    }
  }
}

				
			

This ensures sensitive operations like key creation are scoped to automation roles, avoiding accidental credential sprawl across your environment.

Allow-list approach

Best for zero-trust environments where every action must be explicitly approved. Instead of building an exhaustive deny list, you permit only what’s necessary. For example, a data science OU could be limited to read-only access to Athena and specific S3 buckets.

				
					{
  "Effect": "Allow",
  "Action": [
    "athena:GetQueryResults",
    "athena:StartQueryExecution",
    "s3:GetObject"
  ],
  "Resource": "*"
}

				
			

This keeps experimentation isolated to analytics tools without opening write access to infrastructure or storage.

Of course, this isn’t a binary choice. Many teams implement organization-wide deny-list SCPs to enforce baseline security, then apply allow-list SCPs at the OU level to enforce stricter conditions in regulated or shared environments.

Prioritize Enforcement Based on Organizational Sensitivity

Not all accounts carry the same weight. Identify the OUs responsible for production services, PII storage, regulated workloads, or billing. These are your enforcement hotspots. Apply SCPs that go beyond basic restrictions, such as blocking the ability to detach encryption from RDS snapshots or preventing modifications to key cloud audit services.

For example, to enforce uthe sage of approved AWS Regions in a finance account:

				
					{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:RequestedRegion": [
        "us-west-2",
        "us-east-1"
      ]
    }
  }
}

				
			

This ensures that resources are never provisioned in unauthorized regions, reducing compliance overhead and attack surface. Meanwhile, sandbox OUs can carry lighter restrictions, allowing teams to innovate without risking policy violations. The strategy works best when every SCP reflects a business intent, not just a security rule.

Step 2: Create Baseline SCPs

Once you’ve mapped your SCP strategy to organizational needs, the next move is to define your minimum viable guardrails. These non-negotiable controls (or policies) apply across every account, regardless of its function, lifecycle stage, or team ownership. They aren’t about fine-tuning; they’re about eliminating the possibility of catastrophic missteps. This baseline layer reduces noise, flattens risk, and creates a predictable perimeter for every service interaction.

A good baseline targets the kinds of actions that, when abused or misconfigured, lead to irreversible damage or compliance violations. These aren’t edge cases, they’re the patterns that attackers or careless developers exploit the most. By hard-blocking access to those actions with clear conditions, you ensure stability and auditability across the board.

Protecting Critical Infrastructure from Destructive Actions

Rather than repeating CloudTrail restrictions, consider enforcing service-wide protection for logging and monitoring infrastructure. CloudWatch, for example, is often overlooked but just as critical for detection and alerting. Blocking deletion or suspension of alarms, log groups, or metric filters reinforces your observability baseline.

				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyCloudWatchTampering",
      "Effect": "Deny",
      "Action": [
        "logs:DeleteLogGroup",
        "logs:DeleteLogStream",
        "cloudwatch:DeleteAlarms"
      ],
      "Resource": "*"
    }
  ]
}

				
			

This policy strengthens the integrity of your monitoring stack. By preventing key telemetry components from being disabled or removed, you eliminate blind spots that attackers or rogue processes might exploit.

Restricting Access Based on Execution Context

Adding context-aware conditions to your baseline SCPs allows you to enforce behavior without introducing friction across all workflows. One common control involves restricting sensitive operations based on the source of the request, such as blocking administrative actions from the console while allowing them from automation pipelines.

In theory, an SCP like this would have been great:

				
					{
  "Effect": "Deny",
  "Action": [
    "iam:CreateUser",
    "iam:AttachUserPolicy"
  ],
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "aws:ViaAWSService": "false",
      "aws:RequestedVia": "console"
    }
  }
}

				
			

Alas, aws:RequestedVia is not a valid global condition key! What a shame.

Instead, we would once again need a combination of SCP and IAM policies:

1. SCP to Set Broad Boundaries

				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "RestrictSensitiveIAMOperations",
      "Effect": "Deny",
      "Action": [
        "iam:CreateUser",
        "iam:AttachUserPolicy",
        "iam:CreatePolicy",
        "iam:PutUserPolicy"
      ],
      "Resource": "*",
      "Condition": {
        "ArnNotLike": {
          "aws:PrincipalARN": [
            "arn:aws:iam::*:role/AutomationRole*",
            "arn:aws:iam::*:role/ServiceRole*"
          ]
        }
      }
    }
  ]
}

				
			

This SCP restricts sensitive IAM operations to specific automation roles by focusing on the principal’s ARN rather than trying to detect the console source.

2. IAM Policy to Control Console Access

				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyConsoleAccessForIAMAdmin",
      "Effect": "Deny",
      "Action": [
        "iam:CreateUser",
        "iam:AttachUserPolicy",
        "iam:CreatePolicy",
        "iam:PutUserPolicy"
      ],
      "Resource": "*",
      "Condition": {
        "Bool": {
          "aws:ViaAWSService": "false"
        },
        "StringNotLike": {
          "aws:UserAgent": "*AWS-CloudFormation*"
        }
      }
    }
  ]
}

				
			

This combined approach addresses the limitations of the original SCP while still achieving the goal of ensuring privileged identity operations only happen through approved automation mechanisms. It also reduces the risk of manual misconfiguration or privilege creep from ad hoc changes in the console.

Enforcing Tag-Based Operational Boundaries

Another effective baseline control requires standardized tagging for critical resources. This enforces ownership, traceability, and cost allocation from the beginning. There’s no need for manual enforcement.

				
					{
  "Effect": "Deny",
  "Action": [
    "ec2:RunInstances",
    "rds:CreateDBInstance"
  ],
  "Resource": "*",
  "Condition": {
    "Null": {
      "aws:RequestTag/Environment": "true"
    }
  }
}

				
			

This policy denies provisioning unless a specific tag, like Environment, is included in the request. The result: no more orphaned resources, no more billing surprises, and an easier time filtering and responding to incidents based on environment classification.

Well…. Almost. 

The problem with this approach is that while the SCP is looking for request tags and RDS supports them, EC2 does not.

A better approach would be to check the resource tags instead of request tags: 

				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyResourceCreationWithoutProperTags",
      "Effect": "Deny",
      "Action": [
        "ec2:RunInstances"
      ],
      "Resource": [
        "arn:aws:ec2:*:*:instance/*"
      ],
      "Condition": {
        "ForAnyValue:StringNotLike": {
          "aws:TagKeys": [
            "Environment",
            "Owner",
            "CostCenter"
          ]
        }
      }
    },
    {
      "Sid": "DenyRDSCreationWithoutProperTags",
      "Effect": "Deny",
      "Action": [
        "rds:CreateDBInstance"
      ],
      "Resource": [
        "arn:aws:rds:*:*:db:*"
      ],
      "Condition": {
        "Null": {
          "rds:cluster-tag/Environment": "true"
        }
      }
    },
    {
      "Sid": "DenyUntaggingOperations",
      "Effect": "Deny",
      "Action": [
        "ec2:DeleteTags",
        "rds:RemoveTagsFromResource"
      ],
      "Resource": "*",
      "Condition": {
        "ForAnyValue:StringEquals": {
          "aws:TagKeys": [
            "Environment",
            "Owner",
            "CostCenter"
          ]
        }
      }
    }
  ]
}

				
			

This approach is a little more verbose but significantly more reliable, especially since we’re also verifying that resources maintain proper tagging throughout their lifecycle.

To summarize, baseline SCPs shouldn’t try to do everything. They should do a few critical things consistently across all accounts: preserve visibility, enforce context, and require accountability. When you get those right at the foundation, everything built on top becomes easier to secure and scale.

Step 3: Fine-Tune Permissions with Conditions

Baseline SCPs may create the perimeter, but conditions add control over behavior inside it. Conditions let you express context: when something is allowed, where it’s allowed from, or under what metadata. Instead of a static allow/deny, you enforce rich constraints that reflect how teams operate day to day without relaxing security.

Build Context-Aware Controls

Injecting environmental awareness into your SCPs transforms them from policy walls into dynamic permissions. 

A common example is allowing specific EC2 actions only when triggered by a trusted automation service, not a user in the console.

				
					{
  "Effect": "Deny",
  "Action": "ec2:TerminateInstances",
  "Resource": "*",
  "Condition": {
    "StringEquals": {
      "aws:CalledVia": "ec2.amazonaws.com",
      "aws:ViaAWSService": "true"
    }
  }
}

				
			

This approach prevents interactive use of high-risk infrastructure actions while still enabling your deployment pipeline or autoscaling to work uninterrupted. It also makes incident triage clearer. If something goes wrong, you know exactly which service triggered it.

Enforce Tag-Based Standards

Tags can do more than organize cost reports. They can gate access to infrastructure entirely. Instead of using them just for filtering or dashboards, use them to enforce naming conventions, lifecycle policies, or compliance scopes at the time of resource creation.

For example, to enforce that all compute resources carry a ComplianceScope tag:

				
					{
  "Effect": "Deny",
  "Action": [
    "ec2:RunInstances",
    "eks:CreateCluster"
  ],
  "Resource": "*",
  "Condition": {
    "Null": {
      "aws:RequestTag/ComplianceScope": "true"
    }
  }
}

				
			

This ensures teams have to define how the workload fits into your business context before it even spins up. Downstream, this tag can drive backup policies, logging requirements, or even isolation strategies.

Manage Inheritance with Precision

SCP conditions follow the same inheritance behavior as the policies in which they live. When attached at the root, they apply everywhere unless overridden explicitly at a lower level. This gives you powerful reach, but also demands a clear structure to avoid unintended blocks.

Use this to your advantage by reserving broad conditions—like region or tag enforcement—for root-level policies, and then layering more specific logic at the OU level. For example, you can allow broader service access in a non-prod OU while keeping the same tag enforcement inherited from the org root.

One useful trick: scope conditions to principal tags. This lets you create role-based enforcement without hardcoding ARNs or trusting IAM naming schemes. For instance, restrict S3 access to only principals tagged with DataTeam:

				
					{
  "Effect": "Deny",
  "Action": "s3:*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:PrincipalTag/Team": "DataTeam"
    }
  }
}

				
			

This technique scales well across federated users, short-lived roles, and cross-account access patterns. It also keeps your SCPs clean, so you’re not left juggling dozens of explicit identities or OUs.

Fine-tuned conditions don’t just protect—they clarify. Teams know where their actions are valid and when they’re not. That transparency becomes leverage: governance shifts from overhead to ecosystem.

Step 4: Compare AWS SCPs vs. IAM Policies

SCPs and IAM policies are both essential to AWS security, but they operate at different layers and solve different problems. SCPs define the organizational boundaries—what actions no one is allowed to take, regardless of identity. IAM policies assign specific permissions within those boundaries, scoped to users, roles, and services. Where SCPs focus on governance, IAM policies focus on access control.

IAM policies respond to operational needs: spinning up a server, reading from a bucket, or invoking a Lambda. They’re tied to personas and workflows. SCPs aren’t reactive—they’re proactive. They prevent entire categories of risk by making it impossible, for example, to run resources in unapproved regions or delete logging infrastructure. You attach them to an OU or account, not to a person or team. They don’t ask who’s making the request—they ask whether the action should be allowed in the first place.

Practical Interactions: What Happens When They Collide

Picture a case where an IAM role permits rds:DeleteDBInstance. That might be valid for a DBA in staging. But if there’s an SCP attached at the OU level that denies all rds:Delete* actions, the request dies on arrival even though the IAM policy is correctly configured. The SCP acts as a circuit breaker; it stops the action before it hits the IAM evaluation stage.

				
					{
  "Effect": "Deny",
  "Action": "rds:Delete*",
  "Resource": "*"
}

				
			

This pattern is useful when you want to freeze deletion privileges for production databases across all teams, regardless of what individual IAM roles allow. It eliminates the need to audit every permission grant manually.

Designing with Both in Mind

SCPs and IAM policies complement each other—they’re not redundant. SCPs set the baseline: no action outside this boundary will ever succeed. IAM policies then carve out what’s possible within that limit. You need both to build secure, usable systems at scale.

  • SCPs for enforcement consistency: You attach a deny policy at the org root to block access to us-gov-west-1. That boundary applies to every account, every user, everywhere—no exceptions.
  • IAM policies for scoped access: Within a dev account, a role might be granted ec2:StartInstances on tagged resources only. That permission lives and dies by the boundaries the SCP defines.

Let’s say your SCP allows EC2 use in us-east-1 and us-west-2 only. Any IAM policy granting access to eu-central-1 will silently fail. The IAM layer might say “yes,” but the organizational guardrails say “not here.” That’s the hierarchy in action. Permissions don’t matter if the action isn’t allowed in the first place.

Debugging the Disconnect

When teams miss how these layers interact, they chase ghosts. A user receives an “Access Denied” error, even though their IAM permissions look perfect. The issue isn’t IAM, it’s the SCP blocking the action upstream. The denial isn’t loud, but it’s absolute.

To avoid this, treat SCPs as immutable constraints and IAM policies as negotiable access. Use CloudTrail to observe denied API calls, especially during new policy rollouts. Tag IAM roles with context like Team or Environment, and combine that with SCP conditions to make policy decisions traceable and predictable.

For example, to restrict actions to roles tagged with Environment=prod, you can write:

				
					{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:PrincipalTag/Environment": "prod"
    }
  }
}

				
			

This blocks any untagged or mis-tagged role from performing actions, regardless of IAM permissions. That’s the kind of control IAM alone can’t give you—context-aware enforcement at the org level.

SCPs define what’s structurally off-limits. IAM policies define how people work within those limits. When designed together, they create a system where teams move fast without stepping over the line.

Step 5: Use Policy Builders and Testing Tools

Once your SCP footprint spans multiple OUs, manually writing policies becomes unsustainable. It’s not just the risk of syntax errors—it’s the inconsistency and policy drift that creep in when teams copy-paste JSON snippets without a clear baseline. Policy generators and builders help prevent this by standardizing structure, injecting required condition blocks, and enforcing naming conventions that reflect your internal taxonomy and compliance needs. They also allow teams to focus on the logic and intent of the control, not the formatting.

Many teams bake SCP templates into their infrastructure provisioning workflows. These templates serve as the starting point for new OUs and accounts, ensuring that guardrails are in place before developers even get access. This approach also helps detect deltas between what’s in version control and what’s actually attached across the org, closing down production drift before it becomes a security issue.

Treat Testing as Policy-Driven Observability

Before deploying any SCP to a live OU, replicate its entire policy path in a staging environment with active workloads. Don’t just attach a policy and check if it compiles—observe how it behaves under actual automation triggers, scheduled jobs, and role assumptions. This gives you a preview of how those same policies will behave in production, especially when dealing with inherited conditions or nested OUs.

To track the impact of new SCPs, inspect CloudTrail logs scoped to your staging accounts. Focus on denied operations that correlate with critical services or workflows—these are your early warning signs of potential breakages. For instance, if a pipeline fails silently after an SCP update, trace the role’s session and API call chain until you find the exact condition that blocked it. Use this feedback to adjust policy scope or introduce exception conditions before rollout.

Here’s a case that often catches teams off guard: a deny statement targeting all s3:DeleteBucket actions may appear safe, but if a scheduled cleanup job relies on temporary buckets, it could stall without any visible alert. Testing under realistic load and operational behavior helps uncover these hidden dependencies.

				
					{
  "Effect": "Deny",
  "Action": "s3:DeleteBucket",
  "Resource": "*",
  "Condition": {
    "StringNotLike": {
      "aws:PrincipalTag/Team": "infra-*"
    }
  }
}

				
			

This version of the policy introduces flexibility by allowing deletions only from roles tagged with the appropriate team prefix, making it easier to support exception workflows without weakening the default protection.

Validate Behavior Across Service Patterns and Organizational Units

Edge-case operations are where SCPs often create friction. These include things like cross-account IAM role assumptions, dynamic resource naming, or scheduled invocations of third-party services. Testing tools should account for these patterns, not just the primary workflows. Simulate activities like CloudFormation stack updates that modify IAM roles, or Lambda functions invoking services across regions with different condition keys in play.

Policy simulations and dry-run deployments help here, but only if your test cases reflect real operational behavior. Instead of building synthetic tests, use historical CloudTrail data to identify actual service usage and construct validation scenarios from those patterns. This ensures you’re testing how policies interact with the way your teams already use AWS, not in an idealized vacuum.

To support this, integrate SCP validation into your CI/CD pipelines. Whenever a new policy is created or updated, run it against a suite of known-good operations pulled from production logs. Any divergence, like a blocked call to kms:Decrypt during a backup job, should trigger a review. This isn’t just policy testing. It’s policy-driven observability. And the more your tooling reflects live infrastructure behavior, the more confident your team can be when deploying guardrails at scale.

Step 6: Monitor Continuous Compliance

SCPs don’t operate in a vacuum. They interact with everything, including new service rollouts, updated conditions, and restructured OUs. Your enforcement layer becomes outdated fast if you don’t actively track that evolution. Gaps don’t always break deployments; sometimes they just silently allow behaviors you thought you blocked.

To keep pace, treat each SCP like a living policy artifact. When AWS adds a new service or expands an API, validate whether your deny conditions still apply. If your policies rely on static service names or omit wildcards, unexpected access may slip through. Schedule validation passes are aligned with AWS release cycles and focus on high-risk services like IAM, EC2, and S3.

Automate Compliance Checks Across the Org Structure

Leverage automation to surface SCP drift before it causes problems. Set up scheduled jobs that scan all OUs for SCP coverage, flag accounts missing required policies, or detect policy statements that haven’t been updated in over six months. Include policy version metadata in your tagging conventions:

				
					"Tags": [
  {
    "Key": "PolicyDomain",
    "Value": "Infrastructure"
  },
  {
    "Key": "Version",
    "Value": "v1.3.2"
  }
]

				
			

This makes it easier to correlate what’s deployed with what’s in version control. For higher-sensitivity zones, build alerts for any change in attached SCPs, especially at the OU level. This approach gives you a real-time lens into where governance might be degrading.

CloudTrail logs still matter, but pair them with proactive insights. Look for patterns in denied actions related to new services or API versions. If your team starts adopting a new managed service like Bedrock or QLDB, and those APIs aren’t covered in your SCPs, you’re already behind.

Capture Friction and Feed It Into Policy Design

The fastest signal that something’s off isn’t in your logs—it’s in your Slack. Developers will complain when a deployment fails for no clear reason or when a CLI action gets blocked without explanation. These are early warnings that your SCPs might be too rigid or misaligned with how teams actually work.

Route those signals into a policy review loop. Maintain a lightweight issue tracker where denied actions are logged with the context: who, what service, what OU, and what time. This lets you trace patterns without over-indexing on one-off exceptions.

When you do need to make an exception, do it with surgical precision. Instead of relaxing an SCP across an entire OU, create a scoped policy that only allows the action under tightly defined conditions. For example, allowing kms:Encrypt only from a specific service role in a monitored pipeline:

				
					{
  "Effect": "Allow",
  "Action": "kms:Encrypt",
  "Resource": "arn:aws:kms:us-west-2:123456789012:key/example-key-id",
  "Condition": {
    "ArnEquals": {
      "aws:PrincipalArn": "arn:aws:iam::123456789012:role/DeployPipelineRole"
    }
  }
}

				
			

Or… so you would think.

AWS Organizations SCPs do not support the Condition element with “Effect”: “Allow”. According to AWS IAM Access Analyzer documentation, SCPs can only use conditions with “Effect”: “Deny”.

The correct approach is to use a “Deny” effect with a negated condition:

				
					{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyKMSEncryptExceptForDeployPipeline",
      "Effect": "Deny",
      "Action": "kms:Encrypt",
      "Resource": "arn:aws:kms:us-west-2:123456789012:key/example-key-id",
      "Condition": {
        "ArnNotEquals": {
          "aws:PrincipalArn": "arn:aws:iam::123456789012:role/DeployPipelineRole"
        }
      }
    }
  ]
}

				
			

This policy denies the KMS Encrypt action on the specific key for all principals EXCEPT the designated DeployPipelineRole, effectively creating the same exception but in a syntax that’s compatible with SCP requirements.

This keeps your policy posture intact while unblocking a legitimate workflow. As more of these scoped adjustments accumulate, your SCP library reflects how your infrastructure is actually used, not just how it was initially designed to be used.

Reasons to Keep SCPs Central to Your Strategy

SCPs are foundational to scaling secure operations in AWS. They act as guardrails and encode the organization’s intent into infrastructure. This removes ambiguity across teams and reduces reliance on manual enforcement or ad hoc IAM reviews. When structure replaces discretion, you get consistency without sacrificing autonomy.

Their value compounds in dynamic, multi-account environments. As new services are adopted or new teams onboard, SCPs give you a lever to enforce security posture without blocking innovation. They protect against bad actors and prevent drift from well-intentioned changes that bypass policy through oversight or unfamiliarity.

SCPs Act as a Transparent Enforcement Layer

Strong governance doesn’t require friction. SCPs enable clean, behind-the-scenes enforcement that doesn’t interrupt workflows but still ensures adherence to critical boundaries. For example, you can enforce encryption controls for S3 uploads without burdening each team with custom policy logic:

				
					{
  "Effect": "Deny",
  "Action": "s3:PutObject",
  "Resource": "*",
  "Condition": {
    "Null": {
      "s3:x-amz-server-side-encryption": "true"
    }
  }
}

				
			

This ensures all uploads comply with your encryption standards, without relying on developers to remember configuration details. More importantly, it removes the need to audit every role or bucket individually—compliance is embedded into the infrastructure layer.

Because SCPs apply at the AWS Organization level, they streamline governance conversations with auditors and security teams. You validate a few centralized controls instead of reviewing hundreds of IAM policies. This reduces audit scope and provides assurance that critical rules apply consistently, not just by convention.

SCPs Scale with Organizational Growth

Managing cloud at scale means designing for complexity before it arrives. SCPs do that by allowing you to define consistent boundaries across all accounts, regardless of who owns them or how they’re provisioned. That’s especially useful when teams use different IaC tools, CI/CD platforms, or permission models.

Take region restrictions: instead of updating every role to block unwanted geographies, a single SCP at the org root can enforce your location policy:

				
					{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:RequestedRegion": [
        "us-east-1",
        "us-west-2"
      ]
    }
  }
}


				
			

This policy applies uniformly, regardless of how a service is launched or by whom. It ensures workloads never land in unauthorized regions, even if a developer spins up a test stack using default settings. And because it lives high in the org hierarchy, you don’t have to replicate it manually across accounts or pipelines.

SCPs also help you contain failure. If a team misconfigures IAM permissions or mistakenly grants overbroad access, the SCP layer ensures that damage is capped. For example, a role with *:* permissions still can’t terminate RDS instances or disable CloudTrail if the SCP blocks those actions. That’s not just security—it’s resilience.

SCPs Define the Boundaries for Delegated Responsibility

As orgs grow, central teams can’t micromanage every permission. That’s where SCPs shine: they let you hand off IAM policy management to individual teams while still enforcing non-negotiable rules across the board. This shift enables decentralization without compromising control.

For example, you might allow application teams to manage their own KMS keys, but prevent deletion or disabling to protect data integrity:

				
					{
  "Effect": "Deny",
  "Action": [
    "kms:ScheduleKeyDeletion",
    "kms:DisableKey"
  ],
  "Resource": "*"
}


				
			

With this in place, teams can rotate keys, manage grants, and integrate encryption into their pipelines without risking permanent data loss. The SCP ensures that the lifecycle of those keys aligns with organizational policy and not just project needs.

This model creates a healthy separation of concerns. Platform or security leads define the outer boundary, while builders innovate freely inside it. It also improves onboarding: new projects can inherit tested, pre-approved policies without starting from scratch or introducing shadow exceptions.

SCPs aren’t just about prevention—they’re about enabling trust at scale. When used well, they reduce support burdens, eliminate guesswork, and foster a security culture that’s built into the infrastructure, not bolted on after.

Tips on Maintaining Long-Term Cloud Security

SCPs evolve with your infrastructure. As your org structure shifts, new services get introduced, and compliance requirements change, your policies must adapt without becoming fragile or opaque. Long-term security requires more than just enforcement—it demands clarity, structure, and operational feedback loops.

1. Embrace Version Control

SCPs should live in the same workflows as your infrastructure code. Keeping them in version control ensures every change is traceable and reversible, making it easier to test policy logic before rollout. You can also layer automated syntax validation into your CI/CD pipelines to prevent broken JSON or invalid statements from reaching production.

Organize policies by domain or OU scope, using a consistent file structure. Add structured annotations to each policy file to make audits easier, so you know who last modified it, why it changed, and what service area it governs.

				
					// org-root/global-deny-unapproved-regions.json
// Change owner: CloudSec Team
// Objective: Restrict AWS resource creation to approved regions (us-west-2, eu-west-1)
// Revised: 2024-05-12 based on updated data residency policy
{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringNotEquals": {
      "aws:RequestedRegion": [
        "us-west-2",
        "eu-west-1"
      ]
    }
  }
}


				
			

This approach reinforces accountability while allowing multiple teams to contribute to policy evolution without fear of regression.

2. Document Policy Intents

A policy without context is a liability. Teams need to understand what a policy does, why it exists, what risks it mitigates, and when it should be revised. Add internal documentation that walks through how the policy operates, what environments it applies to, and any known exceptions.

Rather than burying this explanation in separate docs, embed intent directly alongside the policy in your repos or dashboards. Use structured fields that describe the control objective, affected services, and operational considerations.

				
					// ou/dev/deny-large-instance-types.json
// Goal: Prevent resource bloat in dev environments
// Scope: Applies to EC2 RunInstances in all dev accounts
// Exception: Approved ML workloads may request overrides via ticket DEV-1432
{
  "Effect": "Deny",
  "Action": "ec2:RunInstances",
  "Resource": "*",
  "Condition": {
    "StringNotLike": {
      "ec2:InstanceType": [
        "t3.*",
        "t2.*"
      ]
    }
  }
}

				
			

This gives reviewers and developers instant clarity on the policy’s role in the broader cloud governance strategy. It also makes incident response smoother—teams can quickly determine whether a block was intentional or a policy needs refinement.

3. Stay Current

SCPs must track AWS’s service and feature changes, or they’ll fall behind without warning. AWS regularly introduces new APIs, expands condition key support, and sometimes deprecates older actions. If your policies don’t reflect those shifts, you risk either over-permitting or silently failing to block new capabilities.

Build a lightweight review cadence into your governance model. Every few months, scan your SCPs against the latest AWS Organizations documentation and IAM updates. Check for new services your teams are adopting and validate whether your guardrails still apply.

				
					// ou/ai/deny-unvetted-genai-services.json
// Reason: Block newer AI/ML services pending internal review
{
  "Effect": "Deny",
  "Action": [
    "bedrock:*",
    "qldb:*"
  ],
  "Resource": "*"
}

				
			

This type of control offers breathing room while your security team evaluates new capabilities. It also prevents accidental exposure from services launched with default open settings.

Treat policy upkeep as a feedback loop, not a checklist. Monitor denied actions across your org, review incidents where SCPs intervened, and adjust based on real-world friction. When policies evolve with your environment, not just react to it, they strengthen security without slowing teams down.

Make SCPs the Heart of Your Cloud Governance Strategy

The real power of SCPs lies in their ability to operationalize decisions that would otherwise live in documents or Slack threads. They express intent in code, directly in the infrastructure, so policies don’t get lost in translation between security and engineering. Once in place, they quietly influence every deployment, every API call, every attempt to push beyond what was agreed.

When teams work inside known constraints that are defined up front, it changes how systems are designed. Patterns emerge—naming, tagging, provisioning—that naturally align with guardrails without the constant oversight. This predictability compounds; as environments scale, the friction doesn’t.

You don’t need a massive governance overhaul to see impact. A handful of organization-wide SCPs can eliminate entire classes of risk, like accidental use of legacy services or untagged resources slipping through cost reporting. And because SCPs apply automatically to new accounts and OUs, they create a default-secure posture from day one. There’s no extra policy work required.

Well-structured SCPs don’t just survive growth, they anticipate it. As services evolve and teams shift, the boundaries they enforce stay relevant because they’re tied to core principles, not temporary configurations. They evolve through policy changes, not architecture rewrites, and that separation makes them resilient.

Master Guide for AWS SCPs: Frequently Asked Questions

Does an SCP override all other IAM or resource policies?

Yes. SCPs act as the first checkpoint in AWS Organizations. Any action not permitted by an SCP is blocked before IAM or resource policies are evaluated. Even with a full-access IAM policy, the operation won’t pass through if the SCP denies a specific action or service. This makes SCPs ideal for enforcing organization-wide safeguards that shouldn’t be bypassed, regardless of how permissive internal IAM roles might be.

They also help you isolate concerns: IAM handles granular access per role or user, while SCPs ensure no one, anywhere, can cross defined boundaries. Think of them less as permissions and more as global constraints baked into your account structure.

Do I need separate SCPs for each OU?

Only when their control requirements differ. In most setups, a single SCP can govern multiple OUs if they share operational or compliance characteristics. For instance, all sandbox environments might inherit a deny policy that restricts access to production-only services, while production OUs layer additional controls for data residency or encryption standards.

Instead of duplicating policies, use inheritance strategically. Design SCPs to reflect logical groupings like environment type, sensitivity, or team ownership, so you maintain clarity without bloating your policy set. When exceptions are needed, apply them at the OU or account level with scoped conditions rather than creating entirely new policies.

Are SCPs suitable for smaller setups?

Yes, especially when you’re laying the groundwork for future scale. Even with just a few accounts, SCPs help enforce discipline from the start, reducing the chance of accidental missteps like launching resources in unapproved regions or disabling key logs. They also simplify onboarding: every new account inherits the same base controls without requiring manual setup.

For smaller orgs, lightweight SCPs that deny a handful of risky actions—like deleting KMS keys or modifying CloudTrail—deliver outsized impact with minimal overhead. That structure also sets the stage for future automation and compliance tracking as your organization grows.

How do I handle fast-growing environments?

Use repeatable policy patterns and lean on automation. Fast-moving orgs benefit from a modular SCP library that covers common scenarios, like region restrictions, tagging enforcement, or environment-specific service access. Attach these policies during account provisioning so guardrails are in place before infrastructure is deployed.

Track usage patterns through CloudTrail and periodically audit for services not yet reflected in your SCPs. When new AWS features are added, review whether your controls cover them, or if they introduce permissions you want to restrict. Keep policy ownership distributed but structured, with policy files versioned and reviewed like application code. This way, you scale governance without bottlenecks.

SCPs give you the structure to grow securely, without getting buried in permission sprawl or reactive fire drills. When you treat them as part of your infrastructure, not just a compliance checkbox, you unlock both agility and control.

If you found this guide useful, subscribe to the blog to stay updated on new posts and insights—we break down complex cloud strategies so you can focus on building.

Discover the Latest From Tamnoon

There’s always more to learn, see our resources center

Scroll to Top

Join us for

CNAPP Decoded: Alerts, Remediations, and CNAPP Best Practices 1x a Month

Join 2,300+ Cloud Security leaders looking to master their CNAPP with expert remediation tips and best practices to test in your own CNAPP today.