Client-Initiated Backchannel Authentication Flow
Client-Initiated Backchannel Authentication Flow
TBC Bank's TBC ID service supports Client-Initiated Backchannel Authentication (CIBA), allowing your application to authenticate a user without redirecting the user's browser. This page describes the SMS one-time passcode (OTP) flow.
Polling is currently the only supported token delivery mode. In the SMS flow, the client may need to make two backchannel authorization requests and poll the token endpoint after each request.
Before You Start
Retrieve the OpenID Provider configuration for the environment you are integrating with.
Use it to identify the backchannel authentication and token endpoints and check the capabilities available to your client.
Use the same environment throughout the flow; see Overview for the sandbox and production base URLs.
CIBA Proccess
- Start authentication. Send the initial backchannel authorization request with
client_id, the user'slogin_hint, and all requestedscopeandclaims(including verified claims). Include any applicableui_locales. - Get the request ID. TBC Bank returns an
auth_req_idand polling information. If the request is rejected, handle the error and stop the flow. - SMS is sent. Immediately after the initial backchannel authorization request, TBC Bank sends an SMS OTP to the user.
- Poll for the first token response. After the SMS is sent, poll the token endpoint using the CIBA
grant_typeand the initialauth_req_id. Continue at the instructed interval while the request is pending. When this authentication phase completes, TBC Bank returns anid_tokenand anaccess_token. This first response must not contain arefresh_token. Check whether the ID token is intermediate or final, as described in section 10.2.3 of the applicable specification:- Final ID token: authentication is complete. Do not send a second backchannel request; use the access token as authorized for the resource.
- Intermediate ID token: retain the intermediate ID token and access token, then continue to the next step.
- Submit the SMS code. After the user enters the OTP in your application, send a second backchannel authorization request with
client_id, the intermediate ID token asid_token_hint, and the OTP asuser_code. - Poll for final tokens. Use the second request's
auth_req_idto poll the token endpoint. On success, TBC Bank returns a newid_tokenandaccess_token; arefresh_tokenmay also be returned. - Use the access token. Once authentication is complete, validate the token response and use its access token to call the authorized resource. This is the first response's access token when its ID token is final, or the second response's access token when the first ID token is intermediate. To retrieve user claims, call the UserInfo endpoint.
Send all requested claims, including verified claims, in the initial backchannel authorization request. The intermediate token response is not the final resource authorization when its ID token is identified as intermediate.
Endpoints
Backchannel Authorization Endpoint
Send a POST request to the endpoint on the appropriate environment's:
Sandbox: https://test-openbanking.tbcbank.ge/psd2/openbanking/oauth/bc-authorization
Production: https://openbanking.tbcbank.ge/psd2/openbanking/oauth/bc-authorization
Content-Type: application/x-www-form-urlencoded
Authenticate the client using the method configured for your integration. The endpoint is called once to start authentication and, when the first ID token is intermediate, again after the user enters the SMS code.
Backchannel Authorization Request Parameters
Send the request parameters as application/x-www-form-urlencoded form data. Form-encode the values, including the login_hint and claims JSON object.
| Parameter | Usage |
|---|---|
client_id | Your registered client identifier. Include it in both requests. |
scope | Space-separated requested scopes. Include openid and request only scopes supported for your client. Send it with the initial request. |
claims | JSON object describing the requested claims, including any verified claims. Include all required claims in the initial request. |
login_hint | User identifier JSON object. Send either personal_number or msisdn with the initial request. personal_number - User's personal number prefixed with PNOGE-. msisdn - User's mobile number in MSISDN format. |
ui_locales | Preferred user-interface languages, such as en or ka, if supported. Send with the initial request as needed. |
id_token_hint | Intermediate ID token returned from polling the first request. Include it in the second request. |
user_code | SMS one-time passcode entered by the user in your application. Include it in the second request only when backchannel_user_code_parameter_supported is true in the provider's discovery metadata and its use is enabled for your client. |
Backchannel Authorization Response
On success, the endpoint returns a JSON response with the following parameters:
| Parameter | Description |
|---|---|
auth_req_id | Identifier for this backchannel authentication request. Send it as auth_req_id when polling the token endpoint for this request. |
expires_in | Lifetime of the authentication request, in seconds. Stop polling when this period expires. |
interval | Minimum interval, in seconds, between token endpoint polling requests. When returned, wait at least this long between polls. |
The backchannel_user_code_parameter_supported discovery flag indicates whether TBC Bank supports user_code on CIBA backchannel authentication requests. In this SMS flow, the second request uses user_code to carry the OTP entered by the user. The flag reports parameter support; it does not identify the code as an OTP or describe the SMS flow itself.
Include the selected login_hint and claims object as a form parameter and URL-encode it with the rest of the application/x-www-form-urlencoded request body.
Backchannel Authorization Request Example
The following examples show the initial sandbox request with claims form-encoded. The client ID and personal number are illustrative; replace them with values for your integration. Apply the client authentication method configured for your integration. These examples show the initial request; the second request in the SMS flow uses the intermediate id_token as id_token_hint and the SMS code as user_code.
Request verified claims with evidence:
curl --location --request POST 'https://test-openbanking.tbcbank.ge/psd2/openbanking/oauth/bc-authorization' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'client_id=PSDGE-NBG-CLIENTID&scope=openid&login_hint=%7B%22personal_number%22%3A%22PNOGE-01234567890%22%7D&claims=%7B%22userinfo%22%3A%7B%22verified_claims%22%3A%7B%22verification%22%3A%7B%22trust_framework%22%3Anull%2C%22time%22%3Anull%2C%22evidence%22%3A%5B%7B%22type%22%3A%7B%22value%22%3A%22document%22%7D%2C%22document_details%22%3A%7B%22type%22%3Anull%2C%22issuer%22%3A%7B%22country%22%3A%22GE%22%2C%22name%22%3Anull%7D%2C%22document_number%22%3Anull%2C%22date_of_issuance%22%3Anull%2C%22personal_number%22%3Anull%7D%2C%22method%22%3Anull%7D%5D%7D%2C%22claims%22%3A%7B%22given_name%22%3Anull%2C%22family_name%22%3A%7B%22essential%22%3Atrue%7D%2C%22birthdate%22%3Anull%2C%22personal_number%22%3A%7B%22essential%22%3Atrue%7D%2C%22nationalities%22%3Anull%2C%22place_of_birth%22%3A%7B%22essential%22%3Atrue%7D%7D%7D%7D%7D'{
"userinfo": {
"verified_claims": {
"verification": {
"trust_framework": null,
"time": null,
"evidence": [
{
"type": {
"value": "document"
},
"document_details": {
"type": null,
"issuer": {
"country": "GE",
"name": null
},
"document_number": null,
"date_of_issuance": null,
"personal_number": null
},
"method": null
}
]
},
"claims": {
"given_name": null,
"family_name": {
"essential": true
},
"birthdate": null,
"personal_number": {
"essential": true
},
"nationalities": null,
"place_of_birth": {
"essential": true
}
}
}
}
}Request verified claims without specifying evidence:
curl --location --request POST 'https://test-openbanking.tbcbank.ge/psd2/openbanking/oauth/bc-authorization' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data 'client_id=PSDGE-NBG-CLIENTID&scope=openid&login_hint=%7B%22msisdn%22%3A%22+995123456789%22%7D&claims=%7B%22userinfo%22%3A%7B%22verified_claims%22%3A%7B%22verification%22%3A%7B%22trust_framework%22%3Anull%2C%22time%22%3Anull%7D%2C%22claims%22%3A%7B%22given_name%22%3Anull%2C%22family_name%22%3A%7B%22essential%22%3Atrue%7D%2C%22birthdate%22%3Anull%2C%22personal_number%22%3A%7B%22essential%22%3Atrue%7D%2C%22nationalities%22%3Anull%2C%22place_of_birth%22%3A%7B%22essential%22%3Atrue%7D%7D%7D%7D%7D'{
"userinfo": {
"verified_claims": {
"verification": {
"trust_framework": null,
"time": null
},
"claims": {
"given_name": null,
"family_name": {
"essential": true
},
"birthdate": null,
"personal_number": {
"essential": true
},
"nationalities": null,
"place_of_birth": {
"essential": true
}
}
}
}
}Token Endpoint
Poll the token endpoint on the same environment's endpoint. If the discovery configuration provides an mTLS token endpoint alias that applies to your integration, use that URL instead.
Sandbox: https://test-openbanking.tbcbank.ge/openbanking/oauth/token
Production: https://openbanking.tbcbank.ge/openbanking/oauth/token
Content-Type: application/x-www-form-urlencoded
Authenticate the client using the method configured for your integration. Send the following form parameters:
| Parameter | Description |
|---|---|
client_id | Your registered client identifier. |
grant_type | CIBA grant type: urn:openid:params:grant-type:ciba. |
auth_req_id | Request ID returned by the corresponding backchannel authorization request. Use the ID for the initial request when polling for the first token response, and the ID for the second request when polling for the final token response. |
Poll according to the interval and expiry information returned for the request. Stop polling when the request expires or returns a terminal response.
Token Response Parameters
On success, the token endpoint returns a JSON response (Content-Type: application/json). The first response may contain an intermediate ID token, while the response after the second backchannel authorization request contains the final tokens.
| Parameter | Description |
|---|---|
access_token | Token used with the Bearer authorization scheme. The intermediate response's access token is not the final resource authorization when its ID token is intermediate. Use the final access token after authentication is complete. |
token_type | Access token type. |
scope | Space-separated scopes granted for the access token. |
issued_at | Time when the access token was issued, represented as a Unix timestamp in milliseconds. |
expires_in | Access token lifetime in seconds. |
id_token | OpenID Connect ID token. The first response may contain an intermediate ID token; retain it and send it as id_token_hint in the second backchannel authorization request. The final response contains the final ID token. Validate its signature and claims before relying on them. |
refresh_token | Refresh token, returned in the final response when issued. Store it securely and use it only as permitted for your client. |
refresh_token_issued_at | Time when the refresh token was issued, represented as a Unix timestamp in milliseconds. |
refresh_token_expires_in | Refresh token lifetime in seconds. |
refresh_count | Refresh count value returned by TBC Bank. |
See Discovery for provider metadata and Authorization Code Flow for the separate authorization-code flow.
Updated about 4 hours ago
