githubEdit

CBTC Authentication

👥 Audience: App Developers and Infrastructure Integrators setting up authentication for Canton Ledger API access.

⚠️ API Disclaimer: CBTC APIs are subject to change. Authentication flows may evolve as Canton's identity layer matures.


Overview: How Authentication Works for CBTC on Canton

All CBTC operations go through the Canton Ledger API, which requires a valid JWT (JSON Web Token) for every request. The JWT is issued by an OIDC (OpenID Connect) provider connected to your Canton participant node.

This guide covers two authentication options for developers building with CBTC and the Canton Network:

  • Keycloak (officially supported by BitSafe)

  • Auth0 (community example, not officially maintained) For deeper background on how Canton handles authentication and authorization at the platform level, see the Canton Authorization Documentationarrow-up-right.


CBTC Authentication Flow: JWT and OIDC


Set Up Keycloak for CBTC Authentication (Officially Supported) ✅

Keycloak is the officially supported OIDC provider for CBTC integrations. BitSafe engineering provides support for Keycloak-based authentication.

Prerequisites

  • Keycloak instance running and accessible

  • A realm configured for your Canton participant

  • A client application registered in Keycloak

Step 1: Register a Client

In your Keycloak admin console:

  1. Navigate to your realm → ClientsCreate client

  2. Set Client type to OpenID Connect

  3. Set Client ID (e.g., cbtc-minting-app)

  4. Enable Client authentication (for server-to-server flows)

  5. Under Service account roles, enable as needed

Step 2: Configure Your Canton Participant

Your Canton participant must be configured to trust your OIDC provider. Participant configuration is complex and environment-specific. Refer to the official validator operator documentation:

Canton Validator Operator Guide →arrow-up-right

Step 3: Obtain a Token

Client Credentials flow (for server-to-server / backend integrations):

Password grant flow (for user-facing / interactive applications):

Response (both flows):

Step 4: Use the Token

Include the token in all Canton Ledger API calls:

Token Refresh

Tokens expire (typically 5 minutes for Keycloak). Your application should:

  1. Cache the token until near expiry

  2. Request a new token before the current one expires

  3. Retry failed requests with a fresh token if you receive a 401


Set Up Auth0 for CBTC Authentication (Community Example) ⚠️

💡 Auth0 compatibility. Both Keycloak and Auth0 follow the OAuth2/OIDC standard, so the login flow and token usage are identical. There is one known caveat: Auth0 requires an extra audience parameter in the token request. The cbtc-lib and canton-lib libraries do not pass this parameter by default, so they won't work out of the box with Auth0. This is a straightforward fix on either the library side or the client side. See the workaround below. BitSafe engineering support covers Keycloak-based authentication only. For Auth0-specific configuration issues, refer to Auth0's documentationarrow-up-right.

Prerequisites

  • Auth0 tenant and API configured

  • Application registered as Machine to Machine (for backend) or Single Page Application (for frontend)

Step 1: Create an Auth0 API

In the Auth0 dashboard:

  1. Navigate to ApplicationsAPIsCreate API

  2. Set Name (e.g., Canton Ledger API)

  3. Set Identifier to your participant's Ledger API URL

  4. Set Signing Algorithm to RS256

Step 2: Register a Machine-to-Machine Application

  1. Navigate to ApplicationsCreate Application

  2. Select Machine to Machine Applications

  3. Authorise the application to call your Canton Ledger API

  4. Note the Client ID and Client Secret

Step 3: Configure Your Canton Participant

Point your participant to Auth0's JWKS endpoint. Participant configuration is complex and environment-specific. Refer to the official validator operator documentation:

Canton Validator Operator Guide →arrow-up-right

Step 4: Obtain a Token

⚠️ The audience parameter is required for Auth0. This is the key difference from Keycloak. Without it, Auth0 will return an opaque token that the Canton participant will reject. Set audience to your participant's Ledger API base URL. If using cbtc-lib / canton-lib: The Rust libraries' keycloak::login::password and keycloak::login::client_credentials functions do not pass an audience parameter. To use Auth0, you'll need to either:

  1. Make the token request directly via HTTP (as shown above) instead of using the library helper

  2. Patch the login functions to include the audience field, which is a small change A library-level fix may be shipped in a future release of canton-lib.

Step 5: Use the Token

Same as Keycloak. Include the Bearer token in all API requests.


Wallet-Based Authentication for Canton dApps

For applications that use Canton-compatible wallets (Loop, Console/Zoro, Bron), authentication is handled by the wallet provider. Your application receives a JWT through the wallet's SDK or connect flow.

Supported wallets:

  • Loop Wallet

  • Console / Zoro Wallet

  • Bron Wallet

  • WalletConnect (for dApp integrations)

  • Node login (direct participant authentication) See the Integration Guides for wallet-specific connection patterns.


Troubleshooting

Issue
Cause
Resolution

401 Unauthorized on every request

JWT not trusted by participant

Verify JWKS URL in participant config matches your OIDC provider

Token expires immediately

Clock skew between OIDC provider and participant

Sync system clocks (NTP)

CORS errors in browser

Ingress not configured for CORS

Add CORS annotations to your ingress — see Minting App Installation Guide

invalid_grant from OIDC provider

Client secret rotated or incorrect

Regenerate and update client secret


JWT Security Best Practices for Canton Applications

  • Never expose client secrets in frontend code. Use the Client Credentials flow only from backend services.

  • Rotate secrets regularly. Update client secrets in both your OIDC provider and your application config.

  • Use short-lived tokens. The default 5-minute expiry is appropriate for most use cases.

  • Restrict party access. Configure your JWT claims to limit which Canton parties a token can act as.


Last updated