The client initiated backchannel authentication (CIBA) flow and how to implement it.

Client Initiated Backchannel Authentication (CIBA) Flow

On this page

Overview of the CIBA Flow

The Client Initiated Backchannel Authentication (CIBA) defines a protocol to support initiating authentication without user interaction from a Consumer Device. Authentication is performed via an Authentication Device by the user who also consents (if required) to the request. CIBA is also referred to as a decoupled flow. You can learn more about these concepts in the article Client Initiated Backchannel Authentication .

This article describes the messages in the Poll mode as specified by CIBA and aims to help developers understand and implement the specification.

Client Initiated Backchannel Authentication
  1. The flow starts with an Authentication Request to the Backchannel Authentication Endpoint. The Authorization Server immediately returns an Authentication Request Acknowledgement with a transaction identifier, the auth_req_id.
  2. The user authenticates through an out-of-band mechanism, a mobile device in this example.
  3. Meanwhile, the client polls the Authorization Server regularly, checking for a token. The Authorization Server returns a Token Response with either an error indicating that the authentication is pending, or the tokens if available.


At registration, the client specifies that it will use the Poll mode for token delivery. The client must support the grant type urn:openid:params:grant-type:ciba.

grant_typesyesA list of grant types to be used against the token endpoint. Must include urn:openid:params:grant-type:ciba for CIBA.
token_delivery_modeyesThe mode to use for token delivery. In this case, it'spoll.
backchannel_user_code_parameternoSpecifies if the client supports the user_code parameter. The default value is false. Only relevant if the Authorization Server supports user codes.
token_endpoint_auth_methodyesPublic clients are not supported by CIBA. The client must authenticate with any of the client authentication methods supported by the Authorization Server.

If utilizing Pairwise Pseudonymous Identifiers (PPID), the following parameters are of importance.

subject_typeyespairwise indicates that PPIDs are used in tokens
jwks_uriyes*A URL to the client's public keys in the format of JSON Web Key Set. Either jwks_uri or sector_identifier_uri must be specified.
sector_identifier_uriyes*A URL pointing to a file with a single JSON array of redirect_uri or jwks_uri values. If specified, the jwks_uri must be included in the list of URIs.

Authentication Request

To initiate the Backchannel Authentication, the client sends an authentication request to the Authorization Server's Backchannel Authentication Endpoint using HTTP POST with Content-Type header set to application/x-www-form-urlencoded. The client needs to authenticate to the Authorization Server as part of the authentication request. Any client authentication method defined by OpenID or extensions may be used.

Parameter NameMandatoryDescription
scopeyesCIBA extends OpenID Connect. The list of scopes in the authentication request must therefore contain openid.
or login_hint
yesA proprietary token, a previously issued ID token, or some other string that allows the Authorization Server to identify the user (who it requests to login). One of these parameters must be provided.
acr_valuesnoA space-separated list of preferred authentication context class references. The resulting ID token will contain an acr claim with the Authentication Context Class that the authentication satisfied. The acr claim value can specify the level of assurance of the user's identity or authentication method.
binding_messagenoA human-readable message to be displayed at the consumption device and authentication device. This allows the user to ensure the transaction initiated by the consumption device is the same that triggers the action on the authentication device.
user_codenoIf supported by the client and Authorization Server, the client may request a secret code from the user. This code will be used to authorize initiating an authentication at the user's authentication device.
requested_expirynoAuthentication requests have a lifetime, meaning they can time out if the user does not authenticate in a timely fashion. The client can influence the lifetime of the authentication request with this parameter.

In the example below, the client uses mutual TLS, a client authentication method recommended by CIBA. When using mutual TLS for client authentication, the client must include its client_id in the requests. The line breaks were added for display purposes.

POST /oauth/v2/oauth-authorize HTTP/1.1
Content-Type: application/x-www-form-urlencoded

Authentication Response

The Authorization Server authenticates the client and verifies the authentication request. It checks, for example, if the hint is valid and identifies a known user. In case of an error, an authentication error response is returned. Otherwise, the Authorization Server responds with a successful authentication request acknowledgment.

Successful Authentication Request Acknowledgement

The authentication request acknowledgment includes parameters that are of importance for upcoming requests.

Parameter NameMandatoryDescription
auth_req_idyesThis is the unique ID of the authentication request. It is used in the token requests to identify the transaction started by the client's authentication request. Thus, the client must keep this parameter.
expires_inyesThe number of seconds, since the authentication request was received, that the authentication request will be valid for.
intervalnoThe number of seconds that the client must wait between two polling requests. The default value is 5.

Study the following non-normative example of an authentication request acknowledgment:

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
"auth_req_id": "bspuw6ea-scst-u5hn-p3nt-37khzwY4g",
"expires_in": 900,
"interval": 5

