Locking Down UAT Egress: What to Whitelist for External APIs

When your UAT environment needs to call third-party APIs, give it only the network access it truly needs — nothing more. This checklist and the sample rules help you keep UAT safe, compliant, and predictable.

  1. UAT
  2. Egress
  3. Zero Trust
  4. Firewall
  5. API Security

 

Quick Checklist: What to Whitelist

Item Examples Notes
Primary API domains api.stripe.com, graph.microsoft.com, api.sendgrid.com Prefer FQDN allow-lists. If vendor provides IP ranges, subscribe to their feed but expect changes.
Auth/token endpoints login.microsoftonline.com, oauth2.googleapis.com Many APIs require separate OAuth hosts. Don’t forget device code or JWKS endpoints if applicable.
Supporting services Vendor CDNs (*.cloudfront.net), telemetry (dc.services.visualstudio.com) Only if strictly required by the SDK. Block generic wildcards where possible.
Ports & protocols tcp/443 (HTTPS) Deny 80, 25, 22 unless explicitly needed. Enforce TLS1.2+.
DNS resolution Resolver: internal or approved forwarder Restrict DNS so UAT can’t resolve arbitrary domains. Log queries.
Outbound identity UAT API keys, UAT OAuth apps Never reuse prod secrets. Store in a vault. Rotate regularly.
Egress source IPs NAT gateway / firewall public IPs Pin vendor allow-lists to these IPs. Keep UAT egress distinct from prod.
Quotas & rate limits Per-destination throttling Prevents runaway tests from DDoS’ing a vendor or incurring costs.
Principle: Deny by default. Explicitly allow only the exact FQDNs and ports your UAT calls need. Log every egress connection; alert on anything outside the list.

Architecture Patterns

1) Egress via NAT/Firewall + FQDN Rules

  • All UAT subnets route 0.0.0.0/0 to a centralized egress (NAT/Firewall).
  • Firewall policy allows only HTTPS to approved FQDNs.
  • DNS resolution flows through an internal resolver you control/log.

2) Explicit Web Proxy

  • UAT workloads are forced to use an authenticated proxy.
  • Proxy enforces domain allow-lists and injects identity headers only where required.
  • Single choke point for content filtering, TLS inspection (where permitted), and logging.

Sample Rules

Azure: Firewall Policy (FQDN-based)

{
  "ruleCollectionGroups": [{
    "name": "uat-egress",
    "priority": 200,
    "ruleCollections": [{
      "name": "allow-apis",
      "priority": 100,
      "action": { "type": "Allow" },
      "rules": [{
        "name": "allow-stripe",
        "ruleType": "ApplicationRule",
        "protocols": [{ "protocolType": "Https", "port": 443 }],
        "sourceAddresses": ["10.20.0.0/16"],
        "targetFqdns": ["api.stripe.com"]
      },{
        "name": "allow-msft-graph",
        "ruleType": "ApplicationRule",
        "protocols": [{ "protocolType": "Https", "port": 443 }],
        "sourceAddresses": ["10.20.0.0/16"],
        "targetFqdns": ["graph.microsoft.com", "login.microsoftonline.com"]
      }]
    },{
      "name": "deny-all",
      "priority": 900,
      "action": { "type": "Deny" },
      "rules": [{
        "name": "block-rest",
        "ruleType": "ApplicationRule",
        "protocols": [{ "protocolType": "Http", "port": 80 }, { "protocolType": "Https", "port": 443 }],
        "sourceAddresses": ["10.20.0.0/16"],
        "targetFqdns": ["*"]
      }]
    }]
  }]
}

AWS: VPC + Security Group (egress tighten)

Security Groups don’t support FQDNs; pair them with a NAT Gateway + Network Firewall for domain rules. At minimum, restrict SG egress to 443 and route through the firewall.

# Security Group (egress only to 443)
aws ec2 authorize-security-group-egress \
  --group-id sg-XXXX \
  --ip-permissions '[
    {"IpProtocol":"tcp","FromPort":443,"ToPort":443,"IpRanges":[{"CidrIp":"0.0.0.0/0"}]}
  ]'

# AWS Network Firewall (domain list) snippet via Suricata-style rules
pass tls $HOME_NET any -> $EXTERNAL_NET 443 (tls.sni; content:"api.stripe.com"; endswith; msg:"allow stripe"; sid:100001;)
pass tls $HOME_NET any -> $EXTERNAL_NET 443 (tls.sni; content:"graph.microsoft.com"; endswith; msg:"allow graph"; sid:100002;)
drop tls $HOME_NET any -> $EXTERNAL_NET 443 (msg:"deny unknown domains"; sid:199999;)

Proxy (Squid) Domain Allow-List

# /etc/squid/whitelist.txt
api.stripe.com
graph.microsoft.com
login.microsoftonline.com

# /etc/squid/squid.conf (excerpt)
acl allowed dstdomain "/etc/squid/whitelist.txt"
http_access allow allowed
http_access deny all
acl HTTPS_ports port 443
acl CONNECT method CONNECT
http_access allow CONNECT HTTPS_ports

Operational Controls

  • Separate UAT credentials: distinct OAuth apps/API keys from prod; scope to least privilege.
  • Secret handling: use a vault; never embed in code or images. Rotate regularly.
  • DNS controls: internal resolver, logging, and (optionally) domain filtering.
  • Monitoring: centralize egress logs; alert on connections to non-approved hosts.
  • Change management: any new third-party API requires a ticketed update to the allow-list.
  • Rate limiting: throttle UAT to avoid vendor abuse and surprise bills.
  • Segregation: different egress IPs and rulesets for UAT vs prod; no shared service accounts.

Summary

Deny by default, allow the exact FQDNs and ports your tests need, and log everything. Pair tight network policy with proper identity, secret hygiene, and rate limits. UAT stays useful for testing — without becoming an easy path for data leaks or lateral movement.

Anuj holds professional certifications in Google Cloud, AWS as well as certifications in Docker and App Performance Tools such as New Relic. He specializes in Cloud Security, Data Encryption and Container Technologies.

Initial Consultation

Anuj Varma – who has written posts on Anuj Varma, Hands-On Technology Architect, Clean Air Activist.