Auth0 Connector
Connect Auth0 to Brevo through Tajo to sync authenticated user profiles as marketing contacts, trigger automations based on authentication events, and enrich your customer data with identity and access management insights.
Overview
| Property | Value |
|---|---|
| Platform | Auth0 (by Okta) |
| Category | Identity & Access (Custom) |
| Setup Complexity | Medium |
| Official Integration | No |
| Data Synced | Users, Events, Roles, Identities |
| Auth Method | Machine-to-Machine OAuth 2.0 |
Features
- User profile sync - Sync Auth0 user profiles to Brevo contacts
- Authentication events - Trigger automations on login, signup, and password reset
- Role-based segmentation - Segment contacts based on Auth0 roles and permissions
- Social identity data - Enrich contacts with social login profile information
- Login activity tracking - Track last login, login count, and device data
- Multi-tenant support - Sync users across multiple Auth0 tenants
Prerequisites
Before you begin, ensure you have:
- An Auth0 account with API access
- A Machine-to-Machine application registered in Auth0
- Management API permissions granted to the M2M application
- A Brevo account with API access
- A Tajo account with connector permissions
Authentication
Machine-to-Machine OAuth 2.0
# Create an M2M application in Auth0 Dashboardexport AUTH0_DOMAIN=your-tenant.auth0.comexport AUTH0_CLIENT_ID=your_client_idexport AUTH0_CLIENT_SECRET=your_client_secretexport AUTH0_AUDIENCE=https://your-tenant.auth0.com/api/v2/// Get Management API access tokenconst tokenResponse = await fetch( `https://${process.env.AUTH0_DOMAIN}/oauth/token`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ client_id: process.env.AUTH0_CLIENT_ID, client_secret: process.env.AUTH0_CLIENT_SECRET, audience: process.env.AUTH0_AUDIENCE, grant_type: 'client_credentials' }) });
const { access_token } = await tokenResponse.json();// Token is valid for 24 hours by defaultAPI Permissions
Grant only required scopes to your M2M application: read:users, read:user_idp_tokens, read:roles, and read:logs. Avoid granting write permissions unless needed.
Configuration
Basic Setup
connectors: auth0: enabled: true domain: "${AUTH0_DOMAIN}" client_id: "${AUTH0_CLIENT_ID}" client_secret: "${AUTH0_CLIENT_SECRET}" audience: "https://${AUTH0_DOMAIN}/api/v2/"
sync: users: true events: true roles: true schedule: "0 */4 * * *" # Every 4 hours
lists: all_users: 20 verified_users: 21 social_login: 22Field Mapping
field_mapping: email: email given_name: FIRSTNAME family_name: LASTNAME nickname: NICKNAME picture: AVATAR_URL email_verified: EMAIL_VERIFIED logins_count: LOGIN_COUNT last_login: LAST_LOGIN_DATE created_at: SIGNUP_DATE user_metadata.phone: SMS user_metadata.company: COMPANY app_metadata.plan: SUBSCRIPTION_PLAN app_metadata.role: USER_ROLEAPI Endpoints
| Endpoint | Method | Description |
|---|---|---|
https://{domain}/api/v2/users | GET | List or search users |
https://{domain}/api/v2/users/{id} | GET | Get a user |
https://{domain}/api/v2/users/{id} | PATCH | Update user metadata |
https://{domain}/api/v2/users/{id}/roles | GET | Get user roles |
https://{domain}/api/v2/roles | GET | List all roles |
https://{domain}/api/v2/logs | GET | Get log events |
https://{domain}/api/v2/stats/active-users | GET | Get active users count |
https://{domain}/api/v2/stats/daily | GET | Get daily stats |
https://{domain}/oauth/token | POST | Get access token |
Code Examples
Initialize Connector
import { TajoClient } from '@tajo/sdk';
const tajo = new TajoClient({ apiKey: process.env.TAJO_API_KEY, brevoApiKey: process.env.BREVO_API_KEY});
await tajo.connectors.connect('auth0', { domain: process.env.AUTH0_DOMAIN, clientId: process.env.AUTH0_CLIENT_ID, clientSecret: process.env.AUTH0_CLIENT_SECRET});Sync Users to Brevo
// Paginate through Auth0 userslet page = 0;const perPage = 50;let hasMore = true;
while (hasMore) { const response = await fetch( `https://${domain}/api/v2/users?` + new URLSearchParams({ page: page.toString(), per_page: perPage.toString(), include_totals: 'true', search_engine: 'v3', q: 'email_verified:true' }), { headers: { 'Authorization': `Bearer ${accessToken}` } } );
const { users, total } = await response.json();
for (const user of users) { await tajo.contacts.sync({ email: user.email, attributes: { FIRSTNAME: user.given_name, LASTNAME: user.family_name, LOGIN_COUNT: user.logins_count, LAST_LOGIN_DATE: user.last_login, SIGNUP_DATE: user.created_at, EMAIL_VERIFIED: user.email_verified }, listIds: [20] }); }
page++; hasMore = (page * perPage) < total;}Track Authentication Events via Log Streams
// Set up Auth0 Log Stream webhook// Configure in Auth0 Dashboard > Monitoring > Streams
app.post('/webhooks/auth0', async (req, res) => { // Verify authorization header const authHeader = req.headers.authorization; if (authHeader !== `Bearer ${process.env.AUTH0_WEBHOOK_TOKEN}`) { return res.status(401).send('Unauthorized'); }
const logs = req.body;
for (const log of logs) { switch (log.data.type) { case 's': // Successful login await tajo.events.track({ email: log.data.details.email, event: 'user_login', properties: { ip: log.data.ip, user_agent: log.data.user_agent, connection: log.data.connection } }); break; case 'ss': // Successful signup await tajo.contacts.sync({ email: log.data.details.email, attributes: { SIGNUP_DATE: log.data.date }, listIds: [20] }); break; case 'sp': // Successful password change await tajo.events.track({ email: log.data.details.email, event: 'password_changed' }); break; } }
res.status(200).send('OK');});Role-Based Segmentation
// Sync user roles for segmentationconst rolesResponse = await fetch( `https://${domain}/api/v2/users/${userId}/roles`, { headers: { 'Authorization': `Bearer ${accessToken}` } });
const roles = await rolesResponse.json();const roleNames = roles.map(r => r.name).join(', ');
await tajo.contacts.update(userEmail, { attributes: { USER_ROLE: roleNames, IS_ADMIN: roles.some(r => r.name === 'admin') }});Rate Limits
| Endpoint Category | Limit | Notes |
|---|---|---|
| Management API | 50 req/sec (Free) | Per tenant |
| Management API | 100 req/sec (Paid) | Per tenant |
| Authentication API | Varies | Based on plan |
| Log Streams | Real-time | No rate limit on delivery |
| Pagination | 50 items/page max | Use page and per_page params |
Pagination Required
Auth0 Management API returns a maximum of 50 results per page. Always implement pagination using the page and per_page parameters. Include include_totals=true to get the total count.
Troubleshooting
| Issue | Cause | Solution |
|---|---|---|
| 401 Unauthorized | Token expired | Request new M2M token (24h expiry) |
| 403 Forbidden | Missing scopes | Grant required permissions to M2M app |
| Empty user list | Search query error | Use Lucene query syntax for v3 engine |
| Missing metadata | Metadata not set | Check user_metadata and app_metadata |
| Rate limit 429 | Too many requests | Implement backoff with retry headers |
Debug Mode
connectors: auth0: debug: true log_level: verbose log_sync: trueBest Practices
- Use Log Streams - Real-time event streaming instead of polling the Logs API
- Implement pagination - Always paginate user list queries for large tenants
- Cache M2M tokens - Reuse tokens until near expiry (24h default lifetime)
- Use search engine v3 - Use Lucene query syntax for efficient user searches
- Sync verified users only - Filter on
email_verified:trueto avoid unverified contacts - Leverage user metadata - Store custom attributes in Auth0 user_metadata for sync
Security
- Machine-to-Machine OAuth - Client credentials grant for server-to-server auth
- Scoped permissions - Grant minimum required Management API scopes
- Token rotation - M2M tokens expire after 24 hours by default
- Log Stream auth - Use bearer token verification for webhook endpoints
- Tenant isolation - Separate configurations per Auth0 tenant
- Encrypted transport - TLS 1.2+ for all API communications
Related Resources
Open-Source Implementation Map
No official open-source repository was found in the current Tajo connector catalog for Auth0. Keep this page focused on the verified public API contract and vendor documentation until an official schema, SDK, MCP server, or public integration repository is available.
Tajo Revamp Checklist
- Verify authentication and scope requirements against the vendor documentation before each connector release.
- Document primary sync objects, external IDs, pagination strategy, and rate limits explicitly.
- Add smoke tests from public API examples rather than undocumented behavior.
- Capture webhook signature verification and replay protection when the vendor supports webhooks.
- Record gaps where no official public repository or schema exists so future maintainers know what still needs source-backed validation.