GuidesAuth Providers
Auth0 integration
Configure Auth0 as an authentication provider for CloudSignal MQTT.
Configure Auth0 as an authentication provider so your Auth0 users can connect to CloudSignal MQTT with credentials derived from their Auth0 access token. Use this when your app already authenticates users via Auth0.
Prerequisites
- An Auth0 account with an application configured
- A CloudSignal account with API keys
- Auth0 domain and audience values
Configuration
Get Auth0 configuration values
- Go to Auth0 Dashboard
- Navigate to Applications → APIs
- Note your API Audience (identifier)
- Go to Settings → Domain and copy your domain
Your domain will look like: your-tenant.auth0.com
Add Auth0 provider in CloudSignal
- Go to CloudSignal Dashboard
- Navigate to Connections → Auth Providers
- Click Add Provider
- Select Auth0
- Enter your configuration:
| Field | Value |
|---|---|
| Name | A friendly name (for example, "Production Auth0") |
| Domain | Your Auth0 domain (for example, your-tenant.auth0.com) |
| Audience | Your API identifier (for example, https://api.yourapp.com) |
- Click Save
Test the integration
Exchange an Auth0 access token:
curl -X POST https://api.cloudsignal.io/v2/tokens/exchange \
-H "Authorization: Bearer YOUR_CLOUDSIGNAL_SK" \
-H "Content-Type: application/json" \
-d '{
"provider": "auth0",
"token": "YOUR_AUTH0_ACCESS_TOKEN"
}'Implementation
React example with Auth0 SDK
import { useAuth0 } from '@auth0/auth0-react';
import mqtt from 'mqtt';
import { useState, useEffect } from 'react';
function MqttComponent() {
const { getAccessTokenSilently, isAuthenticated } = useAuth0();
const [mqttClient, setMqttClient] = useState<mqtt.MqttClient | null>(null);
async function getMqttCredentials() {
// Get Auth0 access token
const accessToken = await getAccessTokenSilently({
authorizationParams: {
audience: 'https://api.yourapp.com'
}
});
// Exchange via your backend
const response = await fetch('/api/mqtt-credentials', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ auth0Token: accessToken })
});
return response.json();
}
useEffect(() => {
if (!isAuthenticated) return;
async function connect() {
const credentials = await getMqttCredentials();
const client = mqtt.connect('wss://connect.cloudsignal.app:18885/', {
username: credentials.mqtt_username,
password: credentials.mqtt_password
});
client.on('connect', () => {
console.log('Connected to MQTT');
});
setMqttClient(client);
}
connect();
return () => {
mqttClient?.end();
};
}, [isAuthenticated]);
return <div>MQTT Status: {mqttClient ? 'Connected' : 'Disconnected'}</div>;
}API route (Next.js)
// app/api/mqtt-credentials/route.ts
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const { auth0Token } = await request.json();
const response = await fetch('https://api.cloudsignal.io/v2/tokens/exchange', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CLOUDSIGNAL_SK}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
provider: 'auth0',
token: auth0Token
})
});
const credentials = await response.json();
return NextResponse.json(credentials);
}Express.js backend
import express from 'express';
import { auth } from 'express-oauth2-jwt-bearer';
const app = express();
// Auth0 middleware
const checkJwt = auth({
audience: 'https://api.yourapp.com',
issuerBaseURL: 'https://your-tenant.auth0.com/',
});
app.post('/mqtt-credentials', checkJwt, async (req, res) => {
// Token is already validated by middleware
const auth0Token = req.headers.authorization?.split(' ')[1];
const response = await fetch('https://api.cloudsignal.io/v2/tokens/exchange', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CLOUDSIGNAL_SK}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
provider: 'auth0',
token: auth0Token
})
});
const credentials = await response.json();
res.json(credentials);
});React Native with Auth0
import Auth0 from 'react-native-auth0';
import mqtt from 'mqtt';
const auth0 = new Auth0({
domain: 'your-tenant.auth0.com',
clientId: 'YOUR_CLIENT_ID'
});
async function connectToMqtt() {
// Get credentials (assuming user is logged in)
const credentials = await auth0.credentialsManager.getCredentials();
if (!credentials.accessToken) {
throw new Error('Not authenticated');
}
// Exchange token via your backend
const response = await fetch('https://your-api.com/mqtt-credentials', {
method: 'POST',
headers: {
'Authorization': `Bearer ${credentials.accessToken}`,
'Content-Type': 'application/json'
}
});
const { mqtt_username, mqtt_password } = await response.json();
// Connect to MQTT
const client = mqtt.connect('wss://connect.cloudsignal.app:18885/', {
username: mqtt_username,
password: mqtt_password
});
return client;
}Handling token refresh
Auth0 access tokens have configurable expiration. Handle refresh:
import { useAuth0 } from '@auth0/auth0-react';
function useMqttWithRefresh() {
const { getAccessTokenSilently } = useAuth0();
const [client, setClient] = useState<mqtt.MqttClient | null>(null);
// Refresh credentials before expiry
useEffect(() => {
if (!client) return;
const refreshInterval = setInterval(async () => {
try {
const credentials = await getMqttCredentials();
// Update client credentials
client.options.username = credentials.mqtt_username;
client.options.password = credentials.mqtt_password;
// Reconnect with new credentials
client.reconnect();
} catch (error) {
console.error('Failed to refresh credentials:', error);
}
}, 50 * 60 * 1000); // Refresh every 50 minutes
return () => clearInterval(refreshInterval);
}, [client]);
return client;
}ACL rules for Auth0 users
Create ACL rules that match Auth0 user IDs or emails:
# User can only access their own topics
User Pattern: %
Topic: users/%u/#
Permission: pubsubThe MQTT username will be derived from Auth0's sub claim (user ID) or email.
Using Auth0 actions for custom claims
You can add custom claims in Auth0 to control MQTT access:
// Auth0 Action: Add MQTT-related claims
exports.onExecutePostLogin = async (event, api) => {
// Add custom namespace claims
api.accessToken.setCustomClaim('https://cloudsignal.io/mqtt_topics', [
'agents/#',
'alerts/' + event.user.user_id
]);
};Troubleshooting
"Invalid token" error
| Check | What to verify |
|---|---|
| Token freshness | Access tokens expire based on your Auth0 settings |
| Audience | Must match exactly what's configured |
| Token type | The token exchange expects access tokens, not ID tokens |
"Provider not found" error
| Check | What to verify |
|---|---|
| Provider enabled | Confirm the provider is enabled in CloudSignal |
| Provider name | Use "provider": "auth0" (lowercase) |
"Token signature verification failed"
| Check | What to verify |
|---|---|
| Domain | Must match your Auth0 tenant domain exactly |
| Audience | API identifier must match |
Next steps
- Token Exchange API reference - Full request and response details
- Supabase integration - Same pattern with JWT secret
- ACL rules guide - Scope topics to the authenticated user