Configuring Entra ID SAML SSO with Self-Hosted Supabase
This guide walks through configuring Microsoft Entra ID (formerly Azure AD) as a SAML identity provider for your self-hosted Supabase instance to enable SSO authentication with sfp pro CLI/codev
Prerequisites
Before starting the configuration, ensure you have:
Self-Hosted Supabase Requirements:
Running Supabase instance (Docker or Kubernetes)
Access to modify environment variables and configuration files
SSL certificates configured (SAML requires HTTPS)
Ability to restart services
Entra ID Requirements:
Admin access to your Microsoft Entra ID tenant
At least one verified domain in your Entra ID tenant
Ability to create Enterprise Applications
sfp Requirements:
sfp CLI installed
Access to your sfp server instance
sfp server URL (e.g.,
https://your-sfp-server.com
)
Step 1: Enable SAML in Self-Hosted Supabase
Generate Private Key
SAML requires a private key for signing. Generate one:
bash
# Generate private key in DER format
openssl genpkey -algorithm rsa -outform DER -out private_key.der
# Convert to base64
base64 -i private_key.der
Configure Environment Variables
Add to your .env
file (in the same directory as docker-compose.yml
):
bash
# Enable SAML authentication
GOTRUE_SAML_ENABLED=true
GOTRUE_SAML_PRIVATE_KEY=<your-base64-private-key>
# Ensure your external URL is set correctly
API_EXTERNAL_URL=https://your-supabase-instance.com
GOTRUE_EXTERNAL_URL=https://your-supabase-instance.com
Update Docker Compose Configuration
In your docker-compose.yml
, pass the SAML environment variables to the auth container:
yaml
services:
auth:
container_name: supabase-auth
image: supabase/gotrue:v2.99.0
environment:
# ... existing environment variables ...
GOTRUE_SAML_ENABLED: ${GOTRUE_SAML_ENABLED}
GOTRUE_SAML_PRIVATE_KEY: ${GOTRUE_SAML_PRIVATE_KEY}
GOTRUE_EXTERNAL_URL: ${GOTRUE_EXTERNAL_URL}
API_EXTERNAL_URL: ${API_EXTERNAL_URL}
Configure Kong API Gateway
Edit /docker/volumes/api/kong.yml
to expose SAML endpoints:
yaml
## Open SSO routes for SAML
- name: auth-v1-open-sso-acs
url: "http://auth:9999/sso/saml/acs"
routes:
- name: auth-v1-open-sso-acs
strip_path: true
paths:
- /auth/v1/sso/saml/acs
- /sso/saml/acs
plugins:
- name: cors
- name: auth-v1-open-sso-metadata
url: "http://auth:9999/sso/saml/metadata"
routes:
- name: auth-v1-open-sso-metadata
strip_path: true
paths:
- /auth/v1/sso/saml/metadata
plugins:
- name: cors
Configure Reverse Proxy (if applicable)
If using Nginx as a reverse proxy, add:
nginx
# SSO endpoints
location ~ ^/sso/(.*)$ {
proxy_set_header Host $host;
proxy_pass http://kong;
proxy_redirect off;
}
location ~ ^/auth/v1/sso/(.*)$ {
proxy_set_header Host $host;
proxy_pass http://kong;
proxy_redirect off;
}
Restart Services
bash
# Restart Docker services
docker-compose down
docker-compose up -d
# If using Nginx
sudo systemctl restart nginx
Verify SAML is Enabled
bash
# Get your service role key from .env or docker-compose.yml
API_KEY=<your-service-role-key>
# Check settings
curl -X GET https://your-supabase-instance.com/auth/v1/settings \
-H "APIKey: $API_KEY" \
-H "Authorization: Bearer $API_KEY"
You should see "saml_enabled": true
in the response.
Step 2: Note Your Supabase Configuration
Gather your self-hosted instance information:
bash
# Your Supabase instance URL
SUPABASE_URL=https://your-supabase-instance.com
# Your Supabase anon key (from .env or docker-compose.yml)
SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# SAML endpoints
Entity ID: https://your-supabase-instance.com/auth/v1/sso/saml/metadata
ACS URL: https://your-supabase-instance.com/auth/v1/sso/saml/acs
Metadata URL: https://your-supabase-instance.com/auth/v1/sso/saml/metadata
Step 3: Configure Entra ID Enterprise Application
Create the Application
Sign in to Azure Portal
Navigate to Microsoft Entra ID → Enterprise applications
Click New application → Create your own application
Select Integrate any other application you don't find in the gallery (Non-gallery)
Name it (e.g., "sfp SSO Self-Hosted")
Click Create
Configure SAML Settings
In your application, go to Single sign-on
Select SAML as the method
Click Edit in Basic SAML Configuration
Configure these URLs (use your actual instance URL):
Click Save
Configure Attributes and Claims
In Attributes & Claims, click Edit
Ensure these claims are configured:
Download Federation Metadata
In SAML Certificates section
Download Federation Metadata XML
Note the SAML Metadata URL if available
Assign Users
Go to Users and groups
Click Add user/group
Select users who need sfp access
Click Assign
Step 4: Add SAML Provider to Self-Hosted Supabase
Since self-hosted Supabase doesn't have CLI support for SSO management, use the Admin API:
Add the Identity Provider
bash
# Set your service role key
API_KEY=<your-service-role-key>
# Add SAML provider using metadata URL
curl -X POST https://your-supabase-instance.com/auth/v1/admin/sso/providers \
-H "APIKey: $API_KEY" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "saml",
"metadata_url": "https://login.microsoftonline.com/<tenant-id>/federationmetadata/2007-06/federationmetadata.xml",
"domains": ["yourdomain.com"]
}'
Or using metadata XML content:
bash
# Read metadata file content
METADATA_XML=$(cat /path/to/federation-metadata.xml | jq -sR .)
# Add provider with metadata XML
curl -X POST https://your-supabase-instance.com/auth/v1/admin/sso/providers \
-H "APIKey: $API_KEY" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"type\": \"saml\",
\"metadata_xml\": $METADATA_XML,
\"domains\": [\"yourdomain.com\"]
}"
Configure Attribute Mappings
Get the provider ID from the previous response, then update mappings:
bash
PROVIDER_ID=<provider-id-from-response>
curl -X PUT "https://your-supabase-instance.com/auth/v1/admin/sso/providers/$PROVIDER_ID" \
-H "APIKey: $API_KEY" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"attribute_mapping": {
"keys": {
"email": {
"name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
},
"full_name": {
"name": "http://schemas.microsoft.com/identity/claims/displayname"
},
"first_name": {
"name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"
},
"last_name": {
"name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"
}
}
}
}'
Verify Provider Configuration
bash
# List all providers
curl -X GET https://your-supabase-instance.com/auth/v1/admin/sso/providers \
-H "APIKey: $API_KEY" \
-H "Authorization: Bearer $API_KEY"
Step 5: Configure sfp CLI
Configure sfp to use your self-hosted Supabase instance:
bash
# Set your self-hosted Supabase URL
sfp config:set auth-supabase-url https://your-supabase-instance.com
# Set your Supabase anon key
sfp config:set auth-supabase-anon-key eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# Optionally, set default SSO domain
sfp config:set auth-sso-domain yourdomain.com
Example:
bash
sfp config:set auth-supabase-url https://supabase.mycompany.com
sfp config:set auth-supabase-anon-key "your-anon-key-from-env"
sfp config:set auth-sso-domain mycompany.com
Step 6: Test SAML Authentication
Test SSO URL Generation
First, verify the SSO URL can be generated:
bash
API_KEY=<your-service-role-key>
curl -X POST https://your-supabase-instance.com/auth/v1/sso \
-H "APIKey: $API_KEY" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "yourdomain.com",
"skip_http_redirect": true
}'
You should receive a JSON response with a URL to the Entra ID login page.
Test with sfp CLI
bash
sfp server auth login \
--email [email protected] \
--provider saml \
--sso-domain yourdomain.com \
--sfp-server-url https://your-sfp-server.com \
--no-global-auth
Example:
bash
sfp server auth login \
--email [email protected] \
--provider saml \
--sso-domain mycompany.com \
--sfp-server-url https://sfp.mycompany.com \
--no-global-auth
Troubleshooting
Common Issues
"saml_enabled": false in settings
Check environment variables are set correctly
Verify docker-compose.yml passes SAML variables to auth container
Restart all containers:
docker-compose down && docker-compose up -d
Kong routes not working
Verify kong.yml has been updated with SSO routes
Check Kong logs:
docker logs supabase-kong
Ensure paths are correctly configured
SSL/HTTPS issues
SAML requires HTTPS - ensure SSL is properly configured
Check reverse proxy configuration if using one
Verify API_EXTERNAL_URL and GOTRUE_EXTERNAL_URL use https://
"No SSO provider assigned for this domain"
Check provider was added successfully
Verify domain matches exactly
List providers to confirm configuration
Metadata URL not accessible
For on-premise Entra ID behind VPN, use metadata XML instead
Ensure your Supabase instance can reach Microsoft's URLs
Debug Commands
bash
# Check Docker logs
docker logs supabase-auth
docker logs supabase-kong
# Verify SAML endpoints are accessible
curl https://your-supabase-instance.com/auth/v1/sso/saml/metadata
# Check sfp configuration
sfp config:list
# Test with debug logging
sfp server auth login \
--email [email protected] \
--provider saml \
--sso-domain yourdomain.com \
--sfp-server-url https://your-sfp-server.com \
--no-global-auth \
--loglevel debug
Security Considerations
SSL/TLS Configuration
Ensure proper SSL configuration for SAML:
nginx
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
Network Security
Firewall Rules: Allow HTTPS traffic from Entra ID services
Internal Communication: Secure communication between containers
Secret Management: Store sensitive keys securely
Monitoring
Set up log aggregation for auth services
Monitor failed authentication attempts
Track certificate expiration dates
Regular security audits
Managing Multiple Environments
For different environments with self-hosted instances:
bash
# Development
sfp config:set auth-supabase-url https://dev.supabase.mycompany.com
sfp config:set auth-supabase-anon-key "dev-anon-key"
# Production
sfp config:set auth-supabase-url https://supabase.mycompany.com
sfp config:set auth-supabase-anon-key "prod-anon-key"
Or use environment variables:
bash
export SUPABASE_URL=https://dev.supabase.mycompany.com
export SUPABASE_ANON_KEY=dev-anon-key
export AUTH_SSO_DOMAIN=dev.mycompany.com
Next Steps
After successful configuration:
Document the setup for your operations team
Create runbooks for common issues
Set up monitoring and alerting
Plan for certificate rotation
Consider implementing SCIM for user provisioning
Document disaster recovery procedures
Last updated