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

# Tool Credentials

> Give the agent's tools per-user credentials, bound server-side to the session.

Some tools act on a user's behalf — reading their GitHub, posting to their Slack, querying their database. Those credentials are bound to the session **when your backend mints it**, never in the browser.

<Note>
  This is unrelated to the [session token](/sdk/authentication). That authenticates the user *to SideNet*; these authenticate the *tools* to other services.
</Note>

## How it works

Pass `tools_auth` to `POST /v1/token`, keyed by tool provider id:

```javascript theme={null}
// Your backend. Uses the organization API key.
const tokens = await api('/v1/token', {
  user: { id: 'user-789' },
  billing_group: { id: 'acme-corp' },
  tools_auth: {
    'f2f27032-c8d9-4ebd-b4b3-4d5d82f0521e': {
      credentials: { token: 'ghp_…' },
      base_url: 'https://api.example.com',   // optional
    },
  },
});
```

The SDK then needs nothing — `initSidenet({ auth })` carries them implicitly.

<Warning>
  There is no browser-side equivalent. Anything a page sends alongside a session token is ignored server-side, so a client cannot substitute its own credentials.
</Warning>

## Discovering what each provider needs

Call `GET /v1/copilots/{copilotId}` from your backend once. Its `runtimeAuthProviders` list names the fields:

```javascript theme={null}
const { runtimeAuthProviders } = await api(`/v1/copilots/${copilotId}`, {
  headers: { 'X-User-Id': userId },   // required on this endpoint
});
// [{ providerId: 'f2f2…', providerName: 'github',
//    authFields: ['token'], optionalFields: ['base_url'] }, …]
```

| Field            | Description                                                           |
| ---------------- | --------------------------------------------------------------------- |
| `providerId`     | The key to use in `tools_auth`.                                       |
| `authFields`     | What that provider needs inside `credentials`.                        |
| `optionalFields` | Extras that sit *alongside* `credentials` — `base_url`, for instance. |

<Tip>
  Include only the providers you are actually supplying. A provider whose `authFields` is empty is configured server-side already and needs nothing from you.
</Tip>

## Entry shape

| Field         | Type                  | Description                                                                                                                          |
| ------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `credentials` | `Record<string, any>` | The flat bag the provider's auth type expects — `token` for bearer, `key` / `header` for API key, `username` / `password` for basic. |
| `base_url`    | `string`              | Optional. Overrides the provider's stored base URL for this session.                                                                 |
| `identityId`  | `string`              | Optional, reserved. The stable identity these credentials authenticate as. Accepted but not yet used.                                |

Credentials are encrypted at rest, bound to the session, and injected server-side on every call. They are never returned, logged, or cached.

## Changing a credential

Mint a new session with the updated `tools_auth` and swap it in — no teardown, and the open conversation survives:

```javascript theme={null}
updateSidenetConfig({ auth: { ...newTokens, onRefresh, onError } });
```

<Accordion title="Upgrading from v2.0.123 or earlier">
  Browser-side runtime auth was removed in **v2.0.124**. `updateSidenetRuntimeAuth()` and `getSidenetRuntimeAuthProviders()` no longer exist, and `runtimeAuth` is no longer an `initSidenet()` option.

  | Before (in the browser)                     | Now (on your backend)                                    |
  | ------------------------------------------- | -------------------------------------------------------- |
  | `initSidenet({ runtimeAuth: [...] })`       | `tools_auth` on `POST /v1/token`                         |
  | `updateSidenetRuntimeAuth([...])`           | Mint a new session, then `updateSidenetConfig({ auth })` |
  | `getSidenetRuntimeAuthProviders()`          | `GET /v1/copilots/{id}` → `runtimeAuthProviders`         |
  | Keyed by `providerId` **or** `providerName` | Keyed by `providerId` only                               |
  | `optionalFields: { base_url }`              | `base_url` as a sibling of `credentials`                 |

  The `RuntimeAuthProvider` type is still exported — it now describes the `runtimeAuthProviders` entries above. `RuntimeAuthCredentials` is gone.
</Accordion>
