Skip to content

OpenID Connect (OIDC) Setup

Portal supports OpenID Connect (OIDC) for single sign-on with any OIDC-compliant identity provider, including AWS Cognito, Azure AD / Microsoft Entra ID, Google Identity Platform, and Okta.

Requires Portal 1.20.0 or later

OIDC sign-in completes only on Portal 1.20.0 and later. On earlier releases the sign-in cannot be completed: Portal does not issue a usable session at the end of the flow, whatever the identity provider settings are. Upgrade before configuring OIDC.

Warning

OIDC authentication does not work with the Tableau REST API. If your Portal uses Tableau integration, you must use static dashboards rather than the Tableau REST API.

Prerequisites

  • Docker-based Portal deployment
  • Access to your organization's OIDC identity provider admin console
  • Ability to update the Portal's Docker Compose and NGINX configuration

Step 1: Register Portal with Your Identity Provider

Create a new application in your OIDC provider with the following settings:

Setting Value
Application Type Web Application
Grant Type Authorization Code
Redirect URI https://<your-portal-hostname>/openidc/authorize
Scopes openid, profile, email

After registration, note these values:

  • Client ID
  • Client Secret
  • Issuer URL (provided by your identity provider)

Step 2: Create the Settings File

Create a file named settings.json:

{
  "client_id": "your-client-id",
  "client_secret": "your-client-secret",
  "redirect_uri": "https://<your-portal-hostname>/openidc/authorize",
  "issuer": "https://your-identity-provider-issuer-url"
}

Provider-Specific Examples

AWS Cognito:

{
  "client_id": "1a2b3c4d5e6f7g8h9i0j",
  "client_secret": "abcdefghijklmno1234567890",
  "redirect_uri": "https://portal.example.com/openidc/authorize",
  "issuer": "https://cognito-idp.us-east-2.amazonaws.com/us-east-2_EXAMPLE01"
}

The Cognito issuer URL format is: https://cognito-idp.<region>.amazonaws.com/<user-pool-id>

Azure AD / Entra ID:

{
  "client_id": "application-id-from-azure",
  "client_secret": "client-secret-from-azure",
  "redirect_uri": "https://portal.example.com/openidc/authorize",
  "issuer": "https://login.microsoftonline.com/<tenant-id>/v2.0"
}

How Portal names the user

OIDC does not define a username claim, so Portal picks one from the claims your identity provider returns, trying these in order and using the first one present:

  1. username
  2. preferred_username
  3. email
  4. sub

Portal creates the user account on first sign-in, using that name. sub comes last because it is the only claim guaranteed to be present but is usually an opaque identifier - AWS Cognito, for example, returns a UUID, which would then be the visible username in Portal.

To use a specific claim instead, add username_claim to your settings:

{
  "client_id": "your-client-id",
  "client_secret": "your-client-secret",
  "redirect_uri": "https://<your-portal-hostname>/openidc/authorize",
  "issuer": "https://your-identity-provider-issuer-url",
  "username_claim": "email"
}

Only that claim is then used, and sign-in fails if it is absent.

Names must not collide with existing accounts

Portal will not sign an OIDC user in to an account it did not create - a local username/password account, or one synced from Tableau. If the name coming from your identity provider matches one of those, that sign-in is refused. Choose a username_claim that does not collide, or rename the existing account.

Step 3: Deploy the Configuration

  1. Place settings.json in a directory accessible to Docker (e.g., app/openidc/).

  2. Add a volume mount to the auth service in your docker-compose.yaml:

services:
  auth:
    volumes:
      - ./app/openidc:/app/openidc

Step 4: Configure NGINX

Ensure your NGINX configuration routes the OIDC endpoints to the auth service:

location ~ /(openidc/redirect|openidc/authorize)$ {
    proxy_pass http://auth:5756$request_uri;
    include proxy_params;
    include nocache_params;
}

Update the 401 handler to redirect to OIDC instead of the standard login page:

location @401 {
    return 302 https://$http_host/openidc/redirect?location=https://$http_host$request_uri;
}

Step 5: Restart and Test

  1. Restart the Portal:

    docker-compose down && docker-compose up -d
    

  2. Navigate to your Portal URL. You should be redirected to your identity provider's login page.

  3. Log in with your corporate credentials.
  4. You should be redirected back to Portal and logged in.

Troubleshooting

  • Redirect loop - Verify the redirect URI in settings.json exactly matches what is registered with your identity provider.
  • Settings file not found - Check the Docker volume mount and ensure settings.json exists at the mounted path. Restart the auth service.
  • Invalid client error - Verify the client_id and client_secret are correct and the application is still active.
  • HTTPS required - The redirect URI must use https://. Ensure your Portal is accessible via HTTPS.
  • "OIDC response has no ID token" - The authorization request is missing the openid scope, so the provider returned no ID token. Add openid to the scopes registered for the application.
  • "OIDC response has no username claim" - None of the claims Portal looks for were returned. Add the profile or email scope, or set username_claim to a claim your provider does return. See How Portal names the user.
  • "Username is already in use by another account" - The name coming from your identity provider already belongs to a Portal account created another way, such as a local account or one synced from Tableau. Portal refuses the sign-in rather than taking over that account. Rename the existing account, or set username_claim to a claim that does not collide.
  • Sign-in appears to work but pages fail to load - On Portal 1.19.x and earlier, OIDC completes at the browser level but the resulting session is not usable. Upgrade to 1.20.0 or later.

Login behavior (Portal 1.20.0)

Locked out of SSO?

If a broken SSO configuration or an identity-provider outage keeps admins from signing in, Portal can keep a local-admin login available as a fallback. See Local login fallback when SSO is enabled.