GuidesAuth Providers
Supabase integration
Configure Supabase as an authentication provider for CloudSignal MQTT.
Configure Supabase as an authentication provider so your Supabase users can connect to CloudSignal MQTT with credentials derived from their Supabase JWT. Use this when your app already authenticates users via Supabase.
Prerequisites
- A Supabase project with authentication enabled
- A CloudSignal account with API keys
- Your Supabase JWT secret
Configuration
Get your Supabase JWT secret
- Go to your Supabase Dashboard
- Select your project
- Navigate to Settings → API
- Copy the JWT Secret (under "JWT Settings")
Keep your JWT secret secure. Never expose it in client-side code.
Add Supabase provider in CloudSignal
- Go to CloudSignal Dashboard
- Navigate to Connections → Auth Providers
- Click Add Provider
- Select Supabase
- Enter your configuration:
| Field | Value |
|---|---|
| Name | A friendly name (for example, "Production Supabase") |
| Project URL | Your Supabase project URL (for example, https://abc123.supabase.co) |
| JWT Secret | The secret from Step 1 |
- Click Save
Test the integration
Use the CloudSignal API to test token exchange:
curl -X POST https://auth.cloudsignal.app/v2/tokens/exchange \
-H "Authorization: Bearer YOUR_CLOUDSIGNAL_SK" \
-H "Content-Type: application/json" \
-d '{
"provider": "supabase",
"token": "YOUR_SUPABASE_ACCESS_TOKEN"
}'Implementation
React/Next.js example
import { createClient } from '@supabase/supabase-js';
import CloudSignal from '@cloudsignal/mqtt-client';
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
);
// Connect to MQTT using the current Supabase session token
async function connectMqtt() {
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
throw new Error('User not authenticated');
}
const client = new CloudSignal();
client.setOnlineCallback(() => {
console.log('Connected to MQTT');
});
// The SDK exchanges the Supabase JWT for MQTT credentials internally
await client.connectWithToken({
host: 'wss://connect.cloudsignal.app:18885/',
organizationId: 'org_k7xm4pqr2n5t',
externalToken: session.access_token,
provider: 'supabase'
});
return client;
}API route (Next.js)
// app/api/mqtt-credentials/route.ts
import { NextResponse } from 'next/server';
export async function POST(request: Request) {
const { supabaseToken } = 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: 'supabase',
token: supabaseToken
})
});
const credentials = await response.json();
return NextResponse.json(credentials);
}React Native example
import { supabase } from './supabaseClient';
import CloudSignal from '@cloudsignal/mqtt-client';
async function connectToMqtt() {
// Get current Supabase session
const { data: { session } } = await supabase.auth.getSession();
if (!session) {
throw new Error('Not logged in');
}
// The SDK exchanges the Supabase JWT for MQTT credentials internally
const client = new CloudSignal({ preset: 'mobile' });
await client.connectWithToken({
host: 'wss://connect.cloudsignal.app:18885/',
organizationId: 'org_k7xm4pqr2n5t',
externalToken: session.access_token,
provider: 'supabase'
});
return client;
}Handling token refresh
Supabase tokens expire. Handle reconnection with fresh credentials:
import { supabase } from './supabaseClient';
import CloudSignal from '@cloudsignal/mqtt-client';
let mqttClient: CloudSignal | null = null;
// Listen for auth state changes
supabase.auth.onAuthStateChange(async (event, session) => {
if (event === 'TOKEN_REFRESHED' && session && mqttClient) {
// Reconnect with the refreshed Supabase token
await mqttClient.disconnect();
mqttClient = new CloudSignal();
await mqttClient.connectWithToken({
host: 'wss://connect.cloudsignal.app:18885/',
organizationId: 'org_k7xm4pqr2n5t',
externalToken: session.access_token,
provider: 'supabase'
});
}
});ACL rules for Supabase users
Create ACL rules that match Supabase user IDs:
# User can only access their own topics
User Pattern: %
Topic: users/%u/#
Permission: pubsubThe MQTT username derived from Supabase will be the user's email (sanitized) or UUID, depending on your configuration.
Troubleshooting
"Invalid token" error
| Check | What to verify |
|---|---|
| Token freshness | Supabase access tokens expire after 1 hour |
| JWT secret | Ensure the secret matches your Supabase project |
| Project URL | Must match exactly (including https://) |
"Provider not found" error
| Check | What to verify |
|---|---|
| Provider enabled | Confirm the provider is enabled in the CloudSignal dashboard |
| Provider name | Use "provider": "supabase" (lowercase) |
Connection drops after 1 hour
Supabase tokens expire. Implement token refresh handling as shown above.
Next steps
- Firebase integration - Same pattern, different provider
- Token Exchange API reference - Full request and response details
- ACL rules guide - Scope topics to the authenticated user