CubeEgress Architecture for Domain Allowlisting and Credential Injection
CubeEgress implements a first-match-wins L7 egress firewall that filters traffic via domain allowlisting and injects credentials through HTTP header manipulation before forwarding requests.
CubeEgress is the Layer 7 egress firewall integrated into the TencentCloud CubeSandbox network stack. Its architecture enables secure outbound communication by combining domain-based access control with dynamic credential injection. Understanding the internal data model and policy propagation flow is essential for operators configuring egress rules in production environments.
Core Components of the CubeEgress Architecture
The CubeEgress engine is built around four interconnected data structures defined in network-agent/internal/service/types.go.
EgressRule – The Policy Container
The EgressRule struct (line 130) serves as the user-facing rule object that expresses what to allow or modify. Each rule contains:
- An
EgressRuleMatchclause defining trigger conditions - An
EgressRuleActionclause defining the resulting operation
The network-agent evaluates rules in order, implementing first-match-wins semantics. Once a request satisfies a match condition, the corresponding action executes and evaluation stops.
EgressRuleMatch – Domain Allowlisting Logic
Domain allowlisting lives inside the EgressRuleMatch struct (line 138). This component supports matching on:
- SNI (Server Name Indication)
- Host (IP addresses, CIDR ranges, exact domains, or wildcards like
*.example.com) - Path and Method for HTTP-specific filtering
The helper function extractL7AllowOutTargetsFromRules in service.go walks the rule slice to collect all allowed destinations for bookkeeping and validation purposes.
EgressRuleAction and EgressRuleInject – Credential Injection
When a match succeeds, the EgressRuleAction struct (line 148) determines the outcome. The action can:
- Allow the request (
Allow: true) - Inject credentials via the
Injectfield containing a slice ofEgressRuleInjectobjects
The EgressRuleInject struct (line 155) defines the credential-injection descriptor with fields for the header name, value, and optional secret references (e.g., ${TOKEN}). The embedded Lua bootstrap in CubeEgress expands these values into HTTP request headers before forwarding to the downstream service.
How Domain Allowlisting Works
When a request enters the CubeSandbox network stack, CubeEgress evaluates the rule list against the connection attributes:
- The Host field of
EgressRuleMatchaccepts plain domains (api.example.com), CIDR notation (10.0.0.0/8), or wildcard patterns (*.internal.com) - The engine performs string matching against the SNI or HTTP Host header
- The first matching rule determines the fate of the connection
This approach allows administrators to implement strict egress controls, permitting connections only to explicitly enumerated external APIs or internal services.
How Credential Injection Works
Credential injection operates as a modifier on allowed requests:
- If a rule's
action.injectslice is non-empty, CubeEgress prepares header injection - Each
EgressRuleInjectspecifies the header name and value, which can contain interpolation syntax for dynamic secrets - The network-agent expands these templates (e.g.,
"Bearer ${TOKEN}") before the policy reaches CubeEgress - CubeEgress attaches the resolved headers to the HTTP request before forwarding
This mechanism enables secure authentication to external APIs without exposing credentials to the sandboxed workload.
Policy Lifecycle and Push Mechanism
The network-agent manages the transition from configuration to active enforcement through a resilient push mechanism.
Configuration Conversion
The CubeNetworkConfig struct converts to the CubeEgress admin API format via toEgressInput. This conversion:
- Clones rule slices to prevent mutability bugs
- Drops nil fields to minimize payload size
- Validates rule consistency before transmission
The unit test TestToEgressInputDropsNilFields verifies this sanitization logic.
Best-Effort Push and Retry
The pushEgressForState function issues a PUT request to the CubeEgress admin endpoint at /policy/<sandbox-ip>. This operation is best-effort:
- Transient failures set the
pendingEgressPushflag - The lifecycle loop invokes
retryPendingEgressPushes(defined intap_lifecycle.go) to retry failed pushes - Permanent errors clear the flag to prevent infinite retry loops
The test TestPushEgressForStateSuccessClearsPending validates this state machine behavior.
Code Implementation Examples
Creating Rule Lists in Go
rules := []*network_agent.EgressRule{
{
Match: &network_agent.EgressRuleMatch{Host: ptr("api.example.com")},
Action: &network_agent.EgressRuleAction{Allow: true},
},
{
Match: &network_agent.EgressRuleMatch{Host: ptr("private.internal")},
Action: &network_agent.EgressRuleAction{
Allow: true,
Inject: []*network_agent.EgressRuleInject{
{Header: "Authorization", Value: "Bearer ${TOKEN}"},
},
},
},
}
cfg := &network_agent.CubeNetworkConfig{
SandboxID: "sb-01",
SandboxIP: "10.0.2.3",
Rules: rules,
}
Pushing the Policy
svc := network_agent.NewService(cfg) // builds local_service with egress client
if err := svc.PushEgressForState(ctx, state); err != nil {
log.Fatalf("failed to push egress: %v", err)
}
Policy JSON Structure
{
"rules": [
{
"match": { "host": "api.example.com" },
"action": { "allow": true }
},
{
"match": { "host": "private.internal" },
"action": {
"allow": true,
"inject": [{ "header": "Authorization", "value": "Bearer ${TOKEN}" }]
}
}
]
}
Summary
- CubeEgress operates as an L7 firewall inside the CubeSandbox network stack, implementing first-match-wins rule evaluation
- Domain allowlisting uses
EgressRuleMatch.Hostwith support for IPs, CIDRs, domains, and wildcards as defined innetwork-agent/internal/service/types.go - Credential injection occurs via
EgressRuleInject, which adds HTTP headers before forwarding requests to external services - Policy propagation follows a best-effort push model with
pendingEgressPushretry logic managed intap_lifecycle.go - The conversion layer in
local_service.goensures immutable rule cloning and nil-field sanitization before transmission to the CubeEgress admin API
Frequently Asked Questions
How does CubeEgress resolve conflicts between overlapping rules?
CubeEgress evaluates the EgressRule slice sequentially, implementing first-match-wins semantics. When a request satisfies the EgressRuleMatch conditions of multiple rules, only the action of the first matching rule executes. Administrators must order rules from most specific to least specific to ensure correct policy enforcement.
What credential sources does CubeEgress support for header injection?
The EgressRuleInject struct supports static values and dynamic interpolation via the ${VARIABLE} syntax. The network-agent expands these references from environment variables or secrets before pushing the policy to CubeEgress. The actual header injection occurs within the CubeEgress Lua bootstrap before the request leaves the sandbox network.
Where is the retry logic implemented for failed policy pushes?
The retry mechanism resides in network-agent/internal/service/local_service.go and tap_lifecycle.go. The pushEgressForState function sets a pendingEgressPush flag when transient errors occur, and the lifecycle loop calls retryPendingEgressPushes to re-attempt transmission. Permanent errors clear this flag to prevent infinite retries.
How can I verify which domains are allowed by my current policy?
Use the DumpEgressPolicies function or examine the extractL7AllowOutTargetsFromRules helper in service.go. This function walks the rule list and extracts all allowed destinations, returning the complete set of domains, IPs, and CIDR ranges that the sandbox can reach through the egress firewall.
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 →