Skip to main content
Back
DateRead7 min

AWS Declarative Policies vs SCPs: What's the Difference?

The verdict: Use SCPs to control what IAM principals are allowed to do. Use Declarative Policies to enforce what service configurations must always look like. They address different problems, operate at different layers of the AWS stack, and most mature AWS organizations will want both.

What Each One Actually Does

Both SCPs and Declarative Policies live inside AWS Organizations. Both can be applied at the organization root, OU, or account level. Both prevent things that shouldn't happen. That's where the structural similarity ends.

SCPs are authorization policies. They work at the IAM layer by limiting the maximum permissions available to IAM principals (users, roles, and root users) within the accounts they apply to. When a principal tries to call an API, AWS checks whether the SCP allows it before evaluating any identity-based policy. If the SCP doesn't permit the action, the call is denied, regardless of what the identity policy says. SCPs don't grant permissions on their own; they set a ceiling on what's possible.

Declarative Policies are management policies. They don't operate at the IAM layer at all. Instead, they declare a desired configuration state for a specific AWS service, and that state is enforced directly in the service's control plane. The practical meaning of that: when a principal calls an API that would violate the declared configuration, the service rejects the action regardless of what IAM permissions that principal holds. The enforcement isn't happening at the identity layer; it's happening inside the service itself. That's why new API paths, new features, new accounts, and new principals don't create gaps. The configuration is maintained continuously because it's part of how the service behaves, not a filter sitting in front of it.

A Declarative Policy looks structurally different from an SCP. Rather than Allow/Deny policy statements with Action and Resource blocks, a Declarative Policy is a set of attribute declarations: key-value pairs that define the required state for a given service. There's no IAM policy JSON involved. You're not saying "deny ec2:ModifyVpcAttribute"; you're saying "VpcBlockPublicAccessExclusions must always be in this state." AWS handles enforcement from there.

Side-by-Side Comparison

DimensionService Control Policies (SCPs)Declarative Policies
What it controlsIAM principal permissions (actions principals can take)Service configuration state
Enforcement layerIAM authorization layerService control plane
Policy languageIAM policy JSON: Allow/Deny statements with Action, Resource, Condition blocksAttribute declarations: key-value pairs defining desired service state, no IAM syntax
What it can blockAny API action across supported servicesConfiguration attributes for supported services only
Service coverageVirtually all AWS servicesCurrently EC2, EBS, and VPC configurations (expanding)
Applies to service-linked roles?No. Service-linked roles are AWS-managed and exempt from SCPs.Yes. Enforcement is at the service level, not the identity level, so all principals are covered.
Applies to the management account?No. SCPs never apply to the management account, even when attached at the root.Yes. Declarative policies do apply to the management account, so a root attachment governs it too. This is the opposite of SCP behavior and is easy to miss.
Survives new AWS APIs and features?Only if the SCP explicitly addresses themYes. Maintained automatically as AWS ships new capabilities.
Policy size limit10,240 characters per policy10,000 characters per policy
Custom error messages?NoYes. Configurable per policy to redirect users to internal docs or ticketing systems.
Account status reporting?No built-in equivalentYes. An account status report shows the current enforcement state for each attribute across every account in scope, so you can see where configuration is compliant before enforcing.
Where it fits in policy hierarchyAuthorization policyManagement policy

Decision Framework

The clearest way to think about the choice: are you trying to prevent an action, or enforce a state?

If a principal shouldn't be able to perform a class of actions (assuming a role in another account, creating IAM users, provisioning certain instance types, calling APIs outside an approved region), an SCP is the right tool. SCPs express your permission ceiling. They answer the question: "What are principals allowed to do?"

If a service must always be in a particular configuration state (VPC Block Public Access always on, public AMI sharing always blocked, EBS encryption always enforced) and that state needs to hold regardless of who does what or what AWS ships next, a Declarative Policy is the right tool. Declarative Policies answer the question: "What does this service always look like?"

A practical test: if what you're trying to prevent requires blocking a specific API call or set of API calls, start with an SCP. If what you're trying to enforce is a service-level attribute that should be continuously maintained and shouldn't depend on catching every possible API path, start with a Declarative Policy. And if a Declarative Policy doesn't yet exist for your use case, an SCP is still the right interim tool.

Quick reference:

