Skip to content

Supabase client with Secret Key is not compatible with local development #4524

@sapphire008

Description

@sapphire008

When developing locally, I created a supabase admin client with the Secret Key from supabase status

const SUPABASE_URL = "http://127.0.0.1:54321";
const SUPABASE_SECRET_KEY = "<local secret key>" // TODO

const supabase = createClient<Database>(SUPABASE_URL, SUPABASE_SECRET_KEY, {
  auth: {
    autoRefreshToken: false,
    persistSession: false
  }
});

and tried to add some mock users with supabase.auth.admin.createUser, I got the following error message:

❌ Failed to connect to Supabase: invalid JWT: unable to parse or verify signature, token is malformed: token contains an invalid number of segments

However, if I change the to the old Service Role Key (which no longer prints in version 2.51.0), this works just fine.

Minimally reproducible example:
test-supabase-local.zip

index.ts

#!/usr/bin/env tsx

import { createClient, User } from '@supabase/supabase-js';
import { Database } from './database.js';

// Configuration for local Supabase development
const SUPABASE_URL = "http://127.0.0.1:54321";
const SUPABASE_SECRET_KEY = "sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz"

// Create Supabase client with service role key for admin operations
const supabase = createClient<Database>(SUPABASE_URL, SUPABASE_SECRET_KEY, {
  auth: {
    autoRefreshToken: false,
    persistSession: false
  }
});

// Test users to insert
const testUsers = [
  {
    email: 'test1@example.com',
    password: 'TestPassword123!',
    user_metadata: {
      full_name: 'Test User One',
      username: 'testuser1'
    }
  },
  {
    email: 'test2@example.com',
    password: 'TestPassword123!',
    user_metadata: {
      full_name: 'Test User Two',
      username: 'testuser2'
    }
  },
  {
    email: 'test3@example.com',
    password: 'TestPassword123!',
    user_metadata: {
      full_name: 'Test User Three',
      username: 'testuser3'
    }
  }
];

async function insertTestUsers() {
  console.log('🚀 Starting test user insertion...');
  console.log(`📍 Supabase URL: ${SUPABASE_URL}`);
  
  for (const [index, userData] of testUsers.entries()) {
    try {
      console.log(`\n👤 Creating user ${index + 1}: ${userData.email}`);
      
      // Use admin.createUser for creating users with passwords
      const { data, error } = await supabase.auth.admin.createUser({
        email: userData.email,
        password: userData.password,
        user_metadata: userData.user_metadata,
        email_confirm: true // Auto-confirm email for testing
      });

      if (error) {
        console.error(`❌ Failed to create user ${userData.email}:`, error.message);
        continue;
      }

      if (data.user) {
        console.log(`✅ Successfully created user: ${userData.email}`);
        console.log(`   User ID: ${data.user.id}`);
        console.log(`   Email confirmed: ${data.user.email_confirmed_at ? 'Yes' : 'No'}`);
      }

    } catch (error) {
      console.error(`💥 Unexpected error creating user ${userData.email}:`, error);
    }
  }

  console.log('\n🎉 Test user insertion completed!');
}

async function listExistingUsers() {
  try {
    console.log('\n📋 Listing existing users...');
    
    const { data, error } = await supabase.auth.admin.listUsers();
    
    if (error) {
      console.error('❌ Failed to list users:', error.message);
      return;
    }

    console.log(`Found ${data.users.length} users:`);
    data.users.forEach((user: User, index: number) => {
      console.log(`  ${index + 1}. ${user.email} (ID: ${user.id})`);
    });

  } catch (error) {
    console.error('💥 Unexpected error listing users:', error);
  }
}

async function main() {
  console.log('🔧 Supabase Test User Insertion Script');
  console.log('=====================================');

  // Check if we can connect to Supabase
  try {
    const { data, error } = await supabase.auth.admin.listUsers({ page: 1, perPage: 1 });
    if (error) {
      console.error('❌ Failed to connect to Supabase:', error.message);
      console.log('\n💡 Make sure:');
      console.log('   1. Supabase is running locally (supabase start)');
      console.log('   2. VITE_SUPABASE_URL is set correctly');
      console.log('   3. SUPABASE_SERVICE_ROLE_KEY is set correctly');
      process.exit(1);
    }
    console.log('✅ Successfully connected to Supabase');
  } catch (error) {
    console.error('💥 Connection error:', error);
    process.exit(1);
  }

  // List existing users first
  await listExistingUsers();

  // Insert test users
  await insertTestUsers();

  // List users again to show the results
  await listExistingUsers();
}

// Run the script
if (import.meta.url === `file://${process.argv[1]}`) {
  main().catch(console.error);
}
  • I also tried using Python client and got the same error.
  • I am on Supabase CLI 2.51.0 which is the latest version at the time of writing.
  • I have tried to delete everything and reinstall but it didn't make a difference.
  • In the previous thread (currently locked) #29260, local development compatibility has been fixed in a previous release, but I am not sure it specifically address the case I mentioned above.
  • Is there any settings that I need to configure to allow the server to accept the new secret key?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions