Oshu Vault

Network Egress Control

Control which hosts are reachable and which get secret injection

Two-Layer Security Model

Oshu Vault provides two independent controls on every session:

FieldWhen setWhen not set
allowed_egressOnly listed hosts can be reached — everything else gets 403 ForbiddenAll hosts are reachable
secret_hostsOnly listed hosts get sealed token replacement — others pass through unchangedAll hosts get token replacement

This separation lets you lock down network egress independently from secret injection scope.

Why two layers?

Consider a sandbox running an AI agent. You want to:

  1. Block all outbound traffic except the APIs the agent needs (egress control)
  2. Only inject your API key for the specific provider, not every request (secret scoping)
const session = await client.createSession({
  secrets: {
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
  },
  // Layer 1: Network firewall — only these hosts are reachable
  allowed_egress: [
    "api.anthropic.com",
    "*.github.com",      // wildcard for all GitHub subdomains
    "registry.npmjs.org",
  ],
  // Layer 2: Secret injection — only Anthropic gets the real key
  secret_hosts: ["api.anthropic.com"],
});

With this configuration:

  • api.anthropic.com — reachable, sealed tokens replaced with real secrets
  • api.github.com — reachable (wildcard match), but sealed tokens pass through unchanged
  • registry.npmjs.org — reachable, no token replacement
  • evil.comblocked with 403

Wildcard Matching

allowed_egress supports wildcard patterns with *.:

PatternMatchesDoes not match
api.openai.comapi.openai.combeta.openai.com
*.openai.comapi.openai.com, beta.openai.com, openai.comopenai.org
*.github.comapi.github.com, raw.githubusercontent.github.com, github.comgithub.io

secret_hosts uses exact matching only (case-insensitive, port stripped).

Combining with Sandbox Network Controls

Both E2B and Daytona have their own network restriction features. These work at the infrastructure level (IP/CIDR-based), while Oshu Vault's egress control works at the application level (domain-based). Using both together provides defense in depth.

E2B's network.allowOut restricts outbound connections by IP, CIDR, or domain. Combined with Oshu Vault, you get:

  1. E2B network layer — forces all traffic through the proxy (block everything except the proxy IP)
  2. Oshu Vault egress layer — the proxy blocks domains not in allowed_egress
  3. Oshu Vault secret layer — only secret_hosts get token replacement
import { Sandbox, ALL_TRAFFIC } from "@e2b/code-interpreter";
import { SecretsProxyClient } from "@oshu/vault-sdk";

const PROXY_HOST = "pv.oshu.dev";

const client = new SecretsProxyClient({
  baseUrl: `https://${PROXY_HOST}`,
  apiKey: process.env.SECRETS_PROXY_API_KEY!,
});

// Create session with egress + secret host controls
const session = await client.createSession({
  secrets: {
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
  },
  allowed_egress: ["api.anthropic.com", "*.github.com"],
  secret_hosts: ["api.anthropic.com"],
});

const proxyUrl = `https://${session.session_id}:${session.token}@${PROXY_HOST}`;

// E2B: only allow traffic to the proxy itself
const sandbox = await Sandbox.create("oshu-vault-claude", {
  envs: {
    ANTHROPIC_API_KEY: session.sealed_secrets["ANTHROPIC_API_KEY"],
    HTTP_PROXY: proxyUrl,
    HTTPS_PROXY: proxyUrl,
  },
  network: {
    denyOut: [ALL_TRAFFIC],
    allowOut: [PROXY_HOST],
  },
});

try {
  const result = await sandbox.commands.run(
    `claude -p "Write a hello world program"`,
    { timeoutMs: 120_000 },
  );
  console.log(result.stdout);
} finally {
  await client.deleteSession(session.session_id);
  await sandbox.kill();
}

E2B's domain filtering works via SNI inspection for HTTPS (port 443) and Host header for HTTP (port 80). Since all traffic goes through the proxy anyway, Oshu Vault's domain-based allowed_egress provides more granular control on top.

