# The hosted zones that serve name resolution, each marked private or public so internal and external resolution can be shown to be served by separate zones, and the Resolver endpoints that carry queries across the VPC boundary with their direction and operational status

> FedRAMP Consolidated Rules for 2026 v2026.07.14.01 · updated 2026-07-14
> Canonical page: /collect/name-resolution-role-separation

Recipe id: `name-resolution-role-separation` · cadence continuous · partial

> **Authored opinion.** AWS overlay v3.0.0, written
> against dataset 2026.07.14.01. The upstream
> FedRAMP rules name none of these tools; this mapping is ours.

## What it proves

- KSI `KSI-SVC-SIN`
- control `sc-22`

## Collection

Kind: `cli`

```sh
# list-hosted-zones
aws route53 list-hosted-zones
# list-resolver-endpoints
aws route53resolver list-resolver-endpoints
```

## Expected output

From list-hosted-zones, HostedZones[] with Id, Name, CallerReference, ResourceRecordSetCount, an optional LinkedService naming the AWS service that created the zone, and Config carrying Comment and PrivateZone — a boolean, and the ONLY field that separates an internal zone from an external one. Read its absence as public: AWS documents PrivateZone true as private and false-or-absent as public, so a clause testing for equality with false misses the zones where Config never appears. From list-resolver-endpoints, ResolverEndpoints[] with Id, Arn, Name, CreatorRequestId, HostVPCId, SecurityGroupIds, IpAddressCount, a ResolverEndpointType of IPV4, IPV6 or DUALSTACK, a Direction of INBOUND, OUTBOUND or INBOUND_DELEGATION, and a Status of CREATING, OPERATIONAL, UPDATING, AUTO_RECOVERING, ACTION_NEEDED or DELETING.

## Assertions

- {"field":"list-hosted-zones.HostedZones[?Config.PrivateZone==`true`] | [0].Id","op":"exists","controls":["sc-22"],"description":"At least one private hosted zone exists — internal name resolution is served by a zone of its own rather than by the public one. The pipe is load-bearing: without it the [0] indexes each matched zone rather than the filtered list."}
- {"field":"list-hosted-zones.HostedZones[?Config.PrivateZone!=`true`] | [0].Id","op":"exists","controls":["sc-22"],"description":"At least one public hosted zone exists, so the separation asserted above is a separation of two live roles rather than an account that simply has no external presence. Written as != true rather than == false deliberately: AWS documents a public zone as PrivateZone false OR ABSENT, and an equality test against false misses every zone whose Config omits the field."}
- {"field":"list-resolver-endpoints.ResolverEndpoints[?Status!='OPERATIONAL']","op":"count_eq","value":0,"controls":["sc-22"],"description":"No Resolver endpoint is stuck in CREATING, UPDATING, AUTO_RECOVERING, ACTION_NEEDED or DELETING. This is the health of YOUR crossing points and is not evidence of fault tolerance in the resolution service itself, which is AWS's to demonstrate. Zero on an account with no Resolver endpoints, which is a normal architecture rather than a pass."}

## GovCloud

Route 53 is available in both AWS GovCloud (US) Regions with public and private DNS and health checking, and AWS states that public-zone DNS queries are answered from within the FedRAMP boundary — which is itself worth quoting in an assessment. The control plane for Route 53 in GovCloud is in AWS GovCloud (US-West), so these calls are issued there. Four documented differences bear on this recipe. Route 53 RESOLVER DELEGATION is not available for private hosted zones, so an architecture that separates roles by delegating a private subtree cannot be built there and the separation has to be zone-level. Alias targets may point at GovCloud Regions only, never at global AWS Regions. IP-based routing, the console DNS query checking tool and the TestDNSAnswer API are all unavailable, so there is no in-account way to verify what an external resolver actually receives. And the customer managed key for DNSSEC signing and the CloudWatch Logs group for query logging must both be in AWS GovCloud (US-West), where CloudWatch metrics such as DNSQueries can also be found. All Route 53 API actions there share a token bucket of capacity 40 refilling at 5 per second, which matters for a collector that walks many zones.

## Notes

SC-22 asks two things of the systems that collectively provide name and address resolution: that they be FAULT-TOLERANT, and that they implement INTERNAL AND EXTERNAL ROLE SEPARATION. This output answers the second and cannot answer the first.

Role separation is a field. Config.PrivateZone marks each hosted zone as serving internal or external resolution, and an architecture where internal names are served from private zones associated with VPCs while public names are served from public zones is exactly the separation the control describes — visible, enumerable, and reviewable on the cadence the indicator asks for. Resolver endpoints are collected beside the zones because they are where the two roles actually meet: an INBOUND endpoint lets on-premises resolvers query into the VPC, an OUTBOUND endpoint forwards VPC queries out, and each one is a crossing point that the zone list alone does not show.

Fault tolerance is not a field and is not measurable from your account. Route 53's resilience is a property of AWS's anycast name server fleet, not of your configuration, and no call against your account returns it. It is inherited under the shared responsibility model and evidenced from AWS's own authorization package — say so in the assessment rather than presenting a zone list as though it spoke to availability. The one adjacent thing this output does show is whether YOUR crossing points are healthy, which is what the Status clause below asserts, and that is endpoint health rather than service fault tolerance. Conflating them would be the whole control's failure in one line.

A scope edge that decides whether this evidence means anything: name resolution is only separated if the two zone sets actually differ. Two hosted zones for the same domain, one private and one public, is split-horizon DNS and is a legitimate and common pattern — but so is a single public zone answering internal names, which satisfies neither role separation nor the control, and the assertions below cannot tell those apart because the grammar compares a field to a constant rather than one zone's Name to another's. Reconcile the two zone sets by name as part of the review.

A private hosted zone also cannot be DNSSEC-signed, which is why signing is a separate recipe and not folded in here. And LinkedService is worth reading before anything is concluded from a zone's presence: a zone created by another AWS service on your behalf is inventory rather than architecture.

One KSI only. KSI-SVC-SIN — information secured from unwanted access — is what a private zone does, by keeping internal names off the public resolvers. The recipe does not claim the identity indicator that also reaches this control in the dataset: nothing in these two responses evaluates a permission.

## References

- {"title":"AWS CLI: route53 list-hosted-zones (HostedZones[] with Config.PrivateZone as the private/public discriminator, plus Id, Name, CallerReference, ResourceRecordSetCount and LinkedService)","url":"https://docs.aws.amazon.com/cli/latest/reference/route53/list-hosted-zones.html"}
- {"title":"AWS CLI: route53resolver list-resolver-endpoints (Direction INBOUND | OUTBOUND | INBOUND_DELEGATION; Status CREATING | OPERATIONAL | UPDATING | AUTO_RECOVERING | ACTION_NEEDED | DELETING; ResolverEndpointType IPV4 | IPV6 | DUALSTACK)","url":"https://docs.aws.amazon.com/cli/latest/reference/route53resolver/list-resolver-endpoints.html"}
- {"title":"AWS GovCloud (US) User Guide: Amazon Route 53 — public-zone queries answered from within the FedRAMP boundary, control plane in GovCloud (US-West), Resolver delegation unavailable for private hosted zones, TestDNSAnswer and IP-based routing unavailable, DNSSEC signing key must be in US-West","url":"https://docs.aws.amazon.com/govcloud-us/latest/UserGuide/govcloud-r53.html"}
