Keycloak vs Auth0 for Canton Validators
A practical comparison of identity providers for Canton Network validators, based on real production experience running both.
When setting up authentication for a Canton validator, you'll need an OIDC-compliant identity provider. Auth0 and Keycloak are the two most common choices. We ran both in production and ultimately chose Keycloak—here's what we learned.
The Bottom Line
| Consideration | Auth0 | Keycloak |
|---|---|---|
| Setup speed | ✅ Faster initial setup | Requires K8s deployment |
| Claim customization | Actions (JS-based) | ✅ Protocol mappers (declarative) |
| Audience mapper | Requires custom Action | ✅ Built-in, first-class |
| M2M auth | ✅ Works well | ✅ Works well |
| Self-hosted | ❌ SaaS only | ✅ Full control |
| Cost at scale | Per-MAU pricing | ✅ Infrastructure cost only |
| Canton fit | Workable | ✅ Better aligned |
What Canton Actually Needs from Your IdP
Before comparing providers, understand what Canton's authentication layer requires:
- Stable
subclaims — The wallet binds user identity permanently. Ifsubchanges, users lose access to their wallets. - Custom
aud(audience) claims — Canton expects tokens withhttps://canton.network.global(or your custom audience) in the access token. - M2M (machine-to-machine) tokens — The validator backend needs to authenticate to the participant Ledger API using client credentials flow.
- JWKS endpoint — Both validator and participant need to fetch public keys to verify tokens.
Both Auth0 and Keycloak can do all of this. The difference is how.
The Audience Claim Problem
This is where the providers diverge most visibly for Canton operators.
Auth0 Approach
Auth0 requires you to create an API resource and configure your application to request that API's identifier as the audience. Alternatively, you write a custom Action to inject audiences:
exports.onExecutePostLogin = async (event, api) => {
api.accessToken.setCustomClaim('aud', [
event.client.client_id,
'https://canton.network.global'
]);
};This works, but Actions execute JavaScript in Auth0's infrastructure, and debugging them requires navigating Auth0's dashboard and logs.
Keycloak Approach
Keycloak has a built-in Audience protocol mapper. You create a client scope, add the mapper, and attach it to your clients:
Client Scope: canton-audience
└─ Mapper: Audience
Name: canton-audience
Included Custom Audience: https://canton.network.global
Add to access token: ONNo code. Fully declarative. Exportable as JSON. Version-controllable.
Identity Migration: The Hidden Risk
Here's a scenario that catches operators off guard: you start with Auth0 for fast prototyping, then realize you need to switch to Keycloak (or vice versa).
Problem: Auth0 and Keycloak generate different sub claim formats:
| Provider | Typical sub format |
|---|---|
| Auth0 | google-oauth2|123456789012345678901 |
| Keycloak | a1b2c3d4-e5f6-7890-abcd-ef1234567890 |
If you switch IdPs, existing wallet users can't log in—their identity is bound to the old sub.
The Keycloak Escape Hatch
Keycloak's hardcoded claim mapper can force a specific sub value per user, enabling migration from any previous IdP:
{
"name": "legacy-sub-override",
"protocol": "openid-connect",
"protocolMapper": "oidc-hardcoded-claim-mapper",
"config": {
"claim.name": "sub",
"claim.value": "google-oauth2|123456789012345678901",
"access.token.claim": "true"
}
}Auth0 can do something similar with Actions, but the declarative Keycloak approach is easier to audit, version control, and apply per-user when needed.
Self-Hosting: Control vs. Convenience
Auth0 is SaaS-only. Keycloak runs wherever you want.
Why Self-Hosting Matters for Validators
- Data sovereignty — Some jurisdictions require authentication data to stay in-region
- Network topology — Keycloak can run inside your cluster, reducing external dependencies and latency for token validation
- Availability — Your validator doesn't go down because Auth0 has an outage
- Cost predictability — No per-MAU pricing surprises as your user base grows
The Keycloak Deployment Reality
Self-hosting isn't free. You need:
- A PostgreSQL database (or built-in H2 for dev)
- Kubernetes resources (or a VM)
- TLS termination and ingress configuration
- Backup and upgrade procedures
For teams already running Kubernetes for their validator, adding Keycloak is incremental. For teams without K8s experience, Auth0's managed service has real value.
helm repo add bitnami https://charts.bitnami.com/bitnami
helm install keycloak bitnami/keycloak \
--set auth.adminUser=admin \
--set auth.adminPassword=<secure-password> \
--set postgresql.enabled=trueMachine-to-Machine Authentication
Both providers handle M2M well. The validator backend authenticates to the participant Ledger API using client credentials flow—this works identically in both:
curl -X POST https://your-idp/oauth/token \
-d "grant_type=client_credentials" \
-d "client_id=validator-backend" \
-d "client_secret=<secret>" \
-d "audience=https://canton.network.global"The main difference: Auth0 charges for M2M tokens in some plans, while Keycloak has no per-token cost.
Cost Comparison
| Scenario | Auth0 | Keycloak |
|---|---|---|
| 10 users (dev/test) | Free tier | ~$20/mo (small K8s) |
| 1,000 MAU | ~$230/mo (Essentials) | ~$50/mo (K8s + DB) |
| 10,000 MAU | ~$1,000+/mo | ~$100/mo (same infra) |
| M2M tokens | Plan-dependent limits | Unlimited |
For validators expecting growth, Keycloak's flat infrastructure cost becomes increasingly attractive.
Why We Chose Keycloak
We started with Auth0 for speed. It worked. But as we moved toward production:
- Audience mapping friction — Debugging Auth0 Actions was slower than editing Keycloak mappers
- Configuration drift — Auth0's UI-first approach made it hard to version control our IdP config; Keycloak exports to JSON
- Cost trajectory — Our user growth projections made Auth0's pricing less attractive
- Operational consistency — We were already running everything else in Kubernetes; adding Keycloak kept our operational model uniform
Recommendations
Choose Auth0 If:
- You need to ship in days, not weeks
- Your team lacks Kubernetes/infrastructure experience
- You have a small, stable user base
- You're prototyping and may pivot away from Canton
Choose Keycloak If:
- You're already running Kubernetes
- You need full control over claim customization
- You expect user growth or heavy M2M token usage
- You want version-controlled, auditable IdP configuration
- You may need to migrate users from another IdP

