How CubeEgress Implements Domain Allowlisting and Egress Traffic Inspection in TencentCloud/CubeSandbox
CubeEgress enforces application-layer egress policies through a first-match-wins rule engine where domain allowlists are implemented by placing permitted hosts before a deny-all rule, while L7 inspection is achieved via configurable actions including header injection and detailed audit logging.
CubeEgress is the security component within TencentCloud/CubeSandbox that governs outbound application-layer traffic for sandboxed workloads. By transforming sandbox configurations into deterministic policy rules, it enables fine-grained control over which external domains are accessible and provides deep packet inspection capabilities. Understanding how CubeEgress implements domain allowlisting and egress traffic inspection requires examining the policy structures in network-agent/internal/service/types.go and the translation logic in network-agent/internal/service/cubeegress_push.go.
Policy Architecture and First-Match-Wins Semantics
The foundation of CubeEgress security lies in its rule-based policy engine. According to the source code in network-agent/internal/service/types.go, each EgressRule consists of a Match condition and an Action directive. The engine evaluates rules sequentially against outbound connections until the first match succeeds, making order-critical for security posture.
Domain Allowlisting Implementation
Domain allowlisting leverages this first-match-wins behavior to create explicit permit lists. When a sandbox configuration specifies permitted hosts in the Host field of an EgressRuleMatch, the policy generator creates a rule containing a Hosts array. As explicitly noted in sdk/go/policy.go, "allowing specific domains is meaningful only when all all other egress is denied."
To implement a functional allowlist, administrators must structure the Rules array with explicit allow entries enumerating trusted domains, followed by a terminal deny-all rule. This configuration ensures that only traffic matching the enumerated hosts passes through, while all other egress attempts trigger the final denial rule.
// Build a policy that only allows example.com and api.myservice.com
cfg := &CubeNetworkConfig{
Rules: []EgressRule{
{
Match: EgressRuleMatch{
Host: []string{"example.com", "api.myservice.com"},
},
Action: EgressRuleAction{
Allow: true,
},
Name: "allow-list-domains",
},
{
// Fallback rule – deny everything else
Action: EgressRuleAction{
Deny: true,
},
Name: "deny-all-others",
},
},
}
pol := toEgressInput(cfg) // internal conversion, see cubeegress_push.go
err := egClient.PutPolicy(ctx, sandboxIP, pol)
L7 Traffic Inspection and Audit Mechanisms
Beyond access control, CubeEgress performs deep L7 inspection through the ActionInput type defined in network-agent/internal/cubeegress/wire.go. The Inject action enables request modification in-flight, allowing the system to append custom HTTP headers for authentication, tracing, or audit marking.
Each rule carries a mandatory human-readable Name field that propagates into audit logs. This creates an immutable attribution trail, identifying exactly which policy rule authorized or denied specific egress traffic. The combination of injection capabilities and named rules provides comprehensive visibility into sandbox network behavior.
// Inspect HTTP traffic: inject a header for audit
cfg.Rules[0].Action.Inject = []Inject{
{Header: "X-Cube-Audit", Value: "sandbox-123"},
}
Network-Agent Integration and Policy Lifecycle
The network-agent serves as the control plane for CubeEgress policy distribution, handling translation, delivery, and lifecycle management.
Policy Translation and Push Logic
In network-agent/internal/service/cubeegress_push.go, the conversion pipeline begins with toEgressInput, which transforms internal CubeNetworkConfig structures into the cubeegress.PolicyInput wire format. This function delegates to toMatchInput and toActionInput to serialize match conditions and actions respectively. The agent then invokes egress.PutPolicy to push the constructed policy to the CubeEgress admin API endpoint.
Error Handling and Retry Semantics
The push mechanism implements discriminating retry logic with a 2-second timeout defined by the egressRetryCallTimeout constant. Transient network failures trigger automatic retry attempts, while permanent errors—such as malformed rule specifications—are logged immediately without retry to prevent infinite loops. This distinction ensures policy eventual consistency without masking configuration errors.
// Network-agent pushes the policy (simplified)
if s.egress != nil && s.egress.Configured() {
in := toEgressInput(cfg)
if err := s.egress.PutPolicy(ctx, state.SandboxIP, in); err != nil {
// retry logic handled inside cubeegress_push.go
}
}
Policy Deletion on Teardown
When sandboxes terminate, network-agent/internal/service/local_service.go invokes egress.DeletePolicy to ensure immediate cleanup of egress rules. This prevents stale policies from persisting after workload completion, maintaining the integrity of the network security boundary.
Summary
- First-match-wins evaluation in
network-agent/internal/service/types.goenables deterministic domain allowlisting by ordering explicit permits before deny-all rules. - L7 inspection is achieved through the
Injectaction inActionInput, supporting header modification for audit and tracing. - Policy lifecycle management in
cubeegress_push.goconverts configurations usingtoEgressInputand handles delivery with 2-second timeout retries. - Cleanup guarantees are enforced via
DeletePolicycalls when sandboxes terminate, preventing policy leakage.
Frequently Asked Questions
How does CubeEgress determine which rule applies when multiple rules match a connection?
CubeEgress evaluates rules in the order they appear in the Rules array, stopping at the first match. This first-match-wins semantics means you must place specific allow rules before broad deny rules to implement effective allowlisting, as implemented in the policy engine from network-agent/internal/service/types.go.
What happens if the CubeEgress admin API is unavailable when the network-agent pushes a policy?
The network-agent implements retry logic with a 2-second timeout (egressRetryCallTimeout) for transient failures, as defined in cubeegress_push.go. However, permanent errors such as malformed rules are logged and not retried, ensuring the system does not indefinitely attempt to push invalid configurations.
Can CubeEgress modify HTTP headers for security auditing?
Yes. The ActionInput struct supports an Inject field that allows injecting custom HTTP headers into outbound requests. This capability enables audit trails by adding identifying headers—such as X-Cube-Audit with sandbox identifiers—before traffic leaves the sandbox environment.
Where is the domain allowlist logic documented in the CubeSandbox SDK?
The semantic requirement for domain allowlisting—specifically that allowing specific domains is only meaningful when all other egress is denied—is documented in sdk/go/policy.go. This file contains the high-level SDK comments explaining how host-based rules interact with default-deny policies.
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 →