# How CubeEgress Implements L7 Domain Filtering and Credential Injection

> Discover how CubeEgress implements L7 domain filtering and credential injection through ordered rules and secure HTTP header forwarding, enhancing outbound policy enforcement.

- Repository: [Tencent Cloud/CubeSandbox](https://github.com/TencentCloud/CubeSandbox)
- Tags: how-to-guide
- Published: 2026-07-11

---

**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`](https://github.com/TencentCloud/CubeSandbox/blob/main/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.

```go
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`](https://github.com/TencentCloud/CubeSandbox/blob/main/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`](https://github.com/TencentCloud/CubeSandbox/blob/main/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.

```lua
-- 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`](https://github.com/TencentCloud/CubeSandbox/blob/main/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.

```go
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`](https://github.com/TencentCloud/CubeSandbox/blob/main/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`](https://github.com/TencentCloud/CubeSandbox/blob/main/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`](https://github.com/TencentCloud/CubeSandbox/blob/main/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`](https://github.com/TencentCloud/CubeSandbox/blob/main/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.