Daytona's networkAllowList restricts outbound connections by IP/CIDR. Combined with Oshu Vault, you get:

  1. Daytona network layer — forces all traffic through the proxy (only allow the proxy's IP range)
  2. Oshu Vault egress layer — the proxy blocks domains not in allowed_egress
  3. Oshu Vault secret layer — only secret_hosts get token replacement
import { Daytona, Image } from "@daytonaio/sdk";
import { SecretsProxyClient } from "@oshu/vault-sdk";
import dns from "node:dns/promises";

const PROXY_HOST = "pv.oshu.dev";
const PROXY_BASE_URL = `https://${PROXY_HOST}`;

const client = new SecretsProxyClient({
  baseUrl: PROXY_BASE_URL,
  apiKey: process.env.SECRETS_PROXY_API_KEY!,
});

// Create session with egress + secret host controls
const session = await client.createSession({
  secrets: {
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
  },
  allowed_egress: ["api.anthropic.com", "*.github.com"],
  secret_hosts: ["api.anthropic.com"],
});

const proxyUrl = `https://${session.session_id}:${session.token}@${PROXY_HOST}`;

// Resolve the proxy's IP for the Daytona allowlist
const proxyIps = await dns.resolve4(PROXY_HOST);
// Daytona also needs DNS — Cloudflare (1.1.1.0/31) + internal resolver
const networkAllowList = [
  ...proxyIps.map((ip) => `${ip}/32`),
  "1.1.1.0/31",
  "100.65.160.1/32",
].join(",");

const image = Image.base("node:22-slim").runCommands(
  "apt-get update && apt-get install -y curl ca-certificates && rm -rf /var/lib/apt/lists/*",
  `curl -fsSL ${PROXY_BASE_URL}/v1/ca.pem -o /usr/local/share/ca-certificates/proxy-ca.crt && update-ca-certificates`,
  "npm install -g @anthropic-ai/claude-code",
);

const daytona = new Daytona({ apiKey: process.env.DAYTONA_KEY });

const sandbox = await daytona.create(
  {
    image,
    envVars: {
      ANTHROPIC_API_KEY: session.sealed_secrets["ANTHROPIC_API_KEY"],
      HTTP_PROXY: proxyUrl,
      HTTPS_PROXY: proxyUrl,
      NODE_EXTRA_CA_CERTS: "/etc/ssl/certs/ca-certificates.crt",
    },
    // Daytona: only allow traffic to the proxy + DNS
    networkAllowList,
  },
  { timeout: 0, onSnapshotCreateLogs: console.log },
);

try {
  const result = await sandbox.process.executeCommand(
    `claude -p "Write a hello world program"`,
  );
  console.log(result.result);
} finally {
  await client.deleteSession(session.session_id);
  await daytona.delete(sandbox);
}

Daytona's networkAllowList is IP-based (CIDR ranges), so you need to resolve the proxy's hostname to IPs. The sandbox also needs DNS access to resolve hostnames — include your DNS server IPs in the allowlist (Cloudflare 1.1.1.0/31 and Daytona's internal resolver 100.65.160.1/32).

Defense in Depth

The diagram below shows how the layers interact:

Sandbox                    Infrastructure              Oshu Vault              Upstream
  |                         (E2B/Daytona)                  |                      |
  |-- curl evil.com ------->|                              |                      |
  |   BLOCKED (IP)     <----|  (not in allowlist)          |                      |
  |                         |                              |                      |
  |-- curl api.anthropic -->|-- forward to proxy --------->|                      |
  |                         |  (proxy IP allowed)          |                      |
  |                         |                              |-- api.anthropic.com->|
  |                         |                              |   SEALED_x -> sk-... |
  |                         |                              |   (in secret_hosts)  |
  |                         |                              |                      |
  |-- curl api.github.com->|-- forward to proxy --------->|                      |
  |                         |                              |-- api.github.com --->|
  |                         |                              |   SEALED_x intact    |
  |                         |                              |   (not in            |
  |                         |                              |    secret_hosts)     |
  |                         |                              |                      |
  |-- curl example.com ---->|-- forward to proxy --------->|                      |
  |   403 Forbidden    <----|<--- 403 ---------------<-----|                      |
  |                         |                              |   (not in            |
  |                         |                              |    allowed_egress)   |

Layer 1 (Infrastructure): The sandbox provider blocks all direct outbound traffic except to the proxy. This is enforced at the network level — even root inside the sandbox cannot bypass it.

Layer 2 (Proxy Egress): The proxy checks allowed_egress and returns 403 for hosts not on the list. This provides domain-based control (vs. IP-based at the infrastructure level).

Layer 3 (Secret Scoping): For allowed hosts, secret_hosts controls whether sealed tokens get replaced. Non-matching hosts get the request forwarded with sealed tokens intact.

API Reference

Create Session

curl -X POST https://pv.oshu.dev/v1/sessions \
  -H "Authorization: Bearer $SECRETS_PROXY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "secrets": {
      "ANTHROPIC_API_KEY": "sk-ant-..."
    },
    "secret_hosts": ["api.anthropic.com"],
    "allowed_egress": ["api.anthropic.com", "*.github.com"],
    "sliding_ttl": 3600
  }'

Get Session

The response includes both fields:

{
  "session_id": "sess_abc123...",
  "secret_hosts": ["api.anthropic.com"],
  "allowed_egress": ["api.anthropic.com", "*.github.com"],
  "secrets": {
    "SEALED_aaa111...": "[REDACTED]"
  },
  "expires_in": 3600,
  "created_at": "2025-01-15T10:00:00Z"
}