How CubeSandbox Security Proxy Performs Credential Injection: A Deep Dive into CubeProxy
CubeSandbox injects credentials dynamically by intercepting outbound HTTP requests at the CubeProxy layer, matching them against egress policies defined in network.rules, and injecting rendered secret values as HTTP headers before forwarding traffic to external services.
The CubeSandbox security proxy, known as CubeProxy, enforces Layer 7 egress policies to secure outbound traffic from sandboxed workloads. When a sandbox initiates an HTTP request, the proxy performs credential injection by fetching secrets from the CubeMaster secret store and attaching them as headers to authenticated requests. This process ensures that sensitive credentials never reside in sandbox code while enabling secure access to external APIs.
The CubeProxy Credential Injection Architecture
CubeProxy operates as a Layer 7 security proxy within the CubeSandbox network-agent, specifically inside the cubeegress component. When a sandbox initiates an outbound HTTP request, the proxy evaluates the traffic against configurable egress policies that define both access controls and credential injection rules.
The injection mechanism relies on the Inject struct defined in sdk/go/policy.go, which specifies how secrets should be formatted and inserted into request headers. The proxy coordinates with the CubeMaster secret store to resolve secret values at runtime, ensuring that credentials remain confined to the sandbox's secure storage.
Step-by-Step Credential Injection Process
When an HTTP request reaches CubeProxy, the system executes a four-phase injection workflow:
Policy Lookup and Rule Matching
The proxy first reads the sandbox's egress policy from network.rules. Each rule contains a match section and an action section. The request's SNI/host, method, path, and scheme are compared against the rule's Match fields using case-insensitive comparison.
If a rule matches and action.allow is true, the proxy checks for credential injection requirements. When the matched rule's action.inject array is non-empty, the proxy proceeds to resolve and inject the specified credentials.
Secret Resolution and Format Rendering
For each Inject entry in the rule, the proxy performs secret resolution through the sandbox-local secret API. The process involves:
-
Secret Lookup: The
secretfield references a secret stored in the CubeMaster secret store. The proxy fetches the secret value via the sandbox-local secret API managed by CubeMaster. -
Format Processing: The
formatstring (defaulting to"${SECRET}") is processed by theInject.Render()method insdk/go/policy.go. This method substitutes the${SECRET}placeholder with the actual secret value, yielding the final header value.
The EgressRuleInject struct in network-agent/internal/service/types.go mirrors the Inject definition for the gRPC service layer, ensuring consistent data models across components.
Header Insertion and Request Forwarding
The actual header assembly occurs in network-agent/internal/cubeegress/wire.go. The renderInject function orchestrates the final injection:
// Inside network-agent/internal/cubeegress/wire.go (simplified)
for _, inj := range a.Inject {
secretValue, err := secretStore.Get(inj.Secret) // fetch from sandbox secret store
if err != nil { /* handle error */ }
value := strings.ReplaceAll(inj.FormatOrDefault(), "${SECRET}", secretValue)
outgoingReq.Header.Set(inj.Header, value) // header insertion
}
The proxy adds a new HTTP header named by inject.header (e.g., Authorization) with the rendered value to the outbound request. The modified request then proceeds to the external endpoint with the injected credentials, satisfying downstream authentication requirements without exposing secrets to the sandbox workload.
Key Source Files and Implementation Details
The credential injection system spans multiple components within the TencentCloud/CubeSandbox repository:
-
sdk/go/policy.go: Defines the credential injection data model and rendering logic through the
Injectstruct andRendermethod. -
network-agent/internal/service/types.go: Mirrors the
Injectdefinition for the gRPC service layer via theEgressRuleInjectstruct. -
network-agent/internal/cubeegress/wire.go: Implements the actual injection logic through the
renderInjectfunction and request assembly. -
CubeMaster/pkg/service/sandbox/: Manages the secret retrieval APIs that provide the secret values referenced by injection rules.
The Inject struct in sdk/go/policy.go defines the core data structure: Header specifies the target header name, Secret references the secret store key, and Format provides the template string for value rendering.
Configuring Credential Injection in Practice
To enable credential injection, define an egress policy with the inject array populated. The following Go example demonstrates how to structure a policy using the CubeSandbox SDK:
// SDK side – policy definition
policy := []cubesandbox.Rule{
{
Name: "Access private API",
Match: cubesandbox.Match{
Host: "api.private.example.com",
Scheme: "https",
},
Action: cubesandbox.Action{
Allow: true,
Inject: []cubesandbox.Inject{
{
Header: "Authorization",
Secret: "my-api-token", // secret name in the sandbox store
Format: "Bearer ${SECRET}", // optional, defaults to "${SECRET}"
},
},
},
},
}
When the sandbox issues an HTTPS request to https://api.private.example.com/..., CubeProxy automatically intercepts the traffic, retrieves the my-api-token secret from the CubeMaster store, renders the format string Bearer ${SECRET} with the actual token value, and injects the resulting Authorization: Bearer <token> header into the outbound request.
Summary
- CubeProxy acts as the CubeSandbox security proxy, enforcing Layer 7 egress policies for all sandbox-initiated HTTP traffic.
- Credential injection occurs through a three-phase process: policy matching, secret resolution, and header insertion.
- The
Injectstruct insdk/go/policy.godefines the injection schema, whileInject.Render()handles format string substitution. - Secret resolution relies on the CubeMaster secret store, accessed via the sandbox-local secret API.
- The
renderInjectfunction innetwork-agent/internal/cubeegress/wire.goperforms the actual header assembly and attachment.
Frequently Asked Questions
How does CubeSandbox keep credentials secure during injection?
CubeSandbox stores all secrets in the CubeMaster secret store, which is inaccessible to sandbox workloads directly. The CubeProxy fetches secrets at runtime through the sandbox-local secret API, renders them into headers using the Inject.Render() method, and injects them into outbound requests. This ensures credentials never appear in sandbox code, environment variables, or process listings.
What happens if the secret referenced in an inject rule does not exist?
If the secretStore.Get(inj.Secret) call in network-agent/internal/cubeegress/wire.go fails to retrieve the specified secret, the proxy handles the error according to the configured error policy. Typically, the request is blocked or rejected to prevent unauthorized access attempts, ensuring that unauthenticated requests cannot reach external services.
Can I inject multiple headers using a single egress rule?
Yes. The action.inject field accepts an array of Inject objects, allowing you to specify multiple secrets and headers within a single rule. Each entry in the array is processed independently, fetching its respective secret and injecting it into the specified header before the request is forwarded.
What is the default format string if I do not specify a format?
If the format field is omitted, the system defaults to "${SECRET}". This means the secret value is injected directly into the header without additional prefixes or formatting. The Inject.Render() method in sdk/go/policy.go substitutes the ${SECRET} placeholder with the actual secret value to produce the final header content.
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 →