> ## Documentation Index
> Fetch the complete documentation index at: https://docs.steward.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Secret Vault

> Encrypted credential storage with automatic injection — agents never see API keys.

# Secret Vault

The Secret Vault stores encrypted API credentials and injects them into outbound requests through the [Proxy Gateway](/concepts/proxy-gateway). Agents never see real API keys.

## How It Works

Instead of giving agents plaintext API keys:

```bash theme={null}
# ❌ Old way — dangerous
OPENAI_API_KEY=sk-proj-abc123...
ANTHROPIC_API_KEY=sk-ant-def456...
```

You store credentials in Steward's Secret Vault and configure **routes** that map request patterns to credentials:

```typescript theme={null}
// 1. Store an encrypted credential
await fetch("https://api.steward.fi/secrets", {
  method: "POST",
  headers: {
    "X-Steward-Key": "your-tenant-key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    name: "openai-prod",
    value: "sk-proj-abc123...",
    description: "Production OpenAI API key",
  }),
});

// 2. Create a route: when an agent calls api.openai.com, inject this key
await fetch("https://api.steward.fi/secrets/routes", {
  method: "POST",
  headers: {
    "X-Steward-Key": "your-tenant-key",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    secretId: "secret-uuid",
    hostPattern: "api.openai.com",
    pathPattern: "/*",
    injectAs: "header",
    injectKey: "Authorization",
    injectFormat: "Bearer {value}",
  }),
});
```

Now when an agent calls OpenAI through the proxy, Steward decrypts the key and injects it automatically.

## Encryption

Secrets use the same AES-256-GCM encryption as the Wallet Vault, with a key hierarchy that supports per-tenant isolation:

```
Master Key (Argon2id from STEWARD_MASTER_PASSWORD)
    │
    ├── Tenant Key A (wrapped by master key)
    │       ├── encrypts "openai-prod"
    │       ├── encrypts "anthropic-main"
    │       └── encrypts "birdeye-key"
    │
    └── Tenant Key B (wrapped by master key)
            └── encrypts "custom-api"
```

**Key benefits:**

* Rotating a tenant key re-wraps it — no re-encryption of all secrets needed
* Master key rotation is O(tenants), not O(secrets)
* Future: BYOK (Bring Your Own Key) for enterprise customers

## Secret Lifecycle

<Tabs>
  <Tab title="Create">
    ```bash theme={null}
    curl -X POST https://api.steward.fi/secrets \
      -H "X-Steward-Key: your-key" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "anthropic-prod",
        "value": "sk-ant-def456...",
        "description": "Anthropic production key",
        "expiresAt": "2027-01-01T00:00:00Z"
      }'
    ```

    Response (value is **never** returned):

    ```json theme={null}
    {
      "ok": true,
      "data": {
        "id": "550e8400-e29b-41d4-a716-446655440000",
        "name": "anthropic-prod",
        "description": "Anthropic production key",
        "version": 1,
        "expiresAt": "2027-01-01T00:00:00Z",
        "createdAt": "2026-03-26T12:00:00Z"
      }
    }
    ```
  </Tab>

  <Tab title="Rotate">
    ```bash theme={null}
    curl -X POST https://api.steward.fi/secrets/{id}/rotate \
      -H "X-Steward-Key: your-key" \
      -H "Content-Type: application/json" \
      -d '{ "value": "sk-ant-new-key..." }'
    ```

    Rotation creates a new version. Routes automatically use the latest version. **No container redeployment needed.**
  </Tab>

  <Tab title="Delete">
    ```bash theme={null}
    curl -X DELETE https://api.steward.fi/secrets/{id} \
      -H "X-Steward-Key: your-key"
    ```

    Soft delete — the secret is marked as deleted but retained for audit purposes.
  </Tab>
</Tabs>

## Credential Injection

When the proxy forwards a request, it:

1. **Decrypts** the credential (held in memory for microseconds)
2. **Injects** it according to the route config (header, query param, or body)
3. **Forwards** the request to the real API
4. **Zeroes** the credential from memory

Injection methods:

| Method   | Use Case                                          | Example                             |
| -------- | ------------------------------------------------- | ----------------------------------- |
| `header` | Most APIs (Bearer token, API key header)          | `Authorization: Bearer sk-proj-...` |
| `query`  | APIs that use query param auth                    | `?apiKey=sk-proj-...`               |
| `body`   | APIs that require credentials in the request body | `{ "api_key": "sk-proj-..." }`      |

## Security Properties

* **Secrets never leave the vault in API responses** — list/get endpoints return metadata only
* **Decrypted credentials exist in memory for microseconds** — zeroed immediately after injection
* **All access is logged** — every decryption event creates an audit trail entry
* **Tenant isolation** — secrets are scoped to tenants; agents can only trigger decryption of their tenant's secrets

## Related

* [Proxy Gateway](/concepts/proxy-gateway) — How the proxy routes and injects credentials
* [Secrets API Reference](/api-reference/secrets) — Full CRUD API
* [Routes API Reference](/api-reference/routes) — Route configuration API
* [Managing Secrets Guide](/guides/secrets) — Step-by-step guide
