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

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions