CloudSignal Docs
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

  1. Go to Auth0 Dashboard
  2. Navigate to ApplicationsAPIs
  3. Note your API Audience (identifier)
  4. Go to SettingsDomain and copy your domain

Your domain will look like: your-tenant.auth0.com

Add Auth0 provider in CloudSignal

  1. Go to CloudSignal Dashboard
  2. Navigate to ConnectionsAuth Providers
  3. Click Add Provider
  4. Select Auth0
  5. Enter your configuration:
FieldValue
NameA friendly name (for example, "Production Auth0")
DomainYour Auth0 domain (for example, your-tenant.auth0.com)
AudienceYour API identifier (for example, https://api.yourapp.com)
  1. Click Save

Test the integration

Exchange an Auth0 access token:

curl -X POST https://auth.cloudsignal.app/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 CloudSignal from '@cloudsignal/mqtt-client';
import { useState, useEffect } from 'react';

function MqttComponent() {
  const { getAccessTokenSilently, isAuthenticated } = useAuth0();
  const [client, setClient] = useState<CloudSignal | null>(null);
  const [connected, setConnected] = useState(false);

  useEffect(() => {
    if (!isAuthenticated) return;

    const csClient = new CloudSignal({ preset: 'auto' });

    async function connect() {
      // Get Auth0 access token
      const auth0Token = await getAccessTokenSilently({
        authorizationParams: {
          audience: 'https://api.yourapp.com'
        }
      });

      // Connect using the Auth0 token directly
      await csClient.connectWithToken({
        host: 'wss://connect.cloudsignal.app:18885/',
        organizationId: 'org_k7xm4pqr2n5t',
        provider: 'auth0',
        externalToken: auth0Token
      });

      csClient.setOnlineCallback(() => {
        console.log('Connected to MQTT');
        setConnected(true);
      });

      csClient.setOfflineCallback(() => setConnected(false));

      setClient(csClient);
    }

    connect();

    return () => {
      csClient.disconnect();
    };
  }, [isAuthenticated]);

  return <div>MQTT Status: {connected ? '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://auth.cloudsignal.app/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://auth.cloudsignal.app/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 CloudSignal from '@cloudsignal/mqtt-client';

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');
  }

  // Connect using the Auth0 access token directly
  const client = new CloudSignal({ preset: 'mobile' });

  await client.connectWithToken({
    host: 'wss://connect.cloudsignal.app:18885/',
    organizationId: 'org_k7xm4pqr2n5t',
    provider: 'auth0',
    externalToken: credentials.accessToken
  });

  return client;
}

Handling token refresh

Auth0 access tokens have configurable expiration. Enable autoRefresh and use the token lifecycle callbacks to react when the client refreshes or fails to refresh:

import { useAuth0 } from '@auth0/auth0-react';
import CloudSignal from '@cloudsignal/mqtt-client';

function useMqttWithRefresh() {
  const { getAccessTokenSilently } = useAuth0();
  const [client, setClient] = useState<CloudSignal | null>(null);

  useEffect(() => {
    const csClient = new CloudSignal({ preset: 'auto', autoRefresh: true });

    async function connect() {
      const auth0Token = await getAccessTokenSilently({
        authorizationParams: { audience: 'https://api.yourapp.com' }
      });

      await csClient.connectWithToken({
        host: 'wss://connect.cloudsignal.app:18885/',
        organizationId: 'org_k7xm4pqr2n5t',
        provider: 'auth0',
        externalToken: auth0Token
      });

      // The client refreshes the token automatically before it expires
      csClient.setTokenRefreshedCallback(() => {
        console.log('MQTT token refreshed');
      });

      csClient.setTokenErrorCallback((error) => {
        console.error('Failed to refresh credentials:', error);
      });

      setClient(csClient);
    }

    connect();

    return () => {
      csClient.disconnect();
    };
  }, []);

  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: pubsub

The 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

CheckWhat to verify
Token freshnessAccess tokens expire based on your Auth0 settings
AudienceMust match exactly what's configured
Token typeThe token exchange expects access tokens, not ID tokens

"Provider not found" error

CheckWhat to verify
Provider enabledConfirm the provider is enabled in CloudSignal
Provider nameUse "provider": "auth0" (lowercase)

"Token signature verification failed"

CheckWhat to verify
DomainMust match your Auth0 tenant domain exactly
AudienceAPI identifier must match

Next steps

On this page