---
title: "LLM Credentials"
description: "Pass LLM API keys to agent sessions securely."
skill: true
---

- **Keys stay on the server** and are injected at session creation
- **Per-tenant isolation** for multi-tenant deployments

## Passing API keys

Pass LLM provider keys via the `env` option on `createSession`. The VM does not inherit from the host `process.env`, so keys must be passed explicitly.

```ts @nocheck
const session = await agent.createSession("pi", {
  env: { ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY! },
});
```

## Per-tenant credentials

Look up each tenant's API key from your database and pass it at session creation.

```ts @nocheck
import { agentOs } from "rivetkit/agent-os";
import { setup, UserError } from "rivetkit";
import common from "@rivet-dev/agent-os-common";
import pi from "@rivet-dev/agent-os-pi";

interface ConnState {
  userId: string;
  anthropicApiKey: string;
}

const vm = agentOs({
  createConnState: async (c, params: { authToken: string }): Promise<ConnState> => {
    const user = await validateAndLookupUser(params.authToken);
    if (!user) {
      throw new UserError("Forbidden", { code: "forbidden" });
    }
    return { userId: user.id, anthropicApiKey: user.anthropicApiKey };
  },
  options: { software: [common, pi] },
});

export const registry = setup({ use: { vm } });
registry.start();
```

Then use the connection state when creating sessions:

```ts @nocheck
const session = await agent.createSession("pi", {
  env: { ANTHROPIC_API_KEY: c.conn.state.anthropicApiKey },
});
```

See [Sandbox Agent's LLM credentials documentation](https://sandboxagent.dev/docs/llm-credentials) for more details on per-tenant token patterns.

## Embedded LLM Gateway

The [Embedded LLM Gateway](/docs/agent-os/llm-gateway) (coming soon) will remove the need to manage API keys manually. It routes all agent LLM requests through a managed proxy built into agentOS, providing per-tenant usage metering, rate limiting, and cost controls without deploying a separate gateway service.
