How the Credential Vault Prevents API Keys from Entering the Sandbox
The CubeSandbox credential vault stores secrets exclusively on the host and injects them at the CubeEgress proxy layer, ensuring API keys never enter the sandbox's memory, filesystem, or environment.
TencentCloud/CubeSandbox isolates untrusted code inside a micro-VM (the sandbox) while allowing controlled external network access. Central to this security model is the Credential Vault, which guarantees that sensitive tokens remain entirely outside the sandbox perimeter. This article examines the architectural mechanisms and source code implementation that enforce this isolation, referencing the actual implementation in the CubeSandbox repository.
Host-Side Secret Storage and Policy Definition
Secrets never enter the sandbox image or its running environment. Instead, API keys reside only in the host-side CubeMaster configuration or a protected vault, referenced within the sandbox policy by symbolic names alone. This pattern is documented in docs/guide/pi-agent-integration.md, which establishes that the credential vault remains inaccessible to code executing inside the micro-VM.
Declaring Injection Rules in sdk/go/policy.go
Developers define egress policies using the EgressRuleInject struct in sdk/go/policy.go. This struct maps external destinations to credential identifiers without embedding the actual secret values in the policy payload.
// sdk/go/policy.go
type EgressRuleInject struct {
// Header name to inject, e.g. "Authorization"
Header string `json:"header"`
// Name of the stored credential (from the vault)
Credential string `json:"credential"`
}
When you attach a rule to a sandbox, you declare that traffic matching a specific host (for example, api.example.com) should receive the credential named production-api-key in the Authorization header. The policy configuration travels to the CubeEgress proxy, not into the sandbox itself.
Proxy-Level Injection by CubeEgress
The actual interception and header injection occur outside the sandbox boundary. When sandboxed code initiates an outbound HTTP request, the CubeEgress proxy evaluates the traffic against the active L7 policy. Upon a match, the proxy retrieves the secret from the host-side vault and appends the header before forwarding the request to the external service.
Implementation in client.go
According to network-agent/internal/cubeegress/client.go, the proxy maintains a secure connection to the credential vault and performs header injection after the request leaves the micro-VM but before it transits to the external API. The sandboxed process transmits a request without authentication headers; the proxy adds Authorization: Bearer <secret-value> transparently. Because the injection happens in the host network namespace, the secret exists only in the proxy's memory during transit.
Fail-Safe Behavior and Audit Security
The system implements defense-in-depth measures to prevent accidental exposure when injection fails or policies are misconfigured.
Secure Fallback Mechanics
As implemented in sdk/go/policy.go, the proxy enforces a strict fail-safe: if injection fails because a credential is missing or the domain mismatches, the request either proceeds without authentication or is rejected with HTTP 403, depending on the Allow flag. Critically, the secret is never transmitted into the sandbox for client-side handling or debugging.
Log Redaction
All audit logs that flow back to CubeMaster automatically redact credential values, displaying ***REDACTED*** in place of actual tokens. This prevents secret leakage through log aggregation systems or debugging outputs that originate from the sandbox environment, as documented in docs/guide/introduction.md.
Configuring Credential Injection
The following examples demonstrate how to define injection policies using the CubeSandbox SDKs. In each case, the credential field refers to a vault key, not the literal secret.
Go SDK Configuration
import "github.com/TencentCloud/CubeSandbox/sdk/go/policy"
// Define injection for api.example.com
rule := policy.EgressRule{
Match: policy.Match{
Host: "api.example.com",
},
Action: policy.Action{
Allow: true,
Inject: &policy.EgressRuleInject{
Header: "Authorization",
Credential: "production-api-key",
},
},
}
JSON Network Configuration
{
"match": {
"host": "api.example.com"
},
"action": {
"allow": true,
"inject": {
"header": "Authorization",
"credential": "production-api-key"
}
}
}
Python SDK Usage
from cubesandbox import Sandbox, EgressRule, Inject
sandbox = Sandbox(...)
sandbox.add_egress_rule(
EgressRule(
match={"host": "api.example.com"},
action={"allow": True, "inject": Inject(
header="Authorization",
credential="production-api-key"
)}
)
)
Summary
- Host-side isolation: API keys reside exclusively in the CubeMaster configuration or protected vault, never entering the micro-VM filesystem or memory.
- Proxy injection:
network-agent/internal/cubeegress/client.goimplements the interception logic that adds credentials after traffic leaves the sandbox. - Policy-driven control: The
EgressRuleInjectstruct insdk/go/policy.goenables declarative credential mapping without embedding secrets in sandbox images. - Fail-safe defaults: Failed injection results in HTTP 403 rejection or transmission without credentials, never exposing the secret to sandboxed code.
- Comprehensive redaction: Audit logs automatically replace credential content with
***REDACTED***to prevent secondary leakage.
Frequently Asked Questions
Where are API keys physically stored in a CubeSandbox deployment?
API keys are stored exclusively in the CubeMaster host-side configuration or an integrated secure vault. They are referenced within sandbox policies by symbolic names only, keeping them outside the micro-VM entirely according to the architecture described in docs/guide/pi-agent-integration.md.
What happens if the CubeEgress proxy cannot locate a credential for injection?
If the injection fails due to a missing credential or policy mismatch, the proxy enforces a secure fallback defined in sdk/go/policy.go: the request is either rejected with HTTP 403 (if Allow is false) or forwarded without authentication headers (if Allow is true). In neither case is the secret value exposed to the sandbox.
Can sandboxed code ever read the credential vault directly?
No. The credential vault is accessible only to the CubeEgress proxy running in the host network namespace. The sandbox communicates through a restricted interface that lacks any API or filesystem path to the vault, ensuring complete isolation between untrusted code and sensitive credentials.
How does CubeSandbox prevent API keys from appearing in logs or debugging output?
All logs that capture request headers or proxy events automatically redact injected credentials, replacing the actual token with the string ***REDACTED***. This redaction occurs at the host level before logs reach aggregation systems or user-facing interfaces, as specified in docs/guide/introduction.md.
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 →