> ## Documentation Index
> Fetch the complete documentation index at: https://opensandbox-oc-s-762ac928075c46d2828bcb22.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Secret Stores

> Manage secrets and egress control

## `SecretStore.create(opts)`

Create a new secret store.

```typescript theme={null}
import { SecretStore } from '@opencomputer/sdk';

const store = await SecretStore.create({
  name: 'my-agent-secrets',
  egressAllowlist: ['api.anthropic.com'],
});
```

<ParamField body="name" type="string" required>
  Store name (unique per organization)
</ParamField>

<ParamField body="egressAllowlist" type="string[]">
  Allowed egress hosts (e.g. `["api.anthropic.com"]`)
</ParamField>

**Returns:** `Promise<SecretStoreInfo>`

***

## `SecretStore.list(opts?)`

List all secret stores.

**Returns:** `Promise<SecretStoreInfo[]>`

***

## `SecretStore.get(storeId, opts?)`

Get a secret store by ID.

<ParamField body="storeId" type="string" required>
  UUID of the secret store
</ParamField>

**Returns:** `Promise<SecretStoreInfo>`

***

## `SecretStore.update(storeId, opts)`

Partial updates — only the fields you pass are changed.

```typescript theme={null}
const updated = await SecretStore.update('store-uuid', {
  name: 'new-name',
  egressAllowlist: ['api.anthropic.com', '*.openai.com'],
});
```

<ParamField body="storeId" type="string" required>
  UUID of the store to update
</ParamField>

<ParamField body="name" type="string">
  New store name
</ParamField>

<ParamField body="egressAllowlist" type="string[]">
  New allowed egress hosts
</ParamField>

**Returns:** `Promise<SecretStoreInfo>`

***

## `SecretStore.delete(storeId, opts?)`

Deletes the store and all its secrets. Running sandboxes are not affected.

**Returns:** `Promise<void>`

***

## `SecretStore.setSecret(storeId, name, value, opts?)`

Set a secret in a store. Secrets are encrypted at rest. The value is never returned by the API.

```typescript theme={null}
await SecretStore.setSecret('store-uuid', 'ANTHROPIC_API_KEY', 'sk-ant-...');
```

Optionally restrict which hosts can receive this secret:

```typescript theme={null}
await SecretStore.setSecret('store-uuid', 'ANTHROPIC_API_KEY', 'sk-ant-...', {
  allowedHosts: ['api.anthropic.com'],
});
```

<ParamField body="storeId" type="string" required>
  UUID of the secret store
</ParamField>

<ParamField body="name" type="string" required>
  Secret name (used as the env var name in sandboxes)
</ParamField>

<ParamField body="value" type="string" required>
  Secret value (encrypted at rest, never returned by API)
</ParamField>

<ParamField body="allowedHosts" type="string[]">
  Restrict this secret to specific hosts only
</ParamField>

**Returns:** `Promise<void>`

***

## `SecretStore.listSecrets(storeId, opts?)`

Returns secret metadata only. Values are never exposed.

**Returns:** `Promise<SecretEntryInfo[]>`

***

## `SecretStore.deleteSecret(storeId, name, opts?)`

**Returns:** `Promise<void>`

***

## Using Secrets with Sandboxes

Pass the `secretStore` option to `Sandbox.create()` to inject the store's secrets:

```typescript theme={null}
const sandbox = await Sandbox.create({
  secretStore: 'my-agent-secrets',
  timeout: 600,
});

// Secrets are available as sealed env vars
const result = await sandbox.commands.run('echo $ANTHROPIC_API_KEY');
// stdout: "osb_sealed_abc123..." (sealed, not the real key)

// But outbound HTTPS requests get the real value substituted by the proxy
const apiResult = await sandbox.commands.run(
  'curl -s https://api.anthropic.com/v1/messages -H "x-api-key: $ANTHROPIC_API_KEY" ...'
);
```

## Using Secrets with Snapshots and Checkpoints

### Snapshot template with secrets

Attach a secret store when creating a sandbox from a pre-built snapshot — even if the snapshot was built without one:

```typescript theme={null}
import { Sandbox, Snapshots, Image } from '@opencomputer/sdk/node';

// Pre-build a snapshot with dependencies
const snapshots = new Snapshots();
await snapshots.create({
  name: 'data-pipeline',
  image: Image.base().aptInstall(['python3-pip']).pipInstall(['pandas']),
});

// Create sandboxes from the snapshot, each with their own credentials
const worker1 = await Sandbox.create({
  snapshot: 'data-pipeline',
  secretStore: 'worker-1-keys',
});
const worker2 = await Sandbox.create({
  snapshot: 'data-pipeline',
  secretStore: 'worker-2-keys',
});
```

### Checkpoint fork with secrets

Attach or layer a secret store when forking from a checkpoint:

```typescript theme={null}
// Bake a base environment with git credentials
const base = await Sandbox.create({ secretStore: 'git-creds' });
await base.exec.run('git clone https://github.com/org/repo /app', { cwd: '/' });
const cp = await base.createCheckpoint('repo-cloned');

// Fork with different credentials per sandbox (layered on top of git-creds)
const worker = await Sandbox.createFromCheckpoint(cp.id, {
  secretStore: 'worker-keys',  // layered on top of git-creds
});
```

When layered, secrets merge (fork's store wins on collision) and egress allowlists aggregate.

***

## Types

<Accordion title="SecretStoreInfo">
  | Property          | Type       | Description          |
  | ----------------- | ---------- | -------------------- |
  | `id`              | `string`   | Store UUID           |
  | `orgId`           | `string`   | Organization UUID    |
  | `name`            | `string`   | Store name           |
  | `egressAllowlist` | `string[]` | Allowed egress hosts |
  | `createdAt`       | `string`   | ISO 8601 timestamp   |
  | `updatedAt`       | `string`   | ISO 8601 timestamp   |
</Accordion>

<Accordion title="SecretEntryInfo">
  | Property       | Type       | Description                |
  | -------------- | ---------- | -------------------------- |
  | `id`           | `string`   | Entry UUID                 |
  | `storeId`      | `string`   | Parent store UUID          |
  | `name`         | `string`   | Secret name (env var name) |
  | `allowedHosts` | `string[]` | Host restrictions          |
  | `createdAt`    | `string`   | ISO 8601 timestamp         |
  | `updatedAt`    | `string`   | ISO 8601 timestamp         |
</Accordion>
