npm package: @oshu/vault-sdk
Description: TypeScript SDK for the Secrets Proxy API
Author: Oshu
Latest version: 0.2.0

# @oshu/vault-sdk

TypeScript SDK for the [Oshu Vault](https://oshu.dev) secrets proxy — inject secrets into sandboxed environments without exposing plaintext values.

## Install

```bash
npm install @oshu/vault-sdk
```

## How it works

1. Your server creates a **session** with plaintext secrets
2. The SDK returns **sealed tokens** (`SEALED_xxx`) and proxy credentials
3. You pass the sealed tokens as env vars into a sandbox
4. The proxy intercepts outbound requests and replaces sealed tokens with real values on-the-fly

The sandbox never sees plaintext secrets.

## Quickstart: E2B

```typescript
import { Sandbox } from "@e2b/code-interpreter";
import { SecretsProxyClient } from "@oshu/vault-sdk";

const client = new SecretsProxyClient({
  baseUrl: "https://your-proxy.example.com",
  apiKey: process.env.SECRETS_PROXY_API_KEY!,
});

// 1. Create a session with your secrets
const session = await client.createSession({
  secrets: {
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
    MY_API_KEY: process.env.MY_API_KEY!,
  },
});

const proxyUrl = `https://${session.session_id}:${session.token}@your-proxy.example.com`;

// 2. Create an E2B sandbox from template (CA cert + tools pre-installed)
// Build the template first: e2b template build -n oshu-vault-claude
const sandbox = await Sandbox.create("oshu-vault-claude", {
  envs: {
    ANTHROPIC_API_KEY: session.sealed_secrets["ANTHROPIC_API_KEY"],
    MY_API_KEY: session.sealed_secrets["MY_API_KEY"],
    HTTP_PROXY: proxyUrl,
    HTTPS_PROXY: proxyUrl,
  },
});

try {
  // 3. Run commands — sealed tokens are replaced transparently
  const result = await sandbox.commands.run(
    `curl -s https://httpbin.org/headers -H "X-Api-Key: ${session.sealed_secrets["MY_API_KEY"]}"`,
    { timeoutMs: 30_000 },
  );
  console.log(result.stdout); // X-Api-Key will contain the real value
} finally {
  await client.deleteSession(session.session_id);
  await sandbox.kill();
}
```

## Quickstart: Daytona

```typescript
import { Daytona, Image } from "@daytonaio/sdk";
import { SecretsProxyClient } from "@oshu/vault-sdk";

const client = new SecretsProxyClient({
  baseUrl: "https://your-proxy.example.com",
  apiKey: process.env.SECRETS_PROXY_API_KEY!,
});

// 1. Create a session with your secrets
const session = await client.createSession({
  secrets: {
    ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
  },
});

const proxyUrl = `https://${session.session_id}:${session.token}@your-proxy.example.com`;

// 2. Build a sandbox image with trusted CA cert baked in
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 https://your-proxy.example.com/v1/ca.pem -o /usr/local/share/ca-certificates/proxy-ca.crt && update-ca-certificates",
);

// 3. Create the Daytona sandbox with proxy env vars
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",
  },
});

try {
  // 4. Run commands — sealed tokens are replaced transparently
  const result = await sandbox.process.executeCommand(
    `curl -s https://api.anthropic.com/v1/messages -H "x-api-key: ${session.sealed_secrets["ANTHROPIC_API_KEY"]}" -H "anthropic-version: 2023-06-01" -H "content-type: application/json" -d '{"model":"claude-haiku-4-5-20251001","max_tokens":50,"messages":[{"role":"user","content":"Say hello."}]}'`,
  );
  console.log(result.result);
} finally {
  await client.deleteSession(session.session_id);
  await daytona.delete(sandbox);
}
```

## API Reference

### `new SecretsProxyClient(options)`

| Option    | Type     | Description                          |
| --------- | -------- | ------------------------------------ |
| `baseUrl` | `string` | Base URL of the secrets proxy API    |
| `apiKey`  | `string` | Bearer token for API authentication  |
| `fetch`   | `fetch`  | Optional custom fetch implementation |

### `client.createSession(request)`

Creates a session and returns sealed tokens.

**Request:**

| Field           | Type                    | Description                              |
| --------------- | ----------------------- | ---------------------------------------- |
| `secrets`       | `Record<string,string>` | Map of secret name to plaintext value    |
| `allowed_hosts` | `string[]`              | Optional host allowlist for replacement  |
| `sliding_ttl`   | `number`                | Session TTL in seconds (default: `3600`) |

**Response:**

| Field            | Type                    | Description                              |
| ---------------- | ----------------------- | ---------------------------------------- |
| `session_id`     | `string`                | Session identifier                       |
| `token`          | `string`                | Proxy auth token                         |
| `sealed_secrets` | `Record<string,string>` | Map of secret name to `SEALED_xxx` token |
| `env_vars`       | `Record<string,string>` | Pre-built `HTTP_PROXY`/`HTTPS_PROXY`     |
| `ca_cert`        | `string \| undefined`   | MITM CA certificate PEM                  |
| `expires_in`     | `number`                | TTL in seconds                           |

### `client.getSession(sessionId)`

Returns session metadata (secrets are redacted).

### `client.deleteSession(sessionId)`

Deletes a session.

### `client.getCACert()`

Fetches the proxy's MITM CA certificate PEM, or `null` if not configured.

### `createProxiedFetch(options)`

Returns a `fetch` function that routes requests through the proxy (uses `undici` ProxyAgent).

```typescript
import { createProxiedFetch } from "@oshu/vault-sdk";

const proxiedFetch = createProxiedFetch({
  proxyUrl: `https://${session.session_id}:${session.token}@proxy:80`,
  caCert: session.ca_cert,
});

const res = await proxiedFetch("https://api.example.com/data", {
  headers: { Authorization: `Bearer ${session.sealed_secrets["API_KEY"]}` },
});
```

### `getProxyEnvVars(options)`

Returns environment variables for spawning child processes through the proxy. Writes the CA cert to a temp file if provided.

```typescript
import { getProxyEnvVars } from "@oshu/vault-sdk";

const env = getProxyEnvVars({
  proxyUrl: `https://${session.session_id}:${session.token}@proxy:80`,
  caCert: session.ca_cert,
});
// env = { HTTP_PROXY, HTTPS_PROXY, NODE_EXTRA_CA_CERTS }
```