How CubeEgress Implements L7 Domain Filtering and Credential Injection

CubeEgress enforces outbound policies by evaluating requests against ordered rules that match SNI, host, method, and path criteria, then injects credentials from its internal vault into HTTP headers before forwarding traffic.

CubeEgress is the Layer-7 egress proxy component of TencentCloud's CubeSandbox project that governs all outbound traffic from sandboxed workloads. The system combines declarative policy definitions in Go with runtime enforcement in Lua to provide granular control over external API access. Understanding how CubeEgress handles L7 domain filtering and credential injection reveals the complete path from configuration to request modification.

Policy Structure and Configuration

Defining Egress Rules in CubeNetworkConfig

The network-agent builds a CubeNetworkConfig object defined in service/types.go that contains a list of EgressRule objects. Each rule is divided into two distinct sections: a Match section that specifies L7 criteria, and an Action section that determines the resulting behavior.

cfg := &service.CubeNetworkConfig{
    Rules: []*service.EgressRule{
        {
            Name: "llm‑auth",
            Match: &service.EgressRuleMatch{
                Host:   ptrString("api.openai.com"),
                Method: []string{"POST"},
            },
            Action: &service.EgressRuleAction{
                Allow: true,
                Inject: []*service.EgressRuleInject{
                    {
                        Header: "Authorization",
                        Secret: "openai‑api‑key",
                        Format: ptrString("Bearer ${SECRET}"),
                    },
                },
            },
        },
    },
}

The Match Section

The Match struct supports filtering by SNI, host, method, path, and scheme. These fields allow precise targeting of outbound requests based on TLS Server Name Indication indicators or HTTP-layer properties. When the policy is pushed to CubeEgress, these rules populate the policy.rules[] array stored in the proxy's memory.

L7 Domain Filtering Implementation

Rule Evaluation Order

CubeEgress processes rules sequentially using a first-match-wins strategy. During the access phase, the Lua script stored in CubeEgress/lua/access_phase.lua iterates through the rule set until it finds a match or exhausts the list. This ordering guarantees deterministic behavior when multiple rules could potentially apply to a single request.

Domain Matching Logic

The actual comparison logic relies on a helper function named domain_match, which supports both exact string matches and wildcard suffix patterns such as *.example.com. The script extracts the request's SNI and host headers, then validates them against the rule's sni and host fields. If no rule satisfies the request criteria, CubeEgress applies a default deny action, blocking the outbound connection.

Credential Injection Workflow

Secret Vault Integration

When a rule's action.inject array is present, each entry specifies a header name and a secret reference via the InjectInput structure. Secrets are stored in CubeEgress's internal credential vault, isolated from the sandbox environment. The reference name (e.g., openai-api-key) acts as a lookup key during request processing.

Header Injection at Runtime

After a rule matches, the Lua code in access_phase.lua (around line 330) processes the injection list. For each entry, it calls secret_store.get(inj.secret) to retrieve the plaintext value from the vault. If a format field is provided, the code substitutes the ${SECRET} placeholder with the actual secret value—commonly used to prepend Bearer tokens or other schemes. Finally, the script calls ngx.req.set_header(inj.header, secret) to append the credential to the outbound HTTP request before it leaves the sandbox.

-- inside access_phase.lua, after a rule has been selected
if rule.action.inject then
    for _, inj in ipairs(rule.action.inject) do
        local secret = secret_store.get(inj.secret)
        if inj.format then
            secret = inj.format:gsub("${SECRET}", secret)
        end
        ngx.req.set_header(inj.header, secret)
    end
end

Policy Translation Pipeline

From Go Structs to JSON

To ensure consistency between the network-agent's view and CubeEgress's runtime, the codebase uses cubeegress/wire.go to translate Go structs into the exact JSON shape required by the admin API. The PolicyInput and RuleInput types mirror the Lua-side structure, eliminating drift between freshly created policies and those restored after a CubeEgress restart.

policyIn := cubeegress.PolicyInput{
    Rules: []cubeegress.RuleInput{
        {
            Name: "llm‑auth",
            Match: &cubeegress.MatchInput{
                Host:   ptrString("api.openai.com"),
                Method: []string{"POST"},
            },
            Action: &cubeegress.ActionInput{
                Allow: true,
                Inject: []cubeegress.InjectInput{
                    {
                        Header: "Authorization",
                        Secret: "openai‑api‑key",
                        Format: ptrString("Bearer ${SECRET}"),
                    },
                },
            },
        },
    },
}
jsonBody, _ := cubeegress.RenderEgressPolicy("sandbox‑123", &policyIn)

Validation and Storage

Before activation, the payload sent to PUT /admin/v1/policies/<sandbox_ip> undergoes validation in CubeEgress/lua/policy.lua. This step verifies that match criteria are well-formed and that referenced secrets exist in the vault, preventing incomplete or broken policies from entering the enforcement path.

Summary

  • CubeEgress stores policies in an ordered array where the first matching rule wins, ensuring deterministic evaluation
  • Domain filtering supports exact matches and wildcard suffixes via the domain_match Lua helper in access_phase.lua
  • Unmatched requests are denied by default, providing a secure zero-trust baseline for outbound connectivity
  • Credential injection retrieves secrets from the internal vault via secret_store.get() and injects them using ngx.req.set_header()
  • The translation pipeline in cubeegress/wire.go guarantees policy consistency across Go, JSON, and Lua representations

Frequently Asked Questions

What happens if a request doesn't match any egress rule?

CubeEgress implements a default-deny security model. If the Lua matching logic in access_phase.lua iterates through the entire policy.rules[] array without finding a match, the request is blocked and denied egress from the sandbox.

How does wildcard domain matching work in CubeEgress?

The domain_match helper function supports suffix patterns such as *.example.com. During evaluation, it compares the request's SNI or host header against the rule's domain criteria, allowing subdomains to match without requiring explicit rules for each endpoint.

Where are injection secrets stored?

Secrets referenced in the inject array are stored in CubeEgress's internal credential vault, not in the sandbox configuration. At runtime, the Lua environment retrieves these values via secret_store.get(), ensuring sensitive material remains isolated from sandboxed code.

Can multiple headers be injected for a single rule?

Yes. The inject field is an array of EgressRuleInject objects, allowing a single matched rule to populate multiple HTTP headers simultaneously. Each entry can reference different secrets and apply distinct formatting templates.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →