Some of the most sensitive approvals happen when the person who must consent is not sitting at the device that is asking for it. OpenID Connect Client Initiated Backchannel Authentication (CIBA) is the OpenID Foundation flow that lets an application ask an identity provider to authenticate a known user on a separate device, usually their phone, without any browser redirect. It was written for call centres, bank branches and point of sale payments, and it has become the standard way for an AI agent to pause and get a human to approve an action. This guide explains the flow, its three delivery modes, the FAPI CIBA profile and the controls that stop CIBA turning into a push fatigue channel. It is for identity architects, IAM engineers and teams building agent approval steps.
Key takeaways
- CIBA decouples the two devices. The client starts the flow on a consumption device it may control (a call centre desktop, a till, an agent runtime) and the user authenticates on their own authentication device.
- It is a backchannel flow. The client calls a backchannel authentication endpoint directly, receives an
auth_req_id, then collects tokens by polling, by ping callback or by push. - The binding message is the main anti-confusion control. A short value shown on both devices lets the user confirm they are approving this transaction and not a stranger's.
- Unsolicited requests are the core risk. Anyone able to name a user can trigger a prompt, so use user codes, signed hints, rate limits and number matching style binding.
- For high assurance, use the FAPI CIBA profile. It requires confidential clients and signed requests, forbids push mode and sits naturally beside FAPI 2.0 sender-constrained tokens.
What it is
CIBA, formally OpenID Connect Client-Initiated Backchannel Authentication Flow, Core 1.0, is a Final OpenID Foundation specification dated 1 September 2021. It defines an authentication flow in which a relying party that already holds an identifier for the user starts the interaction itself, talking directly to the OpenID Provider (OP) instead of redirecting a browser. The specification separates two roles:
- Consumption device (CD): the device that helps the user consume the service. In CIBA the user is not necessarily in control of it: a contact centre agent's desktop, a branch teller's terminal or a shop's payment terminal.
- Authentication device (AD): the device on which the user authenticates and authorises the request, often a smartphone running the OP's app.
The specification's own non-normative use cases are a call centre agent authenticating a caller, a bank teller authenticating a customer in a branch, and a user approving on their smartphone a payment made at a point of sale terminal. The newer use case is an autonomous or semi-autonomous AI agent that needs a human to approve a purchase, a data release or a production change while the agent waits. Vendor documentation now describes CIBA based "asynchronous authorisation" for exactly that: the agent backend calls the backchannel endpoint, the user gets a push notification on an enrolled device, and the agent receives tokens only after approval.
CIBA is not a replacement for the authorisation code flow. Where the user is at the browser that needs the session, the code flow with PKCE is still correct. See the OAuth 2.0 and OpenID Connect Guide for the core flows CIBA builds on.
How it works
- Registration and discovery: the OP advertises
backchannel_authentication_endpointandbackchannel_token_delivery_modes_supportedin its discovery document, optionallybackchannel_user_code_parameter_supportedandbackchannel_authentication_request_signing_alg_values_supported. Each client registers onebackchannel_token_delivery_modeand, for ping or push, an HTTPSbackchannel_client_notification_endpoint. - Authentication request: the client authenticates to the backchannel endpoint and sends
scope(which must includeopenid) plus exactly one hint:login_hint_token,id_token_hintorlogin_hint. Sending more than one is aninvalid_request. Optional parameters arebinding_message,user_code,acr_valuesandrequested_expiry; ping and push clients also send aclient_notification_token. - Acknowledgement: the OP returns an opaque
auth_req_id(at least 128 bits of entropy),expires_inand, for poll and ping, an optionalintervalthat defaults to 5 seconds. - User interaction: the OP contacts the user's authentication device, shows the binding message and any transaction details, and authenticates the user at the requested level.
- Token delivery: depending on the registered mode, the client polls the token endpoint with grant type
urn:openid:params:grant-type:ciba, receives a ping and then calls the token endpoint, or receives the tokens pushed to its notification endpoint.
Delivery modes compared
| Mode | How the result arrives | Strengths | Watch out for |
|---|---|---|---|
| Poll | Client calls the token endpoint no more often than interval; the OP may hold the request open (30 seconds suggested) | No inbound endpoint needed; simplest for agent backends and firewalled clients | Respect slow_down (add at least 5 seconds); wasted calls at scale |
| Ping | OP POSTs only the auth_req_id to the client's notification endpoint, authenticated with the client_notification_token; client then fetches tokens | Fast, no polling load; tokens still come from the authenticated token endpoint | Notification endpoint must be under the client's control and protected |
| Push | OP POSTs the ID token, access token and optional refresh token to the notification endpoint | Lowest latency | Tokens travel to an endpoint rather than being fetched; ID token must carry at_hash, urn:openid:params:jwt:claim:rt_hash and urn:openid:params:jwt:claim:auth_req_id; not permitted under FAPI CIBA |
Errors worth handling explicitly
| Where | Error | Meaning and action |
|---|---|---|
| Backchannel endpoint | unknown_user_id, expired_login_hint_token | Hint did not resolve; do not reveal to the caller whether the account exists |
| Backchannel endpoint | missing_user_code, invalid_user_code | User code required or wrong; count as a failed authentication attempt |
| Backchannel endpoint | invalid_binding_message | Message too long or wrong characters; keep it short and plain text |
| Token endpoint | authorization_pending, slow_down | Keep waiting; back off |
| Token endpoint | access_denied, expired_token | User refused or did not respond; the agent or operator must not retry blindly |
| Push error payload | transaction_failed | Push mode only; treat as a failed approval |
Signed requests and the FAPI CIBA profile
CIBA allows the request to be sent as a JWT signed with an asymmetric key in the request parameter, carrying aud, iss, exp, iat, nbf and jti; encrypted request objects are not supported. The Financial-grade API: Client Initiated Backchannel Authentication Profile, still an Implementer's Draft, tightens this: the authorisation server supports only confidential clients, requires signed requests with nbf and exp no more than 60 minutes apart, requires either a unique authorisation context or a binding_message, requires poll mode, allows ping, and prohibits push. It also says login_hint should not be used to carry payment intent, and recommends PS256 or ES256 and TLS 1.2 or later. FAPI 2.0 Security Profile (Final, February 2025) names CIBA as one of the two grants with detailed security analysis and requires sender-constrained access tokens via mTLS or DPoP and client authentication by mTLS or private_key_jwt. See the OAuth 2.1, GNAP and FAPI Guide and the DPoP Guide.
Why it matters
- Call centres and branches: knowledge based questions over the phone are weak and are the help desk attacker's favourite route. A CIBA prompt to the customer's registered app, with a binding code the agent reads out, replaces "what is your mother's maiden name" with possession and biometric based authentication. See the Account Recovery and Help Desk Security Guide.
- Payments: decoupled approval is how many banks meet strong customer authentication when the payer is at a terminal or another party's website. See the PSD2/PSD3 Strong Customer Authentication Guide.
- AI agents: an agent cannot complete a browser redirect for a user who is not there. CIBA gives it a standards based way to ask for consent at the moment of a risky action, get an access token scoped to that action and continue. Combined with Rich Authorization Requests the prompt can show "pay 50.00 GBP to ExampleCorp" instead of a vague scope. See the Human-in-the-Loop for AI Agents Guide and the OAuth Rich Authorization Requests (RAR) Guide.
- Accountability: the approval is an OP event tied to a user, an authentication context (
acr), a client and a request ID, which is far better audit evidence than a chat message saying "yes".
Implementing CIBA for agent approvals
- Define what needs approval: list agent actions by risk (payments above a threshold, data exports, privileged changes) and decide which require a CIBA step. See the AI Agent Action Approvals and Spending Limits Guide.
- Register the agent as a confidential client: use
private_key_jwtor mTLS, poll mode for agents without an inbound endpoint, and a shortrequested_expiry(minutes, not hours). - Bind the request: generate a random binding message per transaction, attach structured transaction details (RAR
authorization_detailswhere the OP supports it), and useid_token_hintor a signedlogin_hint_tokenrather than a free text user name. - Constrain the result: request a narrow scope and audience, prefer sender-constrained tokens, and do not issue refresh tokens for one-off approvals. If the agent must act at a downstream service, exchange the token rather than forwarding it. See the OAuth Token Exchange and Delegation Guide.
- Pilot: start with one low risk action and an internal user group, measure approval latency and denial rates, then extend.
- Roll back safely: if CIBA is unavailable, the agent must fail closed (stop and hand back to the user), never fall back to acting without approval.
Detection and measurement
- Log: every backchannel request with client ID, user, hint type, binding message,
acrrequested and result; map anomalies to ATT&CK T1621 Multi-Factor Authentication Request Generation. - Metrics: requests per user per hour (spikes suggest prompt bombing); denial rate by client; share of requests reaching
expired_token; median approval latency; percentage of approvals carrying transaction details or RAR; number of clients registered for push mode (target zero for high assurance).
Common misconceptions
- "CIBA is just push MFA." Push MFA is a product feature; CIBA is a protocol that returns ID and access tokens to a third party client. That is more powerful and needs client authentication, binding and scoping.
- "The user approving means the user started it." CIBA requests are initiated by the client. Attackers who can name a user can generate prompts, exactly as in the Cisco Breach 2022, where repeated push prompts combined with voice phishing ended in an accepted prompt. The specification's
user_codeexists to prevent unsolicited flows. See the MFA Fatigue and Bypass Guide. - "A binding message is enough." Only if users compare it. The FAPI CIBA profile notes that where comparison is unacceptable, QR codes or ephemeral identifiers are alternatives, and that decoupled flows reduce the data available for fraud detection.
- "Push mode is the modern option." Push is the one mode the FAPI CIBA profile forbids, because tokens are delivered to an endpoint rather than collected by an authenticated client.
- "An
id_token_hintproves the user is present." The specification notes expired ID tokens can still be valid hints; a hint identifies the user, it does not authenticate them.
Related concepts
| Concept | Relationship to CIBA |
|---|---|
| Device Authorization Grant (RFC 8628) | Also decoupled, but the user starts by visiting a URL and typing a code; in CIBA the client already knows the user and the OP contacts them |
| Rich Authorization Requests (RFC 9396) | RAR explicitly allows authorization_details in CIBA requests, so the approval screen shows the exact transaction |
| Token exchange (RFC 8693) | Turns the user approved token into a narrower token for a downstream API on the user's behalf |
| DPoP (RFC 9449) and mTLS (RFC 8705) | Bind the resulting access token to the client's key, required by FAPI 2.0 |
| Agent identity | The agent should be its own registered client with its own credentials, so approvals are attributable to it. See the Agent Identity and Access Guide |
Framework mapping
| Framework | Reference | How CIBA supports it |
|---|---|---|
| NIST CSF 2.0 | PR.AA-03, PR.AA-04 | Users authenticated on a trusted device; identity assertions signed and verified |
| NIST SP 800-53 Rev 5 | IA-2, IA-2(8), IA-11 | Strong, replay resistant authentication and re-authentication at the point of a sensitive action |
| NIST SP 800-53 Rev 5 | AC-6, AU-2 | Narrow, per action tokens; approval events logged |
| MITRE ATT&CK | T1621, T1528 | Threats to watch: prompt bombing and theft of the resulting application access tokens |
Practitioner checklist
- Register CIBA clients as confidential clients using
private_key_jwtor mTLS. - Use poll or ping mode; disable push mode for high assurance and agent clients.
- Require signed authentication requests with a short lifetime and a unique
jti. - Send a random binding message and, where possible, RAR transaction details with every request.
- Enable
user_codeor signed hints for flows exposed to callers or untrusted operators. - Rate limit backchannel requests per user and per client, and alert on bursts and repeated denials.
- Set short
requested_expiryvalues and avoid refresh tokens for one-off approvals. - Issue sender-constrained, narrowly scoped access tokens to agents and fail closed when approval is unavailable.
Standards and references
- OpenID Foundation: OpenID Connect Client-Initiated Backchannel Authentication Flow, Core 1.0
- OpenID Foundation: Financial-grade API, Client Initiated Backchannel Authentication Profile
- OpenID Foundation: FAPI 2.0 Security Profile
- OpenID Foundation: OpenID Specifications
- IETF: RFC 9396 OAuth 2.0 Rich Authorization Requests
- Auth0: Asynchronous Authorization for AI Agents
Related NHI Mgmt Group resources: OAuth 2.0 and OpenID Connect Guide · OAuth Token Exchange and Delegation Guide · Agent Identity and Access Guide · DPoP Guide · OAuth Rich Authorization Requests (RAR) Guide