GoalUse
Block principals from creating public S3 bucketsSCP (deny PutBucketAcl with public-access conditions)
Enforce VPC Block Public Access across all accountsDeclarative Policy
Prevent IAM role assumption from outside the orgSCP
Enforce EC2 AMI block public sharing org-wideDeclarative Policy
Restrict which AWS regions principals can operate inSCP
Enforce EBS encryption by default across accountsDeclarative Policy
Prevent use of certain EC2 instance typesSCP
Prevent internet gateway attachment to VPCsDeclarative Policy (VPC Block Public Access attribute)

Using Both Together: A Worked Scenario

Consider an organization enforcing a data perimeter across its production accounts. The security team wants to ensure two things: principals in those accounts can't exfiltrate data to resources outside the organization, and no production VPC can have public internet egress regardless of how it was configured or who is making changes.

The access control requirement (preventing data from leaving the org) is an SCP problem. The team writes a policy that denies certain S3 and STS actions when the request destination is outside the org's resource perimeter. SCPs are the right tool here because the intent is to restrict what principals can do across a range of API calls.

The network configuration requirement (ensuring no VPC in production has public egress) is a Declarative Policy problem. Rather than writing SCPs that try to enumerate every API that could create or modify an internet gateway attachment, the team applies VPC Block Public Access through a Declarative Policy. If a developer with full EC2 permissions attempts to modify a VPC in a way that would violate the declared state, the service rejects the action. It doesn't matter if AWS later ships a new API path, adds a feature, or if a new account joins the OU. The baseline holds because it's enforced at the service level, not at the identity layer.

The two policies work at different layers and reinforce each other. Neither one alone would satisfy both requirements.

Where Teams Get This Wrong

Using SCPs to enforce configuration state, then watching them drift. Before Declarative Policies existed, SCPs were the closest available tool for enforcing service configuration. Teams wrote deny policies against specific API calls: denying DisableEbsEncryptionByDefault, denying ModifyVpcAttribute with specific parameters. This works, but it's brittle. When AWS ships a new API path that achieves the same configuration change, the SCP doesn't cover it. Teams still relying on SCPs for configuration enforcement should evaluate whether a Declarative Policy now covers their use case.

Underestimating the service coverage limitation. Declarative Policies currently support EC2, EBS, and VPC configurations. That's meaningful coverage for network and compute, but it doesn't cover IAM, S3, organizational controls, or most other services. Teams that start thinking of Declarative Policies as an SCP replacement will hit this wall quickly. SCPs remain the primary tool for access control, and for services not yet covered by Declarative Policies, they're still the only organization-level option.

Forgetting that Declarative Policies apply to service-linked roles. SCPs don't apply to service-linked roles. Those roles are AWS-managed and exempt from SCP restrictions. Because Declarative Policies enforce configuration at the service level rather than the identity level, service-linked roles don't create a gap. For teams trying to enforce network isolation or image sharing restrictions that could otherwise be bypassed through a service-linked role, this distinction is material.

FAQ

Can Declarative Policies and SCPs conflict?

They can't conflict in a meaningful way because they operate at different layers. What's worth understanding is that a Declarative Policy doesn't block an API call the way an SCP does; it enforces the configuration outcome at the service level. So if a principal with full IAM permissions calls an API that would violate a Declarative Policy, the service rejects the action directly, independent of any SCP evaluation. Both can be in place simultaneously, and an action could theoretically be blocked by either one for different reasons.

Do Declarative Policies count against the SCP quota?

No. Declarative Policies are a separate policy type within AWS Organizations and have their own quota. They don't affect the SCP quota of 10 policies per root, OU, or account. This matters for organizations already running close to that limit and would otherwise need to consolidate or restructure SCPs to fit new controls.

How do Declarative Policies interact with AWS Control Tower guardrails?

AWS Control Tower supports Declarative Policy-based controls as a guardrail implementation type. When Control Tower manages a Declarative Policy on your behalf, it appears in AWS Organizations like any other Declarative Policy, but Control Tower tracks compliance and surfaces it through its own dashboard. Teams running Control Tower should check whether a desired control is already available as a managed guardrail before creating a standalone Declarative Policy for the same attribute.

What happens when a new account joins an OU that has a Declarative Policy?

The Declarative Policy is applied automatically and the service configuration is brought into compliance for that account. This is part of the "set once and forget" guarantee. The same applies when new resources are created within an account. The account status report makes it possible to verify compliance state before and after a new account joins.

How does Native help with both?

Native connects the controls already present in your AWS environment (including SCPs and Declarative Policies) to the architectural intent behind them. That means your security team can see where access control policies and configuration baselines are holding, where they've drifted, and what the current state is across accounts and OUs, without manually auditing each one. See how Native works across your AWS environment.

Ready to enforce secure-by-design?