Skip to main content

Configuring Dependency-Track with Microsoft Entra ID (Azure AD) OIDC Authentication

In my previous posts, I introduced Dependency-Track and showed you how to deploy it on Azure Container Apps. Now that you have a working instance, it's time to secure it properly by integrating with your organization's identity provider.

In this post, I'll walk you through configuring Dependency-Track to use OpenID Connect (OIDC) authentication with Microsoft Entra ID (formerly Azure Active Directory). This integration will allow your users to log in using their existing corporate credentials, enable single sign-on (SSO), and leverage conditional access policies for enhanced security.

Why using OIDC with Microsoft Entra ID?

Before diving into the configuration, let's understand the benefits of this integration:

Centralized Identity Management: Users authenticate with their existing Microsoft Entra ID accounts, eliminating the need to manage separate credentials for Dependency-Track.

Single Sign-On (SSO): Users already logged into Microsoft services can access Dependency-Track seamlessly without re-entering credentials.

Enhanced Security: Leverage Microsoft Entra ID's security features like multi-factor authentication (MFA), conditional access policies, and risk-based authentication.

Automated User Provisioning: User accounts are automatically created in Dependency-Track upon first login, reducing administrative overhead.

Group-Based Access Control: Map Microsoft Entra ID groups to Dependency-Track teams for streamlined permission management.

Configuration steps

Prerequisites

Before starting, ensure you have:

  • Administrative access to your Microsoft Entra ID tenant
  • Administrative access to your Dependency-Track instance
  • Your Dependency-Track URL (the frontend URL)

Step 1: Register an application in Microsoft Entra ID

First, we need to register Dependency-Track as an application in Microsoft Entra ID:

  1. Sign in to the Azure Portal
  2. Navigate to Microsoft Entra IDApp registrationsNew registration
  3. Configure the application registration:
    • Name: Dependency-Track
    • Supported account types: Select "Accounts in this organizational directory only (Single tenant)"
    • Redirect URI:
      • Platform: Web
      • URI: https://your-dtrack-frontend-url/static/oidc-callback.html
    Replace your-dtrack-frontend-url with your actual Dependency-Track frontend URL.
  4. Click Register

After registration, note down the following values from the Overview page:

  • Application (client) ID: This is your OIDC Client ID
  • Directory (tenant) ID: This is your Tenant ID

Step 2: Configure API permissions

Dependency-Track needs specific permissions to read user and group information:

  1. In your app registration, navigate to API permissions
  2. Click Add a permissionMicrosoft GraphDelegated permissions
  3. Add the following permissions:
    • openid (usually already present)
    • profile (usually already present)
    • email (usually already present)
    • GroupMember.Read.All - Read group memberships (if using group-based access)
  4. Click Add permissions      

Step 3: Configure Group claims

If you want to map Microsoft Entra ID groups to Dependency-Track teams:

  1. In your app registration, navigate to Token configuration
  2. Click Add groups claim
  3. Select:
    • Groups assigned to the application
    • Check Group ID under "Customize token properties by type" for ID tokens
  4. Click Add

Note: By default, Microsoft Entra ID includes group object IDs in the token. You'll need to map these IDs to Dependency-Track teams.

Step 4: Configure Dependency-Track API Server

Now we need to update the Dependency-Track API server container app with the OIDC configuration:

Let me explain the key environment variables:

  • ALPINE_OIDC_ENABLED: Enables OIDC authentication
  • ALPINE_OIDC_CLIENT_ID: The Application (client) ID from Entra ID
  • ALPINE_OIDC_ISSUER: The OpenID Connect issuer URL (includes your tenant ID)
  • ALPINE_OIDC_USERNAME_CLAIM: Which claim to use as the username (typically email or preferred_username)
  • ALPINE_OIDC_USER_PROVISIONING: Automatically creates user accounts on first login
  • ALPINE_OIDC_TEAMS_CLAIM: Which claim contains group memberships (typically groups)