Authentication Error Response

If the authentication request raises an error, the Authorization Server will return an authentication error response using HTTP status codes and descriptive error codes in the body of the response. Just as with token error responses, the body is formatted as application/json.

The following parameters appear in an error response:

Parameter NameMandatoryDescription
erroryesA predefined error code.
error_descriptionnoAdditional information about the error in a human-readable form to help developers diagnose the error.
error_urinoA link to a human-readable web page with additional information about the error similar to error_description.

The non-normative example below demonstrates an authentication error response as a result of the example authentication request listed above:

HTTP/1.1 400 Bad Request
Content-Type: application/json
"error": "unknown_user_id",
"error_description": "Cannot identify the subject from the login_hint_token."

The Authorization Server may return one of the following errors. Please note that this list is not complete by any means. Refer to the specification for a complete list of error codes.

HTTP 400 Bad Request
invalid_requestThe request is malformed. This code may be returned if there is an error with the parameters, such as missing required parameters or duplicates.
invalid_scopeThe requested scope is invalid, unknown, or malformed.
unknown_user_idThe Authorization Server cannot determine which user to authenticate based on the hint provided.
invalid_binding_messageThe binding message is not accepted by the Authorization Server because it is considered invalid in the context of the given authentication request.
unauthorized_clientThe client is not authorized to run a CIBA flow.
HTTP 401 Unauthorized
invalid_clientThe client failed to authenticate. This may be, for example, due to invalid credentials or authentication methods.

Token Request

In Poll mode, after having received the authentication request acknowledgment with auth_req_id, the client polls the token endpoint at a reasonable interval. The client must not poll more frequently than the interval specified by the Authorization Server as part of the authentication acknowledgment.

The Authorization Server may use long polling and not respond before an authentication result is available or a timeout has occurred. Therefore, the CIBA specification recommends waiting for at least 30 seconds between two polling requests, which is the value recommended by RFC6202, Best Practices for Long Polling. When using long polling, the Authorization Server may take more time to respond than the specified interval. In this case, the client must not send two overlapping requests with the same auth_req_id but wait for a response.

For the token request, the client forms a message using the application/x-www-form-urlencoded format and sends it via HTTP POST to the token endpoint. The client must also authenticate as part of the request. The body of the token request contains at least the following parameters:

Parameter NameMandatoryDescription
grant_typeyesThe flow to run to retrieve tokens. For CIBA, the value must be urn:openid:params:grant-type:ciba.
auth_req_idyesThe unique identifier for a transaction initiated by the client. The Authorization Server uses this identifier to retrieve the status of the authentication and issue tokens if authentication was successful and the user gave consent.

The token request may look similar to this example. Note that the client uses mutual TLS for client authentication and must provide the client_id.

POST /oauth/v2/oauth-token HTTP/1.1
Content-Type: application/x-www-form-urlencoded

Successful Token Response

If the token request is valid, and if the user has been authenticated and has authorized the request, the Authorization Server will return a successful response just as with any other OpenID flow.

Consider the non-normative example below. Line breaks are added for readability.

HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store
"access_token": "5ca69968-00ca-4535-82e3-c7badf90b51b",
"refresh_token": "0f8ed1e3-9542-45a0-84ce-4ae3ba61a60e",
"scope": "openid email phone",
"id_token": "eyJraWQiOiI2OTI0NjA1NjkiLCJ4NXQiOiJlYXM0bVVrOWpzMXRCZWVld
"token_type": "bearer",
"expires_in": 300

Token Error Response

As with any other flow in OpenID Connect, the token request in CIBA may result in an error. In addition to the error codes defined as part of the OAuth 2.0 specification, CIBA considers the following as applicable as well:

Error CodeDescription
authorization_pendingThe user has not yet been authenticated, and the authorization request is still pending.
slow_downThe authorization request is still pending, and the client must increase the interval for polling requests by at least 5 seconds.
expired_tokenThe transaction (auth_req_id) has expired. The client must start over with a new Authentication Request.
access_deniedThe user did not consent to the authorization request.
HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-cache, no-store
"error": "authorization_pending"

The specification extends the meaning of some error codes as follows:

Error CodeDescription
invalid_grantThe provided auth_req_id is invalid or was issued to another client.
invalid_requestThe server may return this error if the client does not respect the polling interval. When receiving an invalid_request, the client must stop polling for the auth_req_id.

Resources and Further Information

Join our Newsletter

Get the latest on identity management, API Security and authentication straight to your inbox.

Start Free Trial

Try the Curity Identity Server for Free. Get up and running in 10 minutes.

Start Free Trial