erDiagram
users ||--o{ Account : "links to OAuth"
users ||--o{ Session : "has sessions"
users }o--|| membership_invitations : "email match"
users {
text id PK "Primary blocker"
text email UK "Email match key"
text password "Non-null blocks SSO"
boolean admin
timestamp created_at
timestamp updated_at
}
Account {
text user_id FK "Auto-cleaned"
text provider "Azure AD"
text provider_account_id
}
Session {
text user_id FK "Auto-cleaned"
text session_token
timestamp expires
}
membership_invitations {
text email "Potential conflict"
text organization_id FK
text role
timestamp expires_at
}
User Management and SSO Migration
User Management and SSO Migration
Problem: You’re encountering authentication errors when migrating existing users from password-based authentication to Azure AD SSO, or need to manage user accounts in the database.
Solution: This guide provides specific database operations to resolve SSO migration issues and manage user accounts effectively.
Database Operations: The procedures in this guide involve direct database manipulation. Always backup your database before making changes.
SSO Migration Issues
The “Same Provider” Error
Problem Symptom: When migrating existing password-based users to SSO, users encounter the error:
“Please sign in with the same provider (e.g. Google, GitHub, Azure AD, etc.) that you used to create this account.”
Root Cause: Certain database records link the user’s email to an existing password-based account, preventing fresh SSO account creation.
Database Schema: Tables That Block SSO Onboarding
Tables That Block Fresh SSO Onboarding
users Table - PRIMARY BLOCKER ⚠️
Why it blocks: If a user record exists with a non-null password field, LangFuse attempts to link the Azure AD login to the existing password-based account, causing the “same provider” error.
Key Schema Elements
| Column | Type | Nullable | Impact on SSO |
|---|---|---|---|
id |
text | NO | Primary key that must be removed |
email |
text | YES | Unique constraint - email match triggers conflict |
password |
text | YES | Non-null value blocks fresh SSO setup |
admin |
boolean | NO | User privileges (lost on deletion) |
Solution: Complete user deletion
User Deletion Procedure
Step 1: Get Database Connection Details
# Get database password
kubectl get secret langfuse -n langfuse -o jsonpath='{.data.postgres-password}' | base64 -dStep 2: Delete User Record
# Replace 'user@example.com' with the actual email address
kubectl run delete-user --rm --tty -i --restart='Never' --namespace langfuse --image postgres:15 --command -- sh -c "
apt-get update -qq && apt-get install -y postgresql-client -qq
echo 'Deleting user record...'
PGPASSWORD='$(kubectl get secret langfuse -n langfuse -o jsonpath='{.data.postgres-password}' | base64 -d)' psql -h 10.224.0.65 -U postgres -d langfuse -c \"DELETE FROM users WHERE email = 'user@example.com';\"
echo 'User deletion completed!'
"Database Host IP: The IP address 10.224.0.65 in the example above should be replaced with your actual PostgreSQL service IP. You can find this with:
kubectl get service langfuse-postgresql -n langfuse -o jsonpath='{.spec.clusterIP}'membership_invitations Table - POTENTIAL CONFLICT 📧
Why it might block: Existing pending invitations for the same email could interfere with the new invitation flow.
Key Schema Elements
| Column | Type | Impact |
|---|---|---|
email |
text | Email match with user being migrated |
expires_at |
timestamp | Old invitations may still be active |
Solution (Optional): Clean up old invitations
# Replace 'user@example.com' with the actual email address
kubectl run cleanup-invitations --rm --tty -i --restart='Never' --namespace langfuse --image postgres:15 --command -- sh -c "
apt-get update -qq && apt-get install -y postgresql-client -qq
echo 'Cleaning up old invitations...'
PGPASSWORD='$(kubectl get secret langfuse -n langfuse -o jsonpath='{.data.postgres-password}' | base64 -d)' psql -h 10.224.0.65 -U postgres -d langfuse -c \"DELETE FROM membership_invitations WHERE email = 'user@example.com';\"
echo 'Invitation cleanup completed!'
"Complete SSO Migration Procedure
Step-by-Step Migration Process
Step 1: Identify Users to Migrate
# List all password-based users
kubectl run list-users --rm --tty -i --restart='Never' --namespace langfuse --image postgres:15 --command -- sh -c "
apt-get update -qq && apt-get install -y postgresql-client -qq
PGPASSWORD='$(kubectl get secret langfuse -n langfuse -o jsonpath='{.data.postgres-password}' | base64 -d)' psql -h 10.224.0.65 -U postgres -d langfuse -c \"SELECT email, admin, created_at FROM users WHERE password IS NOT NULL;\"
"Step 2: Clean Up User Records
For each user to be migrated:
- Delete the user record (see procedure above)
- Optionally clean up membership invitations
- Verify deletion was successful
Step 3: Fresh SSO Setup
After user deletion:
- Admin creates new invitation for the user via LangFuse UI
- User clicks invitation link and signs in with Azure AD
- Fresh SSO account is created automatically
Step 4: Verification
# Verify user now has SSO account
kubectl run verify-sso --rm --tty -i --restart='Never' --namespace langfuse --image postgres:15 --command -- sh -c "
apt-get update -qq && apt-get install -y postgresql-client -qq
PGPASSWORD='$(kubectl get secret langfuse -n langfuse -o jsonpath='{.data.postgres-password}' | base64 -d)' psql -h 10.224.0.65 -U postgres -d langfuse -c \"
SELECT u.email, u.password IS NULL as sso_ready, a.provider
FROM users u
LEFT JOIN Account a ON u.id = a.user_id
WHERE u.email = 'user@example.com';\"
"Common User Management Tasks
Check User Account Status
# Check if user exists and authentication method
kubectl run check-user --rm --tty -i --restart='Never' --namespace langfuse --image postgres:15 --command -- sh -c "
apt-get update -qq && apt-get install -y postgresql-client -qq
PGPASSWORD='$(kubectl get secret langfuse -n langfuse -o jsonpath='{.data.postgres-password}' | base64 -d)' psql -h 10.224.0.65 -U postgres -d langfuse -c \"
SELECT
u.email,
CASE WHEN u.password IS NOT NULL THEN 'Password' ELSE 'SSO' END as auth_method,
u.admin,
a.provider as sso_provider,
u.created_at
FROM users u
LEFT JOIN Account a ON u.id = a.user_id
WHERE u.email = 'user@example.com';\"
"List All Active Sessions
# View active user sessions
kubectl run list-sessions --rm --tty -i --restart='Never' --namespace langfuse --image postgres:15 --command -- sh -c "
apt-get update -qq && apt-get install -y postgresql-client -qq
PGPASSWORD='$(kubectl get secret langfuse -n langfuse -o jsonpath='{.data.postgres-password}' | base64 -d)' psql -h 10.224.0.65 -U postgres -d langfuse -c \"
SELECT u.email, s.expires, s.session_token
FROM Session s
JOIN users u ON s.user_id = u.id
WHERE s.expires > NOW()
ORDER BY s.expires DESC;\"
"Clean Up Expired Sessions
# Remove expired sessions
kubectl run cleanup-sessions --rm --tty -i --restart='Never' --namespace langfuse --image postgres:15 --command -- sh -c "
apt-get update -qq && apt-get install -y postgresql-client -qq
PGPASSWORD='$(kubectl get secret langfuse -n langfuse -o jsonpath='{.data.postgres-password}' | base64 -d)' psql -h 10.224.0.65 -U postgres -d langfuse -c \"DELETE FROM Session WHERE expires < NOW();\"
"Troubleshooting User Issues
User Cannot Access After SSO Migration
Problem: User completed SSO migration but cannot access their previous data
Root Cause: User was recreated with a new ID, breaking data relationships
Solution: This is expected behavior. SSO migration creates a fresh account. Previous data is not automatically transferred.
Multiple Accounts for Same User
Problem: User has both password and SSO accounts
Root Cause: User deletion was not completed before SSO setup
Solution: 1. Identify which account has the correct data 2. Delete the unwanted account using the procedures above 3. Ensure only one account exists per email
Admin Privileges Lost After Migration
Problem: User lost admin privileges after SSO migration
Root Cause: Admin status is stored in the users table and is lost during deletion
Solution: Restore admin privileges via database
# Grant admin privileges to SSO user
kubectl run grant-admin --rm --tty -i --restart='Never' --namespace langfuse --image postgres:15 --command -- sh -c "
apt-get update -qq && apt-get install -y postgresql-client -qq
PGPASSWORD='$(kubectl get secret langfuse -n langfuse -o jsonpath='{.data.postgres-password}' | base64 -d)' psql -h 10.224.0.65 -U postgres -d langfuse -c \"UPDATE users SET admin = true WHERE email = 'user@example.com';\"
"Key Takeaway: The users table with a non-null password field is the primary blocker for fresh SSO onboarding. Complete user deletion resolves the issue and allows fresh Azure AD account creation, but requires careful handling of admin privileges and user communication.