Home› Blog› AWS Daily Intelligence #45 - A Regional override r…
AWS Daily Intelligence AWS

AWS Daily Intelligence #45 - A Regional override replaces the default, it does not extend it

Verified against current vendor documentation on 2 October 2026. Pricing, limits and API behaviour were checked against the official docs on that date. Cloud services change fast — if you are reading this much later, treat the specifics as a starting point and re-check the linked sources.

Executive summary

GuardDuty now supports AWS Organizations declarative policies, so you can “centrally enable GuardDuty threat detection across every account and Region in your AWS organization.” All commercial Regions and GovCloud (US).

This is the right mechanism for the job, and the reason is worth stating precisely: declarative policies are “enforced in the service's control plane, which is an important distinction from authorization policies such as service control policies (SCPs) and resource control policies (RCPs)… While authorization policies regulate access to APIs, declarative policies are applied directly at the service level to enforce durable intent.” An SCP can stop someone turning GuardDuty off. Only a declarative policy turns it on.

But the syntax has a rule that inverts what most people will assume, and it costs coverage rather than throwing an error. A Region block replaces the default; it does not add to it.

What changed

One policy type, GUARDDUTY_POLICY, attachable to the root, an OU or an account, governing the foundational detector and every protection plan together. Eight keys:

Policy keyGuardDuty feature
foundationalFoundational threat detection
s3_data_eventsS3 Protection
eks_audit_logsEKS Protection
ebs_malware_protectionMalware Protection (EBS volumes)
rds_login_eventsRDS Protection
lambda_network_logsLambda Protection
ai_protectionAI Protection
runtime_monitoringRuntime Monitoring, with EKS, ECS Fargate and EC2 agent management

And it takes over the old controls rather than sitting beside them. “While a GuardDuty organization policy is active, the Regional GuardDuty auto-enablement configurations no longer apply, and the per-account controls on the GuardDuty Accounts page are managed by the policy and shown as read-only, marked Managed by Organization policy.”

That is the correct design — two systems both claiming to decide enablement is how drift starts — but it means the policy is now the only place the answer lives.

Architecture

Diagram: how a GuardDuty declarative policy decides coverage per Region, and the three ways a Region ends up with no protection. The policy document nests a guardduty key, an enablement key, and then one or more blocks: an optional default block that applies to every Region where GuardDuty is available, and optional Region-specific blocks keyed by Region name. A policy must contain at least one block. The resolution rule is that a Region-specific block fully replaces the default for that Region and is not merged with it, so any feature omitted from a Region block is not inherited from the default. A Region with neither a default block nor a Region-specific block is unmanaged: the policy neither enables nor disables GuardDuty there and existing settings are left unchanged. Within any block, foundational threat detection must be enabled if any other feature in that same block is enabled. Three failure paths are drawn. First, a Region override written to disable one feature, which silently drops every other feature the default had enabled in that Region unless all of them are re-listed. Second, a policy with no default block, where every unnamed Region is unmanaged and, because new Regions are only automatically included when a default block is used, no future Region is ever covered. Third, detaching the policy, where the general declarative-policy rule is that the attribute state rolls back to its previous state, but GuardDuty documents an exception: GuardDuty remains enabled in previously covered accounts, while future accounts joining or moving into the organizational unit are no longer automatically enabled, so what is lost is future enablement rather than current coverage. A panel contrasts the policy types: service control policies and resource control policies control maximum access permissions at an API level and do not govern service-linked roles, whereas declarative policies enforce the desired configuration of a service without using API actions, are enforced in the service control plane, and do govern service-linked roles. A closing panel notes that policies are managed by the Organizations delegated administrator, that the configuration policy pages are available only to that account, that multiple policies merge into an effective policy with more specific policies closer to the account taking precedence, and that the authored form using the at-at-assign inheritance operator differs from the effective form returned by DescribeEffectivePolicy.
Three ways a Region ends up uncovered. None of them is an error.

The resolution rule, in AWS's words

The policy is a default block plus optional Region blocks. What happens when both exist is the whole post:

“A Region-specific block fully replaces the default for that Region; it is not merged with it. List every feature you want in that Region, because any feature omitted from a Region block is not inherited from default.”

AWS's own Example 2 is built around this. The stated intent is narrow — disable EBS malware protection in one Region — and the policy is not short: “Because a Region block fully replaces the default, the us-east-1 block re-lists every feature it wants active in that Region.”

So the override carries foundational and s3_data_events set to enabled, purely to keep what the default already gave it, plus the one key it actually came to change. Drop those two lines and us-east-1 loses S3 Protection and the detector itself — from a policy whose diff reads as "turn off malware protection".

And the third state is neither on nor off

“A Region that has neither a default block nor a Region-specific block is unmanaged. The policy neither enables nor disables GuardDuty there, and existing settings are left unchanged.”

Unmanaged is not a failure — AWS's Example 4 uses it deliberately, for “when you want a policy to govern GuardDuty in a specific set of Regions without asserting any baseline for the rest.” The problem is that unmanaged looks exactly like covered on any dashboard that only lists what the policy says.

And it has a second-order cost, because the forward guarantee is attached to one block specifically: “New Regions are automatically included when using the default block in a policy.” A policy that names Regions and omits default covers no Region AWS opens in future. The "set once and forget" property is not a property of declarative policies in general; it is a property of having a default.

The detach behaviour is a documented exception, and it reads the other way

The general rule for every declarative policy type: “If a declarative policy is detached, the attribute state will roll back to its previous state before the declarative policy was attached.”

Read that and you would expect detaching a GuardDuty policy to switch GuardDuty off wherever the policy had turned it on. It does not:

“If you detach an Amazon GuardDuty policy, Amazon GuardDuty remains enabled in previously covered accounts. However, future changes to the organizational structure (such as new accounts joining or existing accounts moving into the OU) no longer automatically enable Amazon GuardDuty. Any further enablement must be performed manually or through re-attaching a policy.”

This is the safer of the two behaviours and it is worth knowing which one you have: detaching costs you nothing today and everything going forward. Current coverage is unharmed, so nothing alarms; the enablement guarantee is gone, so the next account created is uncovered. The gap appears at the moment somebody creates an account, which is weeks after the change that caused it.

Where the general page and the service page disagree, the service page wins

Both statements are current and neither is wrong — the general page states the declarative-policy rule, and GuardDuty documents its own departure from it. That is a reasonable way to write documentation and a bad way to be read: anyone who learned declarative policies from the Organizations page and then applied that knowledge to GuardDuty would predict the opposite outcome. Read the service's own page for every declarative policy type you attach, specifically for the detach paragraph.

Business value

The thing being removed is a class of audit finding rather than a quantity of work. The old model was Regional auto-enablement plus per-account controls, which meant coverage was a property of how carefully somebody had clicked, Region by Region, and a new Region opted into by a team was a coverage gap by default.

“The baseline configuration for an AWS service is always maintained, even when the service introduces new features or APIs. The baseline configuration is also maintained when new accounts are added to an organization or when new principals and resources are created.”

The clause about new features matters more here than it sounds. GuardDuty has added protection plans repeatedly — RDS, Lambda, Runtime Monitoring, AI Protection. Under the old model each one arrived switched off and needed a fresh enablement campaign. Under a declarative policy the key exists to be enabled once.

Security considerations

It governs service-linked roles, and the authorization policy types do not. AWS's comparison table answers "Governs service-linked roles?" with No for SCPs, No for RCPs and Yes for declarative policies. For a detection service that works through a service-linked role, that is the difference between a control that applies and one that has a hole in it.

It is enforcement without an API surface — declarative policies work “by enforcing the desired configuration of an AWS service without using API actions.” So there is no Deny for a member account to work around and no API call to condition on.

The delegation is explicit and narrow. “GuardDuty policies are managed by the AWS Organizations delegated administrator… The Configuration policies pages in the GuardDuty console are available only to the delegated administrator account.” The management account designates it and attaches the delegation policy. That is the pattern #36 describes for permissions boundaries, applied here: the delegate gets the task, bounded.

Pair it with an SCP rather than choosing between them. The declarative policy enables GuardDuty and keeps it enabled; an SCP denying guardduty:Delete* and guardduty:Disassociate* closes the permission path. They answer different questions and the names make them sound like alternatives.

Cost considerations

The announcement states no charge for the policy mechanism, and that is the uninteresting half. The interesting half is that this is a switch that turns on billed analysis across every account and Region at once, and the protection plans are priced on volume — S3 data events, EKS audit logs, RDS login activity, Lambda network logs, EBS volume scans.

So a default block with every key enabled is a cost decision taken in one line, in Regions nobody has looked at. The feature gating does not help you here: “A feature listed in a Region where it is not yet available has no effect in that Region” — so an unavailable feature is free and silent today, and starts billing the day the Region gets it, with no change on your side.

That is the same shape as the coverage trap, pointing the other way. Enable the plans you want deliberately, and treat a broad default as a forward commitment rather than a current one.

