> For a complete index of all SignalWire documentation pages, fetch https://signalwire.com/docs/llms.txt

# CredentialProvider

> Provides authentication credentials to the SDK.

Provides authentication credentials to the SDK.

Implementors are responsible for:

* Obtaining credentials (e.g. via API calls, user login flows, or third-party auth services).
* Returning a valid [SDKCredential](/docs/browser-sdk/v4/reference/interfaces/sdk-credential) with either a `token` or `authorizationState`.
* Setting `expiry_at` when the credential has a known expiration so the SDK can schedule refresh.
* Handling errors and never leaking sensitive data through error messages.

The SDK owns the credential lifecycle: it calls `authenticate` once during initialization
and, if `refresh` is provided and `expiry_at` is set, schedules automatic refresh before expiry.

### Refresh precedence

The SDK selects exactly one refresh mechanism per session, evaluated at connect
time (and re-evaluated on reconnect):

| `refresh` provided | SAT carries `sat:refresh` scope | Active mechanism                   |
| ------------------ | ------------------------------- | ---------------------------------- |
| yes                | yes                             | Client Bound SAT (DPoP, internal)  |
| yes                | no                              | Developer-provided `refresh()`     |
| no                 | yes                             | Client Bound SAT (DPoP, internal)  |
| no                 | no                              | None — session ends at `expiry_at` |

When the SDK falls back to the developer-provided `refresh()` because the SAT
lacked `sat:refresh` scope, a `credential_refresh_fallback` event is emitted on
[`SignalWire.warnings$`](/docs/browser-sdk/v4/reference/signalwire/warnings\$) so
application code can observe the transition.

Mint a SAT via `POST /api/fabric/subscribers/tokens` with `fingerprint` and
`scope: ["sat:refresh"]` (both currently optional on that endpoint) to enable
the Client Bound SAT path; otherwise provide `refresh()` here.

## **Properties**

Obtains fresh credentials before the current ones expire. Optional. Implementor responsibilities: - Resolve with a new [SDKCredential](/docs/browser-sdk/v4/reference/interfaces/sdk-credential) containing an updated `token` (or `authorizationState`) and `expiry_at`. - Reject (throw) if refresh is not possible — the SDK will stop the refresh schedule. SDK behavior: - Only called when `expiry_at` was set on the previous credential AND the SAT does not carry `sat:refresh` scope (otherwise the SDK refreshes internally via Client Bound SAT). See the precedence table above. - Scheduled automatically before expiry; implementors do not need to manage timing. - On rejection, the refresh schedule stops and the session continues with the current credentials until they expire.

## **Methods**

### authenticate()

```ts
authenticate(context?): Promise<SDKCredential>
```

Obtains the initial credentials. Called once during client initialization.

Implementor responsibilities:

* Resolve with a valid [SDKCredential](/docs/browser-sdk/v4/reference/interfaces/sdk-credential) on success.
* Reject (throw) on failure — this will cause client initialization to fail.
* When `context.fingerprint` is provided, forward it to the server-side token
  endpoint with `scope: "sat:refresh"` to enable automatic token refresh.
  Ignoring `context.fingerprint` causes the SDK to fall back to `refresh()`
  (if provided) or end the session at expiry.

SDK behavior:

* Awaits this method before establishing the WebSocket connection.
* On rejection, propagates the error to the caller of `SignalWire()`.

#### Parameters

Authentication context provided by the SDK at credential-request time. See [`AuthenticateContext`](/docs/browser-sdk/v4/reference/interfaces/authenticate-context).

#### Returns

`Promise<SDKCredential>`