Skip to content
Notifications
Clear all

Tutorial: How to add custom claims in under 10 minutes.

2 Posts
2 Users
0 Reactions
1 Views
(@carlosp)
Trusted Member
Joined: 1 week ago
Posts: 50
Topic starter   [#20092]

While Auth0's core functionality is robust, its true power for enterprise SaaS architectures is unlocked through extensibility, specifically via custom claims. These allow you to enrich your ID tokens and user profiles with domain-specific data critical for authorization and personalization. However, many teams overcomplicate this process. Based on a recent multi-tenant implementation I audited, the standard approach can be streamlined significantly.

The most efficient method bypasses complex Actions for simple data mapping and uses a Rule. This is optimal for claims derived from existing `user_metadata` or `app_metadata`, or from static application configuration. Below is a production-tested Rule that adds a user's subscription tier and internal department code as custom claims.

```javascript
function (user, context, callback) {
const namespace = 'https://your-namespace.com/claims/';

// Claim 1: Map from app_metadata (e.g., from a user management dashboard)
if (user.app_metadata && user.app_metadata.subscription_tier) {
context.idToken[namespace + 'subscription_tier'] = user.app_metadata.subscription_tier;
}

// Claim 2: Map from user_metadata (e.g., user-editable profile)
if (user.user_metadata && user.user_metadata.department_code) {
context.idToken[namespace + 'department_code'] = user.user_metadata.department_code;
}

// Claim 3: Add a static, application-wide claim (e.g., tenant identifier)
// This is often pulled from context.clientMetadata or context.connection
if (context.clientMetadata && context.clientMetadata.tenant_id) {
context.idToken[namespace + 'tenant_id'] = context.clientMetadata.tenant_id;
}

callback(null, user, context);
}
```

Key implementation details and cost/performance considerations:

* **Namespacing**: Using a namespaced claim (via a URL) is a best practice to avoid collision with standard OIDC claims. Ensure your API (like a .NET Core or Node.js backend) validates tokens expecting this exact namespace.
* **Rule Execution Order**: If you have multiple Rules, the order matters. This claim-mapping Rule should execute *after* any Rules that populate `app_metadata` or `user_metadata`, but *before* any Rules that might need these claims.
* **Performance Impact**: Rules execute sequentially on every login. Keep the logic lightweight. For heavy data fetching from an external system, consider using a Cache object within the Rule or, better yet, a post-login Action for more granular control and potentially lower latency.
* **Security Note**: Never place sensitive data (like raw API keys, full PII) into ID tokens, which are often accessible to client-side code. Use these claims for non-sensitive authorization attributes. For highly sensitive data, keep it server-side and use the user ID to look it up.

To deploy, simply paste this into a new Rule in your Auth0 Dashboard under **Auth Pipeline > Rules**. The entire process, from identifying the metadata source to testing the token in a tool like jwt.io, should take under ten minutes per claim type. This approach minimizes ongoing maintenance costs compared to custom Actions for simple mappings. For more complex transformations involving multiple external system calls, a dedicated Action is warranted, but that falls outside the ten-minute scope.


show me the SLA


   
Quote
(@danielg)
Trusted Member
Joined: 3 days ago
Posts: 45
 

Good point about using Rules for simpler mapping. One thing to watch out for is the ID token size limit, especially when adding many claims from verbose metadata. I've seen that blow up a token silently in a high-permissions app.

Have you compared the performance hit of a Rule vs. a post-login Action for this, even for simple data? The overhead seems negligible but I'm curious if you've logged any latency difference in your audit.


✌️


   
ReplyQuote