Additional optional settings:

  • ALPINE_OIDC_TEAM_SYNCHRONIZATION: Set to true to sync group memberships on each login

Step 5: Configure Dependency-Track UI

Almost there! We also need to update the Dependency-Track UI container app:

Testing the OIDC Integration

After the configuration is applied and the container restarts:

  • Navigate to your Dependency-Track frontend URL
  • If the configuration was correct, you should see an "OpenID" button on the login page
  • Click the OIDC login button
  • You'll be redirected to Microsoft's login page
  • Sign in with your Microsoft Entra ID credentials
  • After successful authentication, you'll be redirected back to Dependency-Track
  • Your user account will be automatically created with the email address as the username

However, you will still not be able to do anything as your user didn’t have any permissions (yet).

Configure Team Mappings

You could manually add the created user to a team or assign permissions but you’ll notice that with the next login all permissions are gone again. The correct way is to assign a user to a  team based on their Microsoft Entra ID group memberships:

Get Group Object IDs

First, identify the Object IDs of the groups you want to map:

Create Teams in Dependency-Track

  • Log into Dependency-Track with an admin account
  • Navigate to AdministrationAccess ManagementTeams
  • Create a new team (e.g., "Security Team", "Developers", "Architects")
  • In the team configuration, under OpenID Connect Groups, add the Group Object IDs from Microsoft Entra ID
  • Assign appropriate permissions to each team

Now you should be able to successfully access Dependency-Track with your Microsoft Entra account.

More information

OpenID Connect Configuration | Dependency-Track

Microsoft Entra ID App Registration | Dependency-Track

Popular posts from this blog

Podman– Command execution failed with exit code 125

After updating WSL on one of the developer machines, Podman failed to work. When we took a look through Podman Desktop, we noticed that Podman had stopped running and returned the following error message: Error: Command execution failed with exit code 125 Here are the steps we tried to fix the issue: We started by running podman info to get some extra details on what could be wrong: >podman info OS: windows/amd64 provider: wsl version: 5.3.1 Cannot connect to Podman. Please verify your connection to the Linux system using `podman system connection list`, or try `podman machine init` and `podman machine start` to manage a new Linux VM Error: unable to connect to Podman socket: failed to connect: dial tcp 127.0.0.1:2655: connectex: No connection could be made because the target machine actively refused it. That makes sense as the podman VM was not running. Let’s check the VM: >podman machine list NAME         ...

Cache stampede: when our cache turned against us

While investigating some performance issues, we ran into an ASP.NET Core API that cached a fairly expensive aggregation query for 60 seconds. Under normal load, that was fine: one request rebuilds the cache, everyone else reads from it. Under peak load, dozens of requests would arrive in that same expiry window, all see a cache miss, and all fire the same expensive query in parallel. The database didn't like that. That was the moment when our caching layer stopped helping and started hurting. A burst of requests comes in at the same time, all miss the cache, and all go hammer the database or the downstream API at once. That's a cache stampede . The cache was supposed to protect our backend, and for a few hundred milliseconds it did the opposite. Why this happens IMemoryCache.GetOrCreate (and its async sibling) looks like it protects you, but it doesn't add any locking on its own. Look at the naive version: public async Task<Report> GetReportAsync(string key) ...

A complex system designed from scratch never works

A few years ago, I worked as an architect on a big mainframe rewrite. I still count it as one of my failures. Not because the technology was wrong, but because I couldn't convince the management team to simplify the approach. Years later, the organization is still struggling to get the new system up and running. I left the project at the time, because I couldn't put my name behind an approach that would take very long and cost a lot of money without a working system to show for it along the way. Gall’s Law That memory keeps coming back to me, because it's a textbook case of Gall's Law playing out in real life. Gall's Law , from John Gall's Systemantics , states it plainly: A complex system that works is invariably found to have evolved from a simple system that worked. A complex system designed from scratch never works, and it cannot be patched to make it work. You have to start over with a simple system that works. What does that mean in practice,...