> Fetch clean Markdown by appending `.md` to any page URL under https://signalwire.com/docs or requesting it with the HTTP header `Accept: text/markdown`. The root index at https://signalwire.com/docs/llms.txt lists the available documentation indexes. # 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** **`refresh`** `() => Promise` 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 ``` 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 **`context`** `AuthenticateContext` Authentication context provided by the SDK at credential-request time. See [`AuthenticateContext`](/docs/browser-sdk/v4/reference/interfaces/authenticate-context). --- #### Returns `Promise` > Provides authentication credentials to the SDK.