# How the CubeSandbox Credential Vault Prevents API Keys from Entering the Sandbox Environment

> Discover how the CubeSandbox credential vault protects API keys by keeping them on the host and injecting them via the CubeEgress proxy, preventing sandbox exposure.

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

---

**The CubeSandbox credential vault stores API keys exclusively on the host side and injects them via the CubeEgress proxy, ensuring secrets never appear in the sandbox's memory, filesystem, or environment.**

TencentCloud/CubeSandbox isolates untrusted code inside micro-VMs while maintaining secure access to external APIs. The credential vault prevents API keys from entering the sandbox environment by intercepting outbound traffic at the network boundary and injecting authentication headers after the request leaves the sandbox boundary, keeping secrets inaccessible even if the sandbox is compromised.

## Proxy-Level Injection Architecture

The security model relies on the **CubeEgress** proxy running outside the sandbox trust boundary. When sandboxed code initiates an outbound HTTP request, the proxy evaluates Layer 7 egress policies and injects credentials from the host-side vault before forwarding the request to external services.

### Host-Side Secret Storage

Secrets are stored only in the CubeMaster configuration or protected host vaults, referenced by name in policies. They are never written to the sandbox image, filesystem, or environment variables, eliminating persistence risks.

### The Injection Process

According to [`docs/guide/pi-agent-integration.md`](https://github.com/TencentCloud/CubeSandbox/blob/main/docs/guide/pi-agent-integration.md), the injection happens in three stages: policy matching, credential retrieval, and header injection. The `EgressRuleInject` struct defined in [`sdk/go/policy.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/sdk/go/policy.go) maps HTTP headers to vault-stored credentials without exposing the actual values to the sandbox runtime.

When the sandbox issues a request matching an egress rule, the proxy in [`network-agent/internal/cubeegress/client.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/network-agent/internal/cubeegress/client.go) intercepts the traffic, adds the required header (e.g., `Authorization: Bearer <token>`), and forwards the request. The sandbox process never sees the header value.

## Implementing Credential Injection

Developers declare injection policies using the Go SDK, JSON configuration, or Python SDK. These policies reside in the network configuration sent to the control plane, not the sandbox itself.

### Go SDK Policy Definition

The `EgressRuleInject` struct in [`sdk/go/policy.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/sdk/go/policy.go) defines the injection parameters:

```go
// 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"`
}

// Example usage: inject a Bearer token for calls to api.example.com
policy := []policy.EgressRule{
    {
        Match: policy.Match{
            Host: "api.example.com",
        },
        Action: policy.Action{
            Allow: true,
            Inject: &policy.EgressRuleInject{
                Header:     "Authorization",
                Credential: "my-api-key",
            },
        },
    },
}

```

### JSON Network Configuration

The same policy expressed as JSON in the network configuration file:

```json
{
  "match": { "host": "api.example.com" },
  "action": {
    "allow": true,
    "inject": {
      "header": "Authorization",
      "credential": "my-api-key"
    }
  }
}

```

When the sandbox requests `https://api.example.com/`, CubeEgress automatically adds `Authorization: Bearer <value-from-vault>`.

### Python SDK Usage

The Python SDK provides equivalent helpers for policy construction:

```python
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="my-api-key")}
    )
)

```

## Security Guarantees and Log Redaction

Even if an attacker escapes the sandbox runtime, they cannot extract API keys because the secrets exist only in the CubeEgress proxy memory on the host. As implemented in [`docs/guide/introduction.md`](https://github.com/TencentCloud/CubeSandbox/blob/main/docs/guide/introduction.md), all audit logs redact credential values as `***REDACTED***`, preventing accidental leakage through log streams.

If injection fails due to a missing policy or mismatched domain, the request proceeds **without** the credential rather than exposing it to the sandbox, returning an HTTP 403 as specified in [`sdk/go/policy.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/sdk/go/policy.go).

## Summary

- **Host-only storage**: API keys reside exclusively in the host-side credential vault, never in the sandbox image or filesystem.
- **Proxy injection**: CubeEgress injects headers after the request leaves the sandbox boundary, as implemented in [`network-agent/internal/cubeegress/client.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/network-agent/internal/cubeegress/client.go).
- **Policy-driven**: Developers define injection rules using `EgressRuleInject` in [`sdk/go/policy.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/sdk/go/policy.go) and [`sdk/go/models.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/sdk/go/models.go).
- **Safe failure mode**: Misconfigured policies result in denied requests rather than credential exposure.
- **Log redaction**: Secrets are automatically redacted in all logs per [`docs/guide/introduction.md`](https://github.com/TencentCloud/CubeSandbox/blob/main/docs/guide/introduction.md).

## Frequently Asked Questions

### How does CubeSandbox prevent sandboxed code from reading injected credentials?

The injection occurs at the **CubeEgress** proxy layer outside the micro-VM boundary. The sandbox sends the HTTP request without the secret header; the proxy intercepts the outbound traffic, adds the credential from the host vault, and forwards it to the destination. Since the sandbox process never receives the injected header in its response path, the secret remains outside the sandbox memory.

### What happens if the injection policy is missing or the credential is not found?

According to the policy implementation in [`sdk/go/policy.go`](https://github.com/TencentCloud/CubeSandbox/blob/main/sdk/go/policy.go), the proxy treats a missing injection target as a policy violation. The request proceeds without the credential and is rejected with an HTTP 403 Forbidden status, rather than exposing the credential name or value to the sandbox. This fail-closed behavior prevents accidental leakage through misconfiguration.

### Can I rotate API keys without restarting the sandbox?

Yes. Because credentials are stored in the host-side vault and referenced by name in the egress policy, updating the secret value in the CubeMaster configuration immediately affects new requests without requiring sandbox redeployment. The policy references the credential name, not the value, enabling zero-downtime rotation.

### Where are the credentials actually stored?

Credentials are stored in the **CubeMaster** configuration or a protected host vault accessed by the CubeEgress proxy, as described in [`docs/guide/pi-agent-integration.md`](https://github.com/TencentCloud/CubeSandbox/blob/main/docs/guide/pi-agent-integration.md). They are never written to the sandbox filesystem, environment variables, or command-line arguments, ensuring that even a full filesystem dump of the micro-VM contains no API keys.