Skip to content

Feat: Add Client-Initiated Backchannel Authentication (CIBA) support#254

Merged
tanya732 merged 2 commits into
feat/auth-for-ai-agentsfrom
feat/add-ciba-support
Jul 9, 2026
Merged

Feat: Add Client-Initiated Backchannel Authentication (CIBA) support#254
tanya732 merged 2 commits into
feat/auth-for-ai-agentsfrom
feat/add-ciba-support

Conversation

@tanya732

@tanya732 tanya732 commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds support for Client-Initiated Backchannel Authentication (CIBA),

CIBA is implemented as a stateless, application-owned polling flow, consistent with the existing SDK architecture. The implementation is built entirely on the CIBA primitives already available in com.auth0:auth0:3.10.0

Flow

CIBA consists of two steps:

  1. Initiate

    • The application requests an out-of-band authentication.
    • Auth0 returns:
      • auth_req_id
      • polling interval
      • expires_in
  2. Poll

    • The application polls the token endpoint until:
      • the user approves (tokens are returned), or
      • a terminal error is received.

The library intentionally remains stateless. The application owns the polling loop and is responsible for honoring the returned interval and expires_in.


What's added

AuthenticationController

New public APIs mirroring the existing renewAuth overload pattern:

  • backChannelAuthorize(scope, bindingMessage, loginHint[, domain])

    • Returns BackChannelAuthorizeRequest
    • Optional fluent configuration:
      • .withAudience(...)
      • .withRequestedExpiry(...)
  • backChannelPoll(authReqId[, domain])

    • Returns BackChannelTokenRequest

Both APIs provide:

  • Static-domain overloads
  • Explicit-domain overloads (useful when polling occurs outside the initiating HTTP request or MCD)

New request types

BackChannelAuthorizeRequest

Fluent wrapper for POST /bc-authorize.

Returns the raw BackChannelAuthorizeResponse containing:

  • authReqId
  • interval
  • expiresIn

This allows the application to drive the polling lifecycle.

BackChannelTokenRequest

Fluent polling request that delegates directly to RequestProcessor.

New exception

BackChannelAuthorizationException

Extends IdentityVerificationException.

Provides helper methods for distinguishing retryable vs. terminal OAuth errors.

Retryable:

  • isAuthorizationPending()
  • isSlowDown()

Terminal:

  • isExpiredToken()
  • isAccessDenied()

RequestProcessor

Added executeBackChannelPoll(...), which:

  • Executes the CIBA grant using urn:openid:params:grant-type:ciba
  • Maps APIException.getError() to BackChannelAuthorizationException
  • Requires and verifies the returned ID token
  • Reuses the existing code-flow ID token verifier
  • Preserves organization validation (org_id / org_name) when configured
  • Returns library Tokens

Example

// Step 1: Initiate
BackChannelAuthorizeResponse response = controller
    .backChannelAuthorize(
        "openid profile",
        "Approve login 1234",
        loginHint)
    .withAudience("https://api.example.com")
    .execute();

// Step 2: Application-owned polling loop
Tokens tokens;

while (true) {
    try {
        tokens = controller
            .backChannelPoll(response.getAuthReqId())
            .execute();
        break;
    } catch (BackChannelAuthorizationException e) {
        if (e.isAuthorizationPending() || e.isSlowDown()) {
            Thread.sleep(response.getInterval() * 1000L);
        } else {
            throw e;
        }
    }
}

Notes

  • BackChannelTokenResponse currently does not include:

    • refresh_token
    • token_type
  • Therefore the returned Tokens contain:

    • refreshToken = null
    • type = "Bearer"
  • Refresh token support for CIBA would require an upstream change in auth0-java.

  • No module-info changes are required since the entire com.auth0 package is already exported.


Test plan

BackChannelAuthorizeRequestTest (6 tests)

  • 3-argument vs. 5-argument overload selection
  • Optional parameter handling
  • Response passthrough
  • Auth0Exception propagation

BackChannelTokenRequestTest (3 tests)

  • Delegation to RequestProcessor
  • Pending authorization propagation
  • Auth0Exception propagation

BackChannelAuthorizationExceptionTest (5 tests)

  • Verifies each isX() helper maps to the correct OAuth error
  • Confirms inheritance from IdentityVerificationException

✅ Full test suite passes with no regressions.

@tanya732 tanya732 marked this pull request as ready for review July 9, 2026 10:51
@tanya732 tanya732 requested a review from a team as a code owner July 9, 2026 10:51
@tanya732 tanya732 merged commit 0b1b19e into feat/auth-for-ai-agents Jul 9, 2026
1 check passed
@tanya732 tanya732 deleted the feat/add-ciba-support branch July 9, 2026 11:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants