Bearer Token
This guide documents the implementation of the Bearer Token step in an OAuth 2.0 flow customized for the Interactive Brokers (IBKR) Web API. This step exchanges the OAuth2 access token obtained in the previous step for a gateway session token (referred to in the response as access_token, but functionally an SSO session credential) at IBKR’s sso-sessions endpoint. Like the Access Token step, authentication is conveyed via a signed JWT client assertion using RSA-SHA256, but the claim set, transport, and header structure differ meaningfully from the prior step.
This is the second of two OAuth 2.0 steps in the IBKR flow:
- Access Token (prerequisite — produces the
access_tokenused as the Bearer credential here) - Bearer Token / SSO Session establishment (documented here)
Construct the Endpoint URL
The Bearer Token (SSO Session) endpoint is always accessed via POST over HTTPS.
Assemble the JWT Header and Claims
Implementation note: this claim set is produced by the same compute_client_assertion() helper documented in the Access Token step, branching on the target url. Confirm your implementation routes to the {gatewayUrl}/api/v1/sso-sessions branch, not the token endpoint branch, when building this assertion.
Base64URL-Encode the Header and Claims
This reuses the same base64_encode() helper and base64url encoding rules (strip padding, substitute -/_) as the Access Token step — see that guide for details. Consistency here matters: any deviation in JSON serialization or encoding between steps will produce a structurally valid but unverifiable JWS.
Sign the Payload with RSA-SHA256
Process:
- Encode the
payload(encoded_header.encoded_claims) to UTF-8 bytes. - Compute the SHA-256 digest.
- Sign the digest using PKCS#1 v1.5 padding with the same RSA private key used throughout the flow.
- Base64URL-encode the raw signature bytes.
Assemble the Client Assertion (JWS)
As in the Access Token step, this produces a complete compact JWS:
Unlike the Access Token step, this assertion is not wrapped in a client_assertion form field — it is transmitted as the raw request body, as shown next.
Construct the Authorization Header and Request Body
This differs structurally from the Access Token step, which conveyed its assertion as one field within a form-encoded body and required no Authorization header at all. Here, both an Authorization header and a JWT body are required simultaneously — mixing bearer-token authentication with a signed-assertion payload.
Execute the Request and retrieve the session access_token
The request body is the raw JWS string (data=signed_request), sent with Content-Type: application/jwt.
On success, the response JSON contains an access_token field — do not confuse this with the OAuth2 access token from the previous step; this value represents the established SSO gateway session and is the credential used for subsequent authenticated Client Portal / streaming requests (e.g. via websocket).
A non-200 response returns None in the reference implementation; production code should inspect the response body and status code for actionable error details rather than failing silently.