Operational considerations

Read the effective policy, not the one you wrote. “Multiple policies can apply to a single account and are merged into an effective policy… More specific policies (closer to the account) take precedence.” With a root policy and OU policies in play, the document you are looking at is not the answer for any particular account.

The two forms of the document differ, and the difference will catch a diff. “Child policies set values using the @@assign inheritance operator. The authored form (for example {"status": {"@@assign": "enabled"}}) is distinct from the effective form returned by DescribeEffectivePolicy (which resolves to plain {"status": "enabled"}).” Comparing authored JSON against DescribeEffectivePolicy output textually reports a difference on every key.

The account status report is the surface worth wiring up. It “allows you to review the current status of all attributes supported by declarative policies for the accounts in scope” — which is the only thing that distinguishes unmanaged from enabled without reading every policy in the tree.

Custom error messages exist and are worth writing. You can “create customizable error messages, which can help administrators redirect end users to internal wiki pages or provide a descriptive message that can help end users understand why an action failed”. A control-plane refusal with no explanation becomes a support ticket.

Tradeoffs

ChoiceYou getYou give up
default only Every current and future Region covered; the strongest version of the guarantee Per-Region nuance, and cost control in Regions you do not use
default plus Region overrides Per-Region feature sets with a baseline underneath Every override must re-list the full feature set or it silently subtracts
Named Regions, no default Precise scope; untouched settings everywhere else No automatic coverage of new Regions, ever
Declarative policy instead of per-account setup Enablement that survives new accounts and new features The Accounts page goes read-only; the policy is the only control

Implementation guidance

Prerequisites, in order: “Enable trusted access for the GuardDuty service in AWS Organizations… Enable the GUARDDUTY_POLICY policy type on the organization root. This is done automatically when the delegated administrator creates the first policy in the GuardDuty console.”

The shape to start from is AWS's Example 1 — a single default block with foundational enabled, attached at the root. One key, every Region, every account, every future account. Then add protection plans deliberately, and keep the number of Region overrides as close to zero as the requirements allow.

Two syntax rules that will reject or surprise you: “Within any block, foundational must be enabled if any other feature in that same block is enabled”, and “A policy must contain at least one block.”

For runtime_monitoring, the agent management sub-features sit in a nested object: additional_configuration carrying eks_addon_management, ec2_agent_management and ecs_fargate_agent_management, each with its own status. It is the only feature with sub-features, so it is the only one where the nesting is deeper than you would guess from the others.

Best practices

Treat every Region block as a complete feature list, never as a patch. Generate them rather than hand-editing, so the full set is always emitted; a hand-edited override is one deleted line away from dropping the detector.

Include a default block unless you have a reason not to, and write the reason down next to the policy. It is the only thing that covers Regions that do not exist yet.

Review the account status report, not the policy, when asked whether you are covered. The policy tells you what was asserted; the report tells you what is true, including the Regions where nothing was asserted at all.

Before detaching, read the detach paragraph for that specific policy type. GuardDuty leaves coverage in place and drops the forward guarantee. Another declarative policy type rolls the attribute back. Those are opposite outcomes from the same action.

Who should act on this

Anyone running GuardDuty across more than a handful of accounts should move enablement to a policy and delete the per-Region auto-enablement habit, because the policy supersedes it anyway.

Anyone who already wrote Region overrides — in a pilot, or in another declarative policy type with the same model — should re-read them against the replacement rule today. This is the one item here that can already be wrong rather than becoming wrong later.

Anyone whose coverage evidence is a policy document should replace it with the account status report. A policy cannot show you an unmanaged Region; it can only fail to mention it.

Key takeaways

A Region block replaces the default rather than extending it, so an override has to re-state everything it wants to keep. Omitting default leaves every unnamed Region unmanaged and forfeits automatic coverage of future Regions. Detaching leaves current coverage intact and silently ends future enablement, which is the opposite of the general declarative-policy rule.

All three are the same failure: a configuration that is absent rather than wrong. That is also exactly what #36 is about on the permissions side — an action missing from a permissions boundary behaves differently from one denied in it, and the document looks the same either way. Today's #70 is the third instance: a role trust policy with no aws:SourceArn condition is reachable by every certificate authority in the account.

The two halves fit together. A declarative policy states the configuration that must hold; an SCP or RCP states the permissions that must not be exceeded. Neither substitutes for the other, and in both the thing that bites is what you did not write down.

Official AWS references

Comments

How was your experience?
Your feedback helps improve this site.
PoorExcellent