How to Configure DCR Fallback#

You want users on attestation-incapable devices — older OS versions, non-Google-certified Android hardware, simulators, devices the server rejects — to still complete authentication. Dynamic Client Registration (DCR) is the SDK’s fallback: when attestation is unavailable, the SDK registers a per-device dynamic OAuth client and uses that client for subsequent token requests.

For the concept and trade-offs, see DCR . For the per-layer configuration depth, see DCR (SDK Layer) . This page is the end-to-end task walkthrough.

Prerequisites#

DCR is a coordinated client-and-server feature. The server side must be configured first; the client side is wired afterward. On the Curity Identity Server:

  1. Main HAAPI client with a real authentication method (Secret, MTLS, or Signed JWT). These are the credentials that ship with your app and the SDK uses to bootstrap the registration request. The main client must not use no-authentication.
  2. Template HAAPI client carrying the haapi capability. Defines the shape of the per-device dynamic clients (capabilities, allowed scopes, token settings). The template client must reference the main client via the authenticate-client-by setting.
  3. OAuth profile exposes the DCR endpoint (oauth-registration). Note the URL — you’ll paste it into the client configuration below.

See the Implementing HAAPI Attestation Fallback guide on the Curity resources site for the full server-side walkthrough.

Step-by-Step#

1. Choose a client authentication method#

DCR cannot use no-authentication — the SDK must prove itself as the main HAAPI client when calling the registration endpoint. Pick one:

  • Secret — easy, development-only.
  • Mutual TLS — production-recommended for sensitive deployments.
  • Signed JWT (asymmetric) — production-recommended for app distribution where the private key stays on-device.

Per-method depth lives at Client Authentication (SDK Layer) .

2. Wire DCR + the auth method onto your builder#

Configure both unconditionally — the SDK picks attestation when available and falls back to DCR only when needed.

SDK Layer#

let dcrConfiguration = DCRConfiguration(
    templateClientId: "dcr-template-client-haapi-ios",
    clientRegistrationEndpointUrl: URL(
        string: "/oauth/oauth-registration",
        relativeTo: baseURL
    )!
)

let haapiAccessor = HaapiAccessorBuilder(haapiConfiguration)
    .setDCRConfiguration(dcrConfiguration)
    .setClientAuthenticationMethod(method: ClientAuthenticationMethodSecret("foo"))
    .buildForHaapi()

UI Layer#

HaapiUIKitConfigurationBuilder(...)
    .setClientAuthenticationMethod(method: ClientAuthenticationMethodSecret("foo"))
    .setDCRConfiguration(
        configuration: DCRConfiguration(
            templateClientId: "dcr-template-client-haapi-ios",
            clientRegistrationEndpointUrl: URL(
                string: "/oauth/oauth-registration",
                relativeTo: baseURL
            )!
        )
    )
    .build()

Verify It Works#

The SDK selects between attestation and DCR automatically at runtime. To confirm the DCR path runs on an attestation-incapable device:

  • Run the app on an iOS Simulator or an Android emulator.
  • Watch the logs for HAAPI_DRIVER_DCR records (Android) or DCR-related events in HaapiLogger (iOS). On first launch, the SDK calls the registration endpoint and persists the dynamic client identity to storage.
  • The HAAPI flow proceeds and the user receives an access token, just as on an attestation-capable device.

Pitfalls#

  • Forgetting client authentication. Configuring setDCRConfiguration / setDcr without a non-None authentication method causes the first registration call to fail at the server. The SDK Layer’s DCR warning admonition spells this out.
  • Template client missing authenticate-client-by. Without this server setting, the registration request is unauthenticated and the server rejects it. Validate the template-client configuration before testing the client path.
  • Wrong endpoint URL. The dist endpoint typically lives at <baseURL>/oauth/oauth-registration, but some deployments differ. Copy the exact URL from the OAuth profile on CIS.
  • Branch on attestation capability. Don’t. Both HaapiAccessorBuilder (iOS) and HaapiAccessorFactory (Android) decide the path automatically. Ship one configuration; the SDK ignores the DCR config on attestation-capable devices.

Was this helpful?