/ docs / docs / documentation / enterprise / single-sign-on.md
single-sign-on.md
  1  ---
  2  title: Enabling SSO
  3  sidebar_position: 10
  4  ---
  5  
  6  ## Overview
  7  
  8  Single Sign-On (SSO) enables users to authenticate with Agent Mesh Enterprise using their existing organizational credentials through OAuth2 providers such as Azure, Google, Auth0, Okta, or Keycloak. This integration eliminates the need for separate login credentials and leverages your organization's existing identity management infrastructure.
  9  
 10  This guide walks you through configuring and enabling SSO for Agent Mesh Enterprise running in Docker. You will create configuration files, set up your OAuth2 provider, and launch the container with the appropriate environment variables.
 11  
 12  ## Prerequisites
 13  
 14  Before you begin, ensure you have:
 15  
 16  - A running instance of your chosen OAuth2 provider (Azure, Google, Auth0, Okta, Keycloak, or another OIDC-compliant provider)
 17  - Client credentials (client ID and client secret) from your OAuth2 provider
 18  - A Named Docker Volume for storing configuration files
 19  - Access to the Agent Mesh Enterprise Docker image
 20  
 21  ## Understanding the SSO Architecture
 22  
 23  Agent Mesh Enterprise uses a two-component architecture for SSO:
 24  
 25  1. The main UI server (default port 8000) handles user interactions and serves the web interface
 26  2. The OAuth2 authentication service (default port 8080) manages the authentication flow with your identity provider
 27  
 28  When a user attempts to access the UI, they are redirected to your OAuth2 provider for authentication. After successful authentication, the provider redirects back to the application with an authorization code, which is then exchanged for access tokens. This separation of concerns keeps authentication logic isolated from the main application.
 29  
 30  ## Step 1: Create Configuration Files
 31  
 32  You need to create two YAML configuration files in your Named Docker Volume. These files define how the OAuth2 service operates and which identity provider it connects to.
 33  
 34  ### Create oauth2_server.yaml
 35  
 36  The oauth2_server.yaml file configures the OAuth2 authentication service as a component within Agent Mesh Enterprise. This file tells the system to start the OAuth2 service and specifies where to find its detailed configuration.
 37  
 38  Create a file named `oauth2_server.yaml` in the root directory of your Named Docker Volume with the following content:
 39  
 40  ```yaml
 41  ---
 42  # Example gateway configuration with OAuth2 service integration
 43  # This shows how to configure a gateway to use the OAuth2 authentication service
 44  
 45  log:
 46    stdout_log_level: INFO
 47    log_file_level: DEBUG
 48    log_file: oauth_server.log
 49  
 50  !include ../shared_config.yaml
 51  
 52  shared_config:
 53    # OAuth2 service configuration
 54    - oauth2_config: &oauth2_config
 55        enabled: true
 56        config_file: "configs/sso_vol/oauth2_config.yaml"
 57        host: ${OAUTH2_HOST, localhost}
 58        port: ${OAUTH2_PORT, 8080}
 59        ssl_cert: ""  # Optional: path to SSL certificate
 60        ssl_key: ""   # Optional: path to SSL private key
 61  
 62  flows:
 63    # Initialize OAuth2 service
 64    - name: oauth2_service
 65      components:
 66        - component_name: oauth2_auth_service
 67          component_module: solace_agent_mesh_enterprise.components.oauth2_component
 68          component_config:
 69            <<: *oauth2_config
 70  ```
 71  
 72  This configuration accomplishes several things:
 73  
 74  - It sets up logging for the OAuth2 service, directing detailed debug information to oauth_server.log
 75  - It references the shared_config.yaml file, which contains common configuration used across multiple components
 76  - It defines the OAuth2 service configuration, including where to find the provider-specific settings (oauth2_config.yaml)
 77  - It specifies the host and port where the OAuth2 service will listen for requests
 78  - It creates a flow that initializes the OAuth2 authentication service component
 79  
 80  The `${OAUTH2_HOST, localhost}` syntax means the service will use the OAUTH2_HOST environment variable if provided, otherwise it defaults to localhost. This pattern allows you to override configuration values at runtime without modifying the file.
 81  
 82  ### Create oauth2_config.yaml
 83  
 84  The oauth2_config.yaml file contains provider-specific configuration for your chosen OAuth2 identity provider. This is where you specify which provider to use and provide the necessary credentials and endpoints.
 85  
 86  Create a file named `oauth2_config.yaml` in the same directory with the following content:
 87  
 88  ```yaml
 89  ---
 90  # OAuth2 Service Configuration
 91  # This file configures the OAuth2 authentication service that supports multiple providers
 92  # All providers now use the unified OIDC approach with automatic endpoint discovery
 93  
 94  # Enable or disable the OAuth2 service
 95  enabled: ${OAUTH2_ENABLED:false}
 96  
 97  # Development mode - enables insecure transport and relaxed token scope for local development
 98  # Set OAUTH2_DEV_MODE=true for local development (NEVER use in production!)
 99  development_mode: ${OAUTH2_DEV_MODE:false}
100  
101  # OAuth2 providers configuration
102  # All providers now use the unified OIDCProvider with automatic endpoint discovery
103  providers:
104    # Google OAuth2 provider
105    # google:
106    #   # OIDC issuer URL - endpoints will be discovered automatically
107    #   issuer: "https://accounts.google.com"
108    #   client_id: ${GOOGLE_CLIENT_ID}
109    #   client_secret: ${GOOGLE_CLIENT_SECRET}
110    #   redirect_uri: ${GOOGLE_REDIRECT_URI:http://localhost:8080/callback}
111    #   scope: "openid email profile"
112  
113    # Azure/Microsoft OAuth2 provider
114    azure:
115      # Azure OIDC issuer URL includes tenant ID
116      issuer: https://login.microsoftonline.com/${AZURE_TENANT_ID}/v2.0
117      client_id: ${AZURE_CLIENT_ID}
118      client_secret: ${AZURE_CLIENT_SECRET}
119      redirect_uri: ${AZURE_REDIRECT_URI:http://localhost:8080/callback}
120      scope: "openid email profile offline_access"
121  
122    # Auth0 OAuth2 provider
123    # auth0:
124    #   # Auth0 issuer URL
125    #   issuer: ${AUTH0_ISSUER:https://your-domain.auth0.com/}
126    #   client_id: ${AUTH0_CLIENT_ID}
127    #   client_secret: ${AUTH0_CLIENT_SECRET}
128    #   redirect_uri: ${AUTH0_REDIRECT_URI:http://localhost:8080/callback}
129    #   scope: "openid email profile"
130    #   # Optional: Auth0 audience for API access
131    #   audience: ${AUTH0_AUDIENCE:}
132  
133    # # Okta OAuth2 provider (example)
134    # okta:
135    #   issuer: ${OKTA_ISSUER:https://your-okta-domain.okta.com/oauth2/default}
136    #   client_id: ${OKTA_CLIENT_ID}
137    #   client_secret: ${OKTA_CLIENT_SECRET}
138    #   redirect_uri: ${OKTA_REDIRECT_URI:http://localhost:8080/callback}
139    #   scope: "openid email profile"
140  
141    # # Keycloak OAuth2 provider (example)
142    # keycloak:
143    #   issuer: ${KEYCLOAK_ISSUER:https://your-keycloak.com/auth/realms/your-realm}
144    #   client_id: ${KEYCLOAK_CLIENT_ID}
145    #   client_secret: ${KEYCLOAK_CLIENT_SECRET}
146    #   redirect_uri: ${KEYCLOAK_REDIRECT_URI:http://localhost:8080/callback}
147    #   scope: "openid email profile"
148  
149    # # Generic OIDC provider (for any standard OIDC-compliant provider)
150    # custom_oidc:
151    #   # Just provide the issuer URL and the service will discover all endpoints
152    #   issuer: ${CUSTOM_OIDC_ISSUER:https://your-provider.com}
153    #   client_id: ${CUSTOM_OIDC_CLIENT_ID}
154    #   client_secret: ${CUSTOM_OIDC_CLIENT_SECRET}
155    #   redirect_uri: ${CUSTOM_OIDC_REDIRECT_URI:http://localhost:8080/callback}
156    #   scope: "openid email profile"
157  
158  # Logging configuration
159  logging:
160    level: ${OAUTH2_LOG_LEVEL:INFO}
161  
162  # Session configuration
163  session:
164    # Session timeout in seconds (default: 1 hour)
165    timeout: ${OAUTH2_SESSION_TIMEOUT:3600}
166  
167  # Security configuration
168  security:
169    # CORS settings
170    cors:
171      enabled: ${OAUTH2_CORS_ENABLED:true}
172      origins: ${OAUTH2_CORS_ORIGINS:*}
173  
174    # Rate limiting
175    rate_limit:
176      enabled: ${OAUTH2_RATE_LIMIT_ENABLED:true}
177      requests_per_minute: ${OAUTH2_RATE_LIMIT_RPM:60}
178  ```
179  
180  This configuration file provides several features:
181  
182  The `enabled` setting controls whether the OAuth2 service is active. You can enable it by setting the OAUTH2_ENABLED environment variable to true.
183  
184  The `development_mode` setting is crucial for local testing. When enabled, it allows HTTP connections (instead of requiring HTTPS) and relaxes token validation. You must disable this in production environments to maintain security.
185  
186  The `providers` section defines multiple OAuth2 providers. By default, Azure is uncommented and active. To use a different provider, comment out the Azure section and uncomment your chosen provider. Each provider requires:
187  
188  - An `issuer` URL that points to the OAuth2 provider's discovery endpoint
189  - A `client_id` and `client_secret` obtained from your provider's application registration
190  - A `redirect_uri` where the provider sends users after authentication
191  - A `scope` that defines what user information the application can access
192  
193  The system uses OpenID Connect (OIDC) discovery, which means it automatically finds the authorization, token, and userinfo endpoints from the issuer URL. This simplifies configuration because you only need to provide the base issuer URL rather than individual endpoint URLs.
194  
195  The `session` configuration determines how long authenticated sessions remain valid. The default of 3600 seconds (1 hour) balances security with user convenience.
196  
197  The `security` section configures Cross-Origin Resource Sharing (CORS) and rate limiting. CORS allows the web UI to communicate with the OAuth2 service from different origins, while rate limiting prevents abuse by restricting the number of authentication requests per minute.
198  
199  :::info
200  The Platform Service shares this same SSO infrastructure. When you configure the WebUI Gateway for OAuth2 authentication, the Platform Service automatically uses the same token validation and the same OAuth2 provider. For details, see [Authentication and Authorization](platform-service-auth.md).
201  :::
202  
203  ### Update Your WebUI Gateway
204  
205  Update your WebUI Gateway to configure login as follows:
206  
207  ```
208  # Auth-related (placeholders, functionality depends on backend implementation)
209  frontend_auth_login_url: ${FRONTEND_AUTH_LOGIN_URL}
210  frontend_use_authorization: ${FRONTEND_USE_AUTHORIZATION}
211  frontend_redirect_url: ${FRONTEND_REDIRECT_URL, ""}
212  
213  external_auth_callback_uri: ${EXTERNAL_AUTH_CALLBACK}
214  external_auth_service_url: ${EXTERNAL_AUTH_SERVICE_URL}
215  external_auth_provider: ${EXTERNAL_AUTH_PROVIDER}
216  ```
217  
218  Your final WebUI Gateway yaml configuration should look like this:
219  
220  <details>
221  
222  <summary>WebUI Gateway SSO Enabled</summary>
223  
224  **webUI.yaml**
225  ```yaml
226  log:
227    stdout_log_level: INFO
228    log_file_level: INFO
229    log_file: webui_app.log
230  
231  
232  !include ../shared_config.yaml
233  
234  apps:
235    - name: a2a_webui_app
236      app_base_path: .
237      app_module: solace_agent_mesh.gateway.http_sse.app
238  
239      broker:
240        <<: *broker_connection
241  
242      app_config:
243        namespace: ${NAMESPACE}
244        session_secret_key: "${SESSION_SECRET_KEY}"
245        model_provider: 
246          - "general"
247        model: *general_model
248        artifact_service: *default_artifact_service
249        session_service: 
250          type: "sql"
251          database_url: ${WEB_UI_GATEWAY_DATABASE_URL, sqlite:///webui_gateway.db}
252          default_behavior: "PERSISTENT"
253        gateway_id: ${WEBUI_GATEWAY_ID}
254        fastapi_host: ${FASTAPI_HOST}
255        fastapi_port: ${FASTAPI_PORT}
256        cors_allowed_origins: 
257          - "http://localhost:3000" 
258          - "http://127.0.0.1:3000"
259  
260        enable_embed_resolution: ${ENABLE_EMBED_RESOLUTION} # Enable late-stage resolution
261        gateway_artifact_content_limit_bytes: ${GATEWAY_ARTIFACT_LIMIT_BYTES, 10000000} # Max size for late-stage embeds
262        sse_max_queue_size: ${SSE_MAX_QUEUE_SIZE, 200} # Max size of SSE connection queues
263  
264        system_purpose: >
265              The system is an AI Chatbot with agentic capabilities.
266              It will use the agents available to provide information,
267              reasoning and general assistance for the users in this system.
268              **Always return useful artifacts and files that you create to the user.**
269              Provide a status update before each tool call.
270              Your external name is Agent Mesh.
271  
272        response_format: >
273              Responses should be clear, concise, and professionally toned.
274              Format responses to the user in Markdown using appropriate formatting.
275  
276        # --- Frontend Config Passthrough ---
277        frontend_welcome_message: ${FRONTEND_WELCOME_MESSAGE}
278        frontend_bot_name: ${FRONTEND_BOT_NAME}
279        frontend_collect_feedback: ${FRONTEND_COLLECT_FEEDBACK}
280  
281        # Auth-related (placeholders, functionality depends on backend implementation)
282        frontend_auth_login_url: ${FRONTEND_AUTH_LOGIN_URL}
283        frontend_use_authorization: ${FRONTEND_USE_AUTHORIZATION}
284        frontend_redirect_url: ${FRONTEND_REDIRECT_URL, ""}
285  
286        external_auth_callback_uri: ${EXTERNAL_AUTH_CALLBACK}
287        external_auth_service_url: ${EXTERNAL_AUTH_SERVICE_URL}
288        external_auth_provider: ${EXTERNAL_AUTH_PROVIDER}
289  ```
290  </details>
291  
292  ## Step 2: Configure Your OAuth2 Provider
293  
294  Before running the Docker container, you need to register an application with your chosen OAuth2 provider and obtain the necessary credentials.
295  
296  ### For Azure (Microsoft Entra ID)
297  
298  1. Navigate to the Azure Portal and go to Microsoft Entra ID (formerly Azure Active Directory)
299  2. Select "App registrations" and create a new registration
300  3. Note the Application (client) ID and Directory (tenant) ID
301  4. Create a client secret under "Certificates & secrets"
302  5. Add a redirect URI pointing to your callback endpoint (for example, http://localhost:8000/api/v1/auth/callback)
303  6. Grant the necessary API permissions (typically Microsoft Graph with User.Read)
304  
305  ### For Google
306  
307  1. Go to the Google Cloud Console and create a new project or select an existing one
308  2. Enable the Google+ API
309  3. Create OAuth2 credentials under "APIs & Services" > "Credentials"
310  4. Configure the authorized redirect URIs
311  5. Note the client ID and client secret
312  
313  ### For Other Providers
314  
315  Consult your provider's documentation for application registration procedures. You will need to obtain a client ID, client secret, and configure the redirect URI to point to your Agent Mesh Enterprise callback endpoint.
316  
317  ## Step 3: Launch the Docker Container
318  
319  With your configuration files in place and provider credentials obtained, you can now launch the Agent Mesh Enterprise container with SSO enabled.
320  
321  The following example demonstrates a production deployment using Azure as the OAuth2 provider:
322  
323  :::tip
324  You may need to include `--platform linux/amd64` depending on the host machine you're using.
325  :::
326  
327  ```bash
328  docker run -itd -p 8000:8000 -p 8080:8080 \
329    -e LLM_SERVICE_API_KEY="<YOUR_LLM_TOKEN>" \
330    -e LLM_SERVICE_ENDPOINT="<YOUR_LLM_SERVICE_ENDPOINT>" \
331    -e LLM_SERVICE_PLANNING_MODEL_NAME="<YOUR_MODEL_NAME>" \
332    -e LLM_SERVICE_GENERAL_MODEL_NAME="<YOUR_MODEL_NAME>" \
333    -e NAMESPACE="<YOUR_NAMESPACE>" \
334    -e SOLACE_DEV_MODE="false" \
335    -e SOLACE_BROKER_URL="<YOUR_BROKER_URL>" \
336    -e SOLACE_BROKER_VPN="<YOUR_BROKER_VPN>" \
337    -e SOLACE_BROKER_USERNAME="<YOUR_BROKER_USERNAME>" \
338    -e SOLACE_BROKER_PASSWORD="<YOUR_BROKER_PASSWORD>" \
339    -e FASTAPI_HOST="0.0.0.0" \
340    -e FASTAPI_PORT="8000" \
341    -e AZURE_TENANT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \
342    -e AZURE_CLIENT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \
343    -e AZURE_CLIENT_SECRET="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \
344    -e OAUTH2_ENABLED="true" \
345    -e OAUTH2_LOG_LEVEL="DEBUG" \
346    -e OAUTH2_DEV_MODE="true" \
347    -e OAUTH2_HOST="0.0.0.0" \
348    -e OAUTH2_PORT="8080" \
349    -e FRONTEND_USE_AUTHORIZATION="true" \
350    -e FRONTEND_REDIRECT_URL="http://localhost:8000" \
351    -e FRONTEND_AUTH_LOGIN_URL="http://localhost:8000/api/v1/auth/login" \
352    -e EXTERNAL_AUTH_SERVICE_URL="http://localhost:8080" \
353    -e EXTERNAL_AUTH_PROVIDER="azure" \
354    -e EXTERNAL_AUTH_CALLBACK="http://localhost:8000/api/v1/auth/callback" \
355    -v <YOUR_NAMED_DOCKER_VOLUME>:/app/config/sso_vol/ \
356    --name sam-ent-prod-sso \
357  solace-agent-mesh-enterprise:<tag> run config/sso_vol/oauth2_server.yaml config/webui_backend.yaml config/a2a_orchestrator.yaml config/a2a_agents.yaml
358  ```
359  
360  This command starts the container in detached mode with interactive terminal support. The `-p` flags expose both the main UI port (8000) and the OAuth2 service port (8080) to the host machine. The volume mount makes your configuration files available inside the container at the expected location.
361  
362  After the container starts successfully, you can access the Agent Mesh Enterprise UI at http://localhost:8000. When you navigate to this URL, the system will redirect you to your OAuth2 provider's login page for authentication.
363  
364  ## Understanding the Environment Variables
365  
366  The Docker run command includes numerous environment variables that control different aspects of the SSO configuration. Understanding these variables helps you customize the deployment for your specific environment.
367  
368  ### Core Application Settings
369  
370  These variables configure the main Agent Mesh Enterprise application:
371  
372  ```bash
373  -e FASTAPI_HOST="0.0.0.0" \
374  -e FASTAPI_PORT="8000" \ 
375  ```
376  
377  The FASTAPI_HOST setting determines which network interfaces the main UI server binds to. Using "0.0.0.0" allows external access to the container, which is necessary for production deployments. The FASTAPI_PORT specifies which port the UI listens on inside the container.
378  
379  ### Frontend Authentication Settings
380  
381  These variables control how the web UI handles authentication:
382  
383  ```bash
384  -e FRONTEND_USE_AUTHORIZATION="true" \
385  ```
386  
387  Setting FRONTEND_USE_AUTHORIZATION to "true" enables SSO processing on the frontend. When enabled, the UI will redirect unauthenticated users to the login flow instead of allowing direct access.
388  
389  ```bash
390  -e FRONTEND_REDIRECT_URL="http://localhost:8000" \
391  ```
392  
393  The FRONTEND_REDIRECT_URL specifies the main URL of your UI. In production, this would be your public-facing domain (for example, https://www.example.com). The system uses this URL to construct proper redirect chains during authentication.
394  
395  ```bash
396  -e FRONTEND_AUTH_LOGIN_URL="http://localhost:8000/api/v1/auth/login" \
397  ```
398  
399  The FRONTEND_AUTH_LOGIN_URL tells the frontend where to send users who need to authenticate. This endpoint initiates the OAuth2 flow by redirecting to your identity provider.
400  
401  ### OAuth2 Service Settings
402  
403  These variables configure the OAuth2 authentication service itself:
404  
405  ```bash
406  -e OAUTH2_ENABLED="true" \
407  -e OAUTH2_LOG_LEVEL="DEBUG" \
408  ```
409  
410  The OAUTH2_ENABLED variable activates the OAuth2 service. Setting OAUTH2_LOG_LEVEL to "DEBUG" provides detailed logging information, which is helpful during initial setup and troubleshooting. You can change this to "INFO" or "WARNING" in production to reduce log verbosity.
411  
412  ```bash
413  -e OAUTH2_HOST="0.0.0.0" \
414  -e OAUTH2_PORT="8080" \
415  ```
416  
417  These variables specify where the OAuth2 authentication service listens for requests. Using "0.0.0.0" as the host allows external access to the container. The port must match the port mapping in your Docker run command.
418  
419  ```bash
420  -e OAUTH2_DEV_MODE="true" \
421  ```
422  
423  The OAUTH2_DEV_MODE setting controls whether the OAuth2 service operates in development mode. When set to "true", the service sets these internal environment variables:
424  
425  ```bash
426  OAUTHLIB_RELAX_TOKEN_SCOPE="1"
427  OAUTHLIB_INSECURE_TRANSPORT="1"
428  ```
429  
430  These settings allow HTTP connections (instead of requiring HTTPS) and relax token scope validation. This is convenient for local development and testing, but you must set OAUTH2_DEV_MODE to "false" in production environments to maintain security. Production deployments should always use HTTPS with valid SSL certificates.
431  
432  ### Provider-Specific Credentials
433  
434  These variables provide the credentials obtained from your OAuth2 provider. The example shows Azure configuration:
435  
436  ```bash
437  -e AZURE_TENANT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \
438  -e AZURE_CLIENT_ID="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \
439  -e AZURE_CLIENT_SECRET="xxxxxxxxx-xxxxxx-xxxxxxxx-xxxxxxxxxx" \
440  ```
441  
442  The required variables depend on which provider you configured in oauth2_config.yaml. For Google, you would use GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET. For Auth0, you would use AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET, and AUTH0_ISSUER. Refer to the oauth2_config.yaml file to identify the exact variable names for your chosen provider.
443  
444  ### External Authentication Configuration
445  
446  These variables connect the main UI to the OAuth2 service:
447  
448  ```bash
449  -e EXTERNAL_AUTH_SERVICE_URL="http://localhost:8080" \
450  -e EXTERNAL_AUTH_PROVIDER="azure" \
451  ```
452  
453  The EXTERNAL_AUTH_SERVICE_URL specifies the URL where the OAuth2 service can be reached by the WebUI Gateway backend. This is used for server-to-server communication (code exchange, token validation, user info retrieval) and does not need to be publicly accessible. The identity provider redirects users to `EXTERNAL_AUTH_CALLBACK` (the WebUI Gateway), not to this URL. The EXTERNAL_AUTH_PROVIDER must match one of the provider names defined in your oauth2_config.yaml file (in this example, "azure").
454  
455  ```bash
456  -e EXTERNAL_AUTH_CALLBACK="http://localhost:8000/api/v1/auth/callback" \
457  ```
458  
459  The EXTERNAL_AUTH_CALLBACK is the URL where your OAuth2 provider redirects users after successful authentication. This URL must be registered with your OAuth2 provider as an authorized redirect URI. In production, this would be your public domain followed by the callback path (for example, https://www.example.com/api/v1/auth/callback).
460  
461  ### Port Mapping and Volume Mount
462  
463  Two additional configuration elements are required for SSO to function:
464  
465  ```bash
466  -p 8000:8000 -p 8080:8080 \
467  ```
468  
469  Both the main UI port (8000) and the OAuth2 service port (8080) must be mapped to the host machine. The UI port must be externally accessible for the OAuth callback redirect. The OAuth2 service port needs to be reachable from the WebUI Gateway backend for server-to-server token operations.
470  
471  ```bash
472  -v <YOUR_NAMED_DOCKER_VOLUME>:/app/config/sso_vol/ \
473  ```
474  
475  The volume mount makes your OAuth2 configuration files available inside the container at the expected location. Replace `<YOUR_NAMED_DOCKER_VOLUME>` with the path to your Named Docker Volume containing the oauth2_server.yaml and oauth2_config.yaml files.
476  
477  ## Verifying Your SSO Configuration
478  
479  After starting the container, you can verify that SSO is working correctly:
480  
481  1. Navigate to http://localhost:8000 in your web browser
482  2. You should be automatically redirected to your OAuth2 provider's login page
483  3. After entering your credentials, you should be redirected back to the Agent Mesh Enterprise UI
484  4. Check the container logs for any authentication errors: `docker logs sam-ent-prod-sso`
485  
486  If you encounter issues, check that:
487  
488  - Your OAuth2 provider credentials are correct
489  - The redirect URI in your provider's configuration matches the EXTERNAL_AUTH_CALLBACK value
490  - Both ports (8000 and 8080) are accessible from your network
491  - The configuration files are properly mounted in the container
492  
493  ## Understanding the OAuth2 Flow and Environment Variables
494  
495  When using SSO, it’s important to understand how the authentication flow works between the WebUI Gateway, the OAuth2 service, and your identity provider (IdP). This section clarifies the purpose of each variable and common configuration mistakes.
496  
497  ### How the OAuth2 Flow Works
498  
499  1. A user opens the frontend application (for example, `http://localhost:8000`).  
500     - The frontend checks whether a valid access token exists (e.g., in local storage or cookies).  
501     - If no valid token is found or the token has expired, the frontend automatically calls the backend endpoint defined by `FRONTEND_AUTH_LOGIN_URL` (for example, `http://localhost:8000/api/v1/auth/login`) to start the authentication process.  
502  2. The WebUI Gateway redirects the user's browser to the OAuth2 service at `EXTERNAL_AUTH_SERVICE_URL` (typically `http://localhost:8080`), passing the `EXTERNAL_AUTH_PROVIDER` value (such as `azure` or `keycloak` or `auth0`, or `google`) and the `EXTERNAL_AUTH_CALLBACK` as the redirect URI.
503  3. The OAuth2 service looks up the provider in `oauth2_config.yaml` and automatically constructs the correct authorization request using the provider's `issuer`, `client_id`, `redirect_uri`, and `scope`.
504  4. The user is redirected to the IdP (e.g., Azure AD, Auth0, or Keycloak) for login.
505  5. After successful login, the IdP redirects the user back to `EXTERNAL_AUTH_CALLBACK` (for example, `http://localhost:8000/api/v1/auth/callback`), which is handled by the WebUI Gateway.
506  6. The WebUI Gateway receives the authorization code and calls the OAuth2 service's `/exchange-code` endpoint (server-to-server) to exchange it for tokens. The OAuth2 service returns the tokens and user info to the WebUI Gateway, which then mints a SAM Access Token (if enabled) and returns it to the frontend.
507  
508  :::info
509  You do not need to manually append `client_id`, `scope`, or `redirect_uri` query parameters to the login URL. The OAuth2 service automatically handles these based on the selected provider in `oauth2_config.yaml`.
510  :::
511  
512  ### Common Environment Variables
513  
514  | Variable | Purpose | Example |
515  |-----------|----------|----------|
516  | `FRONTEND_AUTH_LOGIN_URL` | The frontend endpoint that triggers authentication. It should **not** include OAuth query parameters. | `http://localhost:8000/api/v1/auth/login` |
517  | `EXTERNAL_AUTH_SERVICE_URL` | URL of the OAuth2 authentication service. | `http://localhost:8080` |
518  | `EXTERNAL_AUTH_PROVIDER` | The IdP name as defined under `providers:` in `oauth2_config.yaml`. | `azure` or `keycloak` |
519  | `EXTERNAL_AUTH_CALLBACK` | Callback URI used after login. Must match the redirect URI registered with your IdP. | `http://localhost:8000/api/v1/auth/callback` |
520  | `FRONTEND_REDIRECT_URL` | Where users are redirected after login completes. | `http://localhost:8000` |
521  
522  ## Security Considerations for Production
523  
524  When deploying SSO in a production environment, follow these security best practices:
525  
526  Set OAUTH2_DEV_MODE to "false" to disable insecure transport and enforce proper token validation. This ensures that all OAuth2 communication uses HTTPS with valid SSL certificates.
527  
528  Use HTTPS for all URLs (FRONTEND_REDIRECT_URL, FRONTEND_AUTH_LOGIN_URL, EXTERNAL_AUTH_SERVICE_URL, and EXTERNAL_AUTH_CALLBACK). Configure SSL certificates using the ssl_cert and ssl_key parameters in oauth2_server.yaml.
529  
530  Restrict CORS origins by setting OAUTH2_CORS_ORIGINS to your specific domain instead of using the wildcard "*". This prevents unauthorized websites from making requests to your authentication service.
531  
532  Regularly rotate your OAuth2 client secrets and update the corresponding environment variables. Store sensitive credentials securely using Docker secrets or a secrets management service rather than passing them directly in the command line.
533  
534  Configure appropriate session timeouts based on your security requirements. Shorter timeouts increase security but may inconvenience users who need to reauthenticate more frequently.
535  
536  Monitor authentication logs for suspicious activity and failed login attempts. The OAuth2 service logs all authentication events, which you can review for security auditing.