How CubeEgress Domain Allowlist Filtering Works for Egress Traffic
CubeEgress enforces domain-based egress filtering by validating that domain allowlists require a default-deny posture, then applies first-match-wins rules to permit traffic only to specified domains while blocking all other outbound connections.
In the TencentCloud/CubeSandbox repository, CubeEgress domain allowlist filtering provides Layer 7 egress control by restricting outbound traffic to specific domain names while denying all other internet access. This security mechanism ensures that sandboxed workloads can only communicate with approved external endpoints, preventing data exfiltration to unauthorized destinations. The implementation spans the SDK validation layer, the network-agent translation service, and the CubeEgress enforcement engine.
Policy Structure and Domain Allowlisting
When you configure egress rules through the Go, Python, or Node SDK, you construct a network.rules object containing match criteria (host, SNI, path, method) and action directives (allow, inject, or audit). The critical field for domain filtering is allowOut (or allow_out in Python), which accepts an array of domain names or CIDR blocks.
However, domain-based entries in allowOut trigger a strict validation requirement. According to the source code in sdk/go/policy.go, the system mandates that all other egress traffic must be explicitly denied when using domain allowlists. This prevents security gaps where domain allowances might coexist with permissive default internet access.
The Domain Validation Logic
The function validateAllowOutDomainsRequireDenyAll in sdk/go/policy.go (lines 60-86) enforces this contract. If isDomainAllowOutTarget detects at least one domain name in the allowOut list, the validation accepts the request only when either:
defaultDenyAllis set totrue(viaallowInternetAccess=false), ordenyOutincludes the wildcard CIDR0.0.0.0/0.
If neither condition is satisfied, the SDK returns an APIError with the message allowOutDomainRequiresDenyAll (lines 62-66).
Domain Detection Algorithm
The helper function isDomainAllowOutTarget distinguishes domain names from IP addresses through several checks implemented in sdk/go/policy.go (lines 92-144):
- Trims whitespace and rejects empty strings or strings containing "/".
- Rejects any string that successfully parses as an IP address using
net.ParseIP. - Rejects dotted-decimal-like strings (e.g.,
192.168.1) viaisDottedDecimalLike. - Accepts DNS-style names, including wildcard prefixes like
*.example.com, throughisValidDNSDomainName.
This ensures that only valid domain patterns trigger the strict deny-all requirement, while pure CIDR-based policies can operate under different egress postures.
Policy Translation and Enforcement
Once validated, the network-agent translates your CubeNetworkConfig into a cubeegress.PolicyInput structure. In network-agent/internal/service/cubeegress_push.go (lines 52-71), the toEgressInput function populates the Rules slice with cubeegress.RuleInput objects, preserving the match and action semantics from your SDK configuration.
The CubeEgress service evaluates these policies using first-match-wins semantics, as documented in network-agent/internal/service/types.go. When a request's SNI or Host header matches a domain listed in allowOut, the corresponding rule with allow: true permits the traffic to pass, optionally injecting credential headers. Any request failing to match an explicit allow rule gets blocked by the default deny rule, which is active when defaultDenyAll is enabled.
Implementation Examples
The following examples demonstrate how to configure a sandbox that allows egress only to api.example.com while blocking all other outbound traffic.
Go SDK:
opts := cubesandbox.SandboxOptions{
Network: cubesandbox.NetworkOptions{
AllowOut: []string{"api.example.com"},
// Deny all other traffic by disabling public egress:
AllowInternetAccess: false,
},
}
sandbox, err := client.CreateSandbox(ctx, opts)
Python SDK:
policy = cubesandbox.Policy(
allow_out=["api.example.com"],
allow_internet_access=False,
)
sandbox = client.create_sandbox(policy=policy)
Node SDK:
const policy = {
allowOut: ["api.example.com"],
allowInternetAccess: false,
};
await client.createSandbox({ policy });
All three examples trigger the validation in validateAllowOutDomainsRequireDenyAll. If allowInternetAccess were omitted, the SDK would automatically add denyOut: ["0.0.0.0/0"] to satisfy the contract that domain allowlisting requires explicit denial of all other traffic.
Key Source Files
The domain allowlist filtering implementation spans these critical locations in the TencentCloud/CubeSandbox repository:
sdk/go/policy.go– Contains thevalidateAllowOutDomainsRequireDenyAllvalidation function (lines 60-86) and domain detection logicisDomainAllowOutTarget(lines 92-144).network-agent/internal/service/cubeegress_push.go– Implements thetoEgressInputfunction (lines 52-71) that translatesCubeNetworkConfigintocubeegress.PolicyInput.network-agent/internal/service/types.go– Defines theEgressRulestructure and documents the first-match-wins evaluation semantics.sdk/python/_policy.py– Mirrors the Go validation logic for the Python SDK.sdk/node/src/policy.ts– Implements equivalent domain validation for the Node.js SDK.
Summary
- Domain allowlisting in CubeEgress requires explicit denial of all other egress traffic via
defaultDenyAllor a0.0.0.0/0entry indenyOut. - The
validateAllowOutDomainsRequireDenyAllfunction insdk/go/policy.goenforces this security contract across all SDKs. - Domain detection distinguishes DNS names from CIDR blocks using
net.ParseIPand pattern matching against dotted-decimal strings. - The network-agent translates SDK configurations into
cubeegress.PolicyInputobjects and pushes them to the CubeEgress admin API. - CubeEgress applies first-match-wins evaluation, allowing traffic to specified domains while blocking all non-matching outbound requests.
Frequently Asked Questions
Why does CubeEgress require denying all other traffic when using domain allowlists?
CubeEgress mandates a default-deny posture for domain allowlists to prevent security bypasses. If you could specify allowed domains while simultaneously permitting general internet access, the domain restrictions would be meaningless. The validation function validateAllowOutDomainsRequireDenyAll in sdk/go/policy.go enforces this by checking that either defaultDenyAll is true or denyOut contains 0.0.0.0/0.
How does CubeEgress distinguish between a domain name and an IP address in the allowOut list?
The SDK uses the isDomainAllowOutTarget function, which attempts to parse the string as an IP using net.ParseIP, rejects dotted-decimal patterns like 192.168.1, and validates DNS syntax including wildcards such as *.example.com. Strings containing "/" are immediately rejected as CIDR blocks rather than domains.
What happens if a request matches multiple egress rules?
CubeEgress evaluates rules using first-match-wins semantics as implemented in the enforcement engine. The first rule in the policy whose match criteria (host, SNI, path, method) satisfies the request determines the action—whether to allow, inject credentials, or audit the traffic. Subsequent rules are ignored for that specific request.
Can I use wildcard domains in the allowOut list?
Yes, the domain validation supports wildcard prefixes like *.example.com. The isValidDNSDomainName function in sdk/go/policy.go accepts these patterns, allowing you to authorize entire subdomains while maintaining the strict deny-all requirement for other egress traffic.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →