You open the VPC console because a partner asked which source range will arrive over the Site-to-Site VPN. The NAT gateways page shows a public gateway with an Elastic IP attached, and the temptation is to send that address and move on. It is the right answer for the internet path and the wrong answer for the VPN path, and the difference is which gateway the route table points at. Walk the route before you write the allowlist.

Start at the NAT gateways page, not the allowlist

The NAT gateways page tells you the subnet, the type and the Elastic IP, and those three fields are enough to start. What it does not tell you is the path the traffic takes afterwards. That comes from the route tables attached to the NAT gateway's subnet.

Read the type first, because public or private decides whether an internet gateway appears later in the chain. Then read the subnet, because that is where the second route lives.

Follow the two translations

Both public and private NAT gateways translate the workload's private IPv4 source into the NAT gateway's own private IPv4 address. That first translation happens regardless of type. The second translation is the one people forget: a public NAT gateway hands traffic to the internet gateway, which maps the address to the associated Elastic IP.

workload 10.20.1.5 -> NAT gateway 10.20.2.10 -> internet gateway -> Elastic IP 203.0.113.25
workload 10.20.1.5 -> NAT gateway 10.20.2.10 -> transit or virtual private gateway -> partner sees 10.20.2.10

On the private path there is no internet gateway in the chain. When traffic leaves through a transit gateway or a virtual private gateway, the NAT gateway guide documents the NAT gateway's private address as the source the remote side receives. That is the address the partner should allow, not the Elastic IP.

The VPN path usually shows the private address

For a workload in 10.20.1.0/24 reaching a partner prefix, the workload subnet's route table points at the NAT gateway, and the NAT gateway's subnet route table points at the private gateway path. Both hops matter, and only the second one decides what the partner sees. If the NAT subnet has no route to the VPN path, the packet never arrives, which is a different failure from a wrong source address.

Verify that second route before you discuss addresses at all. A missing route and a misreported source look identical to a partner who is simply not seeing traffic.

When a second translation changes the answer

AWS also offers an explicit, matching one-to-one NAT mapping on a transit gateway attachment. That mapping can translate the source again before the remote service sees it, and it is not the default routing-only behaviour. Because it has to be configured deliberately, treat it as a design exception rather than something you inherit by accident. If nobody on your team remembers turning it on, assume it is absent until you have read the attachment.

If your design uses it, the allowlist has to describe the final mapping rather than the NAT gateway's address. The same caution applies to availability paths: when several gateway addresses participate, the expected source set is the union, not one representative address. Write down which translation each address belongs to, because a list without provenance is impossible to audit later.

A private NAT gateway cannot be given internet service by pointing it at an internet gateway; AWS documents that such traffic is dropped. Choose the type from the full path, not from the word VPN in the requirement.

Write the contract your partner can act on

The usable contract has four parts: the direction flows are initiated, the translated identity the partner will see, the return route for that identity, and the protection scope that applies. NAT gateway flows are initiated from the supported originating side, so this is not an inbound port-forwarding service for exposing a private workload. Saying that out loud early prevents a design review where each side assumed the other was initiating.

Translation buys address-overlap relief and a predictable source policy, and it costs you individual workload identity in the partner's logs. If audit needs per-workload attribution, keep that identity at the application layer instead of trying to recover it from a translated source address.

Then re-check both route tables after any change, because a new attachment or a re-associated subnet silently rewrites the answer.

Makomi ya ndenge moko