diff --git a/.env.azure.example b/.env.azure.example new file mode 100644 index 0000000..4c7b6c6 --- /dev/null +++ b/.env.azure.example @@ -0,0 +1,24 @@ +# Microsoft Entra (Azure AD) OAuth Configuration for Self-Hosted Supabase +# Copy this file to your actual environment configuration and fill in the values + +# Azure Application (Client) ID +# Get this from Azure Portal > App registrations > Your app > Overview +AZURE_CLIENT_ID=your-application-client-id-here + +# Azure Client Secret +# Get this from Azure Portal > App registrations > Your app > Certificates & secrets +AZURE_CLIENT_SECRET=your-client-secret-value-here + +# Azure Tenant ID or 'common' +# Options: +# - 'common': Multi-tenant (any Azure AD organization) +# - 'organizations': Any Azure AD organization (excludes personal accounts) +# - 'consumers': Personal Microsoft accounts only +# - Your specific tenant ID: Single-tenant (e.g., '12345678-1234-1234-1234-123456789012') +# Get tenant ID from Azure Portal > App registrations > Your app > Overview +AZURE_TENANT_ID=common + +# Notes: +# 1. These variables are used in supabase/config.toml via env() substitution +# 2. Never commit this file with real secrets to git +# 3. After setting these, restart your Supabase services: docker-compose restart diff --git a/docs/MICROSOFT_ENTRA_QUICKSTART.md b/docs/MICROSOFT_ENTRA_QUICKSTART.md index 9b343cf..9f79d7a 100644 --- a/docs/MICROSOFT_ENTRA_QUICKSTART.md +++ b/docs/MICROSOFT_ENTRA_QUICKSTART.md @@ -42,16 +42,45 @@ User redirected back to application (authenticated) ### 1. Azure Portal Setup - Register application in Microsoft Entra ID -- Configure redirect URI: `https://.supabase.co/auth/v1/callback` +- Configure redirect URI: + - **Supabase Cloud**: `https://.supabase.co/auth/v1/callback` + - **Self-hosted**: `http://:/auth/v1/callback` - Generate client ID and client secret - Set API permissions (openid, profile, email) ### 2. Supabase Configuration + +#### For Supabase Cloud: Navigate to Authentication > Providers > Azure and configure: - **Azure Client ID**: From Azure app registration - **Azure Secret**: From Azure client secrets - **Azure Tenant**: Use `common` for multi-tenant or specific tenant ID +#### For Self-Hosted Supabase: + +Edit `supabase/config.toml`: +```toml +[auth.external.azure] +enabled = true +client_id = "env(AZURE_CLIENT_ID)" +secret = "env(AZURE_CLIENT_SECRET)" +redirect_uri = "" +url = "https://login.microsoftonline.com/env(AZURE_TENANT_ID)/v2.0" +skip_nonce_check = false +``` + +Set environment variables: +```bash +AZURE_CLIENT_ID="your-application-client-id" +AZURE_CLIENT_SECRET="your-client-secret" +AZURE_TENANT_ID="common" # or specific tenant ID +``` + +Restart Supabase: +```bash +docker-compose down && docker-compose up -d +``` + ### 3. Application Environment Set in `.env` file: ```bash diff --git a/docs/MICROSOFT_ENTRA_SETUP.md b/docs/MICROSOFT_ENTRA_SETUP.md index 38278bf..d532815 100644 --- a/docs/MICROSOFT_ENTRA_SETUP.md +++ b/docs/MICROSOFT_ENTRA_SETUP.md @@ -4,11 +4,13 @@ This guide walks you through configuring Microsoft Entra ID (formerly Azure Active Directory) authentication for the USDA Vision Management Dashboard using Supabase's Azure OAuth provider. +> **📌 Self-Hosted Supabase Users**: If you're using a self-hosted Supabase instance, see the simplified guide: [SELF_HOSTED_AZURE_SETUP.md](SELF_HOSTED_AZURE_SETUP.md). Self-hosted instances configure OAuth providers via `config.toml` and environment variables, not through the UI. + ## Prerequisites - Access to Azure Portal (https://portal.azure.com) - Admin permissions to register applications in Azure AD -- Access to your Supabase project dashboard +- Access to your Supabase project (Cloud dashboard or self-hosted instance) - The USDA Vision application deployed and accessible via URL ## Step 1: Register Application in Microsoft Entra ID @@ -107,14 +109,16 @@ This prevents users from seeing a consent prompt on first login. ## Step 5: Configure Supabase -### 5.1 Navigate to Supabase Auth Settings +### For Supabase Cloud (Hosted) + +#### 5.1 Navigate to Supabase Auth Settings 1. Log in to your [Supabase Dashboard](https://app.supabase.com) 2. Select your project 3. Navigate to **Authentication** > **Providers** 4. Find **Azure** in the provider list -### 5.2 Enable and Configure Azure Provider +#### 5.2 Enable and Configure Azure Provider 1. Toggle **Enable Sign in with Azure** to ON 2. Fill in the configuration: @@ -128,7 +132,7 @@ This prevents users from seeing a consent prompt on first login. 3. Click **Save** -### 5.3 Note the Callback URL +#### 5.3 Note the Callback URL Supabase provides the callback URL in the format: ``` @@ -137,6 +141,85 @@ https://.supabase.co/auth/v1/callback Verify this matches what you configured in Azure (Step 1.2). +### For Self-Hosted Supabase + +If you're running a self-hosted Supabase instance, OAuth providers are configured via the `config.toml` file and environment variables rather than through the UI. + +#### 5.1 Edit config.toml + +1. Open your `supabase/config.toml` file +2. Find or add the `[auth.external.azure]` section: + +```toml +[auth.external.azure] +enabled = true +client_id = "env(AZURE_CLIENT_ID)" +secret = "env(AZURE_CLIENT_SECRET)" +redirect_uri = "" +url = "https://login.microsoftonline.com/env(AZURE_TENANT_ID)/v2.0" +skip_nonce_check = false +``` + +3. Set `enabled = true` to activate Azure authentication + +#### 5.2 Set Environment Variables + +Create or update your environment file (`.env` or set in your deployment): + +```bash +# Azure AD OAuth Configuration +AZURE_CLIENT_ID="your-application-client-id-from-azure" +AZURE_CLIENT_SECRET="your-client-secret-from-azure" +AZURE_TENANT_ID="common" # or your specific tenant ID +``` + +**Important**: +- Use `common` for multi-tenant (any Azure AD organization) +- Use `organizations` for any Azure AD organization (excludes personal Microsoft accounts) +- Use `consumers` for personal Microsoft accounts only +- Use your specific tenant ID (GUID) for single-tenant applications + +#### 5.3 Update Azure Redirect URI + +For self-hosted Supabase, your callback URL will be: +``` +http://:/auth/v1/callback +``` + +For example, if your Supabase API is at `http://192.168.1.100:54321`: +``` +http://192.168.1.100:54321/auth/v1/callback +``` + +**Go back to Azure Portal** (Step 1.2) and add this redirect URI to your app registration. + +#### 5.4 Restart Supabase Services + +After making these changes, restart your Supabase services: + +```bash +# If using docker-compose +docker-compose down +docker-compose up -d + +# Or if using the provided script +./docker-compose.sh restart +``` + +#### 5.5 Verify Configuration + +Check that the auth service picked up your configuration: + +```bash +# View auth service logs +docker-compose logs auth + +# Or for specific service name +docker-compose logs supabase-auth +``` + +Look for log entries indicating Azure provider is enabled. + ## Step 6: Configure Application Environment ### 6.1 Update Environment Variables diff --git a/docs/SELF_HOSTED_AZURE_SETUP.md b/docs/SELF_HOSTED_AZURE_SETUP.md new file mode 100644 index 0000000..188f358 --- /dev/null +++ b/docs/SELF_HOSTED_AZURE_SETUP.md @@ -0,0 +1,158 @@ +# Self-Hosted Supabase - Microsoft Entra Setup + +## Quick Setup Guide + +For self-hosted Supabase instances, OAuth providers like Microsoft Entra (Azure AD) are configured through config files and environment variables, not through the UI. + +### Step 1: Configure Azure Application + +Follow steps 1-4 in [MICROSOFT_ENTRA_SETUP.md](MICROSOFT_ENTRA_SETUP.md) to: +1. Register your app in Azure Portal +2. Get your Client ID and Secret +3. Set up API permissions +4. Configure token claims + +**Important**: Your redirect URI should be: +``` +http://:/auth/v1/callback +``` + +Example: `http://192.168.1.100:54321/auth/v1/callback` + +### Step 2: Configure Supabase + +The Azure provider configuration is already added to `supabase/config.toml`: + +```toml +[auth.external.azure] +enabled = false # Change this to true +client_id = "env(AZURE_CLIENT_ID)" +secret = "env(AZURE_CLIENT_SECRET)" +redirect_uri = "" +url = "https://login.microsoftonline.com/env(AZURE_TENANT_ID)/v2.0" +skip_nonce_check = false +``` + +### Step 3: Set Environment Variables + +1. Copy the example file: + ```bash + cp .env.azure.example .env.azure + ``` + +2. Edit `.env.azure` with your actual values: + ```bash + AZURE_CLIENT_ID=your-application-client-id + AZURE_CLIENT_SECRET=your-client-secret + AZURE_TENANT_ID=common # or your specific tenant ID + ``` + +3. Source the environment file before starting Supabase: + ```bash + source .env.azure + ``` + + Or add it to your docker-compose environment. + +### Step 4: Enable Azure Provider + +Edit `supabase/config.toml` and change: +```toml +[auth.external.azure] +enabled = true # Change from false to true +``` + +### Step 5: Restart Supabase + +```bash +docker-compose down +docker-compose up -d +``` + +Or if using the project script: +```bash +./docker-compose.sh restart +``` + +### Step 6: Enable in Application + +In `management-dashboard-web-app/.env`: +```bash +VITE_ENABLE_MICROSOFT_LOGIN=true +``` + +### Verification + +1. Check auth service logs: + ```bash + docker-compose logs auth | grep -i azure + ``` + +2. You should see the Microsoft login button on your application's login page + +3. Click it and verify you're redirected to Microsoft login + +### Troubleshooting + +#### Azure Provider Not Working + +**Check logs**: +```bash +docker-compose logs auth +``` + +**Verify environment variables are loaded**: +```bash +docker-compose exec auth env | grep AZURE +``` + +#### Redirect URI Mismatch + +Ensure the redirect URI in Azure exactly matches: +``` +http://:/auth/v1/callback +``` + +Common mistake: Using `localhost` instead of the actual IP address. + +#### Environment Variables Not Set + +If you see errors about missing AZURE variables, make sure to: +1. Export them in your shell before running docker-compose +2. Or add them to your docker-compose.yml environment section +3. Or use a .env file that docker-compose automatically loads + +### Docker Compose Environment Variables + +You can also add the variables directly to your `docker-compose.yml`: + +```yaml +services: + auth: + environment: + AZURE_CLIENT_ID: ${AZURE_CLIENT_ID} + AZURE_CLIENT_SECRET: ${AZURE_CLIENT_SECRET} + AZURE_TENANT_ID: ${AZURE_TENANT_ID:-common} +``` + +Then create a `.env` file in the same directory: +```bash +AZURE_CLIENT_ID=your-client-id +AZURE_CLIENT_SECRET=your-secret +AZURE_TENANT_ID=common +``` + +### Security Notes + +- Never commit `.env.azure` or `.env` files with real secrets to git +- Add them to `.gitignore` +- Use environment variable substitution in config.toml +- Rotate client secrets regularly (before expiration) +- Monitor sign-in logs in Azure Portal + +### Additional Resources + +- Full setup guide: [MICROSOFT_ENTRA_SETUP.md](MICROSOFT_ENTRA_SETUP.md) +- Quick reference: [MICROSOFT_ENTRA_QUICKSTART.md](MICROSOFT_ENTRA_QUICKSTART.md) +- Supabase self-hosting docs: https://supabase.com/docs/guides/self-hosting +- Azure OAuth docs: https://docs.microsoft.com/azure/active-directory/develop/v2-oauth2-auth-code-flow diff --git a/supabase/config.toml b/supabase/config.toml index b4e8807..8e5f4ef 100755 --- a/supabase/config.toml +++ b/supabase/config.toml @@ -278,6 +278,18 @@ url = "" # If enabled, the nonce check will be skipped. Required for local sign in with Google auth. skip_nonce_check = false +[auth.external.azure] +enabled = "env(VITE_ENABLE_MICROSOFT_LOGIN)" +client_id = "env(AZURE_CLIENT_ID)" +# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead: +secret = "env(AZURE_CLIENT_SECRET)" +# Overrides the default auth redirectUrl. +redirect_uri = "" +# Azure tenant ID or 'common' for multi-tenant. Use 'common', 'organizations', 'consumers', or your specific tenant ID. +url = "https://login.microsoftonline.com/env(AZURE_TENANT_ID)/v2.0" +# If enabled, the nonce check will be skipped. +skip_nonce_check = false + # Allow Solana wallet holders to sign in to your project via the Sign in with Solana (SIWS, EIP-4361) standard. # You can configure "web3" rate limit in the [auth.rate_limit] section and set up [auth.captcha] if self-hosting. [auth.web3.solana]