﻿# Microsoft Entra ID authentication

You can use Microsoft Entra ID, formerly known as Azure Active Directory (AAD), to authenticate when logging in to the Octopus Server. To use Microsoft Entra ID authentication with Octopus, you will need to do the following:

1. Configure Microsoft Entra ID to trust your Octopus Deploy instance by setting it up as an App in your Microsoft Azure Portal.
2. Optionally, map Entra ID Users into Roles so that users can be automatically connected to Octopus Teams.
3. Configure your Octopus Deploy instance to trust and use Microsoft Entra ID as an Identity Provider.

:::div{.hint}
If your Octopus database is running in Azure SQL, it's also possible to configure a Microsoft Entra ID Managed identity for use with your SQL database. See our [Using Microsoft Entra ID in Azure SQL](/docs/installation/sql-server-database/#using-aad-in-azure-sql) section for further information.
:::

## Configure Microsoft Entra ID

First, you need to configure your Microsoft Entra ID to trust your instance of Octopus Deploy by configuring an App in your Microsoft Azure Portal.

### Configure Octopus Deploy as an App in your Azure Portal

:::div{.success}
**Get the right permissions for your Microsoft Entra ID tenant before starting**
To configure your instance of Octopus Deploy as an App, you need administrator permissions for the desired Microsoft Entra ID tenant in your subscription.
:::

1. Log in to the [Azure Portal](https://portal.azure.com), click on your account positioned at the top-right of the screen, then select your desired directory:

:::figure
![Switch Azure Directories](/docs/img/security/authentication/images/aad-portal.png)
:::

1. Select "All services" in the [Azure Portal](https://portal.azure.com)  and select **Microsoft Entra ID** from the Azure menu:

:::figure
![Open Microsoft Entra ID service](/docs/img/security/authentication/images/aad-service.png)
:::

1. In the top menu, select *Add** then choose **App registration**:

:::figure
![New App registration](/docs/img/security/authentication/images/aad-new-app-registration.png)
:::

4. Choose a **Name** such as *Octopus Deploy*, select the correct **Supported account type** for Single or Multi-Tenant, choose **Web** from the drop down and enter a value for **Redirect URI** like `https://octopus.example.com/api/users/authenticatedToken/AzureAD`. Then click **Register**.
 - The URL must use HTTPS.
 - When users input their credentials, the value you specify for **Name** will appear at the top of the Azure authentication page.
 - The value you specify for **Redirect URI** should be the URL to your Octopus Server. This address is only linked within your browser, so it only has to be resolvable on your network, not from the public Internet.
 - Include `/api/users/authenticatedToken/AzureAD` at the end of your Octopus URL.

:::div{.hint}
Take care when you add this URL. They are **case-sensitive** and can be sensitive to trailing **slash** characters. You cannot use `HTTP` here and need to use `https`. You will need to use an SSL certificate from a Certificate Authority, such as [LetsEncrypt](https://letsencrypt.org/). You can do this by using Octopus Deploy [Let's Encrypt Integration](/docs/security/exposing-octopus/lets-encrypt-integration) or one from Active Directory Certificate Services.
:::

:::figure
![Filling the App registration form](/docs/img/security/authentication/images/aad-new-app-registration-form.png)
:::

#### Enable ID Tokens and configure

:::div{.hint}
Support for OAuth code flow with PKCE was introduced in **Octopus 2022.2.4498**. This step is **not required** for any newer versions of Octopus. Instead, we suggest following the instructions for [generating a client secret](#generate-the-client-secret) below.
:::

1. Within your new App registration in Microsoft Entra ID, navigate to Manage > Authentication.
2. Ensure the ID Tokens box is enabled:

:::figure
![Enable ID Token](/docs/img/security/authentication/images/aad_id_token.png)
:::

#### Enable Logout URL if using Single Sign-On (optional)

1. Within your new App registration in Microsoft Entra ID, navigate to Authentication.
2. Input logout URL and enter `https://octopus.example.com/app#/users/sign-out` substituting your URL.

:::figure
![Configure Logout URL](/docs/img/security/authentication/images/aad_logout_url.png)
:::

#### Mapping Microsoft Entra ID users into Octopus teams (optional)

If you want to manage user/team membership via Microsoft Entra ID, you must configure Roles for your App. To add Role(s), you can create and assign a new App Role in the Azure Portal or directly edit the App's manifest.

##### Create and Assign a new Microsoft Entra ID App Role

1. On the left hand side menu, select **App roles** and click the **Create app role** button.

   ![Creating new App Role](/docs/img/security/authentication/images/aad-new-app-role-create.png)

2. Enter all required fields and click **Apply** to create the new app role.

   ![Apply App Role value and name](/docs/img/security/authentication/images/aad-new-app-role-create-apply.png)

   :::div{.hint}
   The **Value** property is the most important field. This value becomes the external Role ID you use later on when [adding this Role to a Team](/docs/security/users-and-teams/external-groups-and-roles/#ExternalGroupsandRoles-AddExternalRole) in Octopus Deploy.
   :::

##### Edit Microsoft Entra ID App Manifest

1. Under the App Registration, select **Manifest**, and then you can start editing your manifest file as required.

:::figure
![Editing an App registration manifest](/docs/img/security/authentication/images/aad-edit-app-registration-manifest.png)
:::

The example below illustrates two roles, one for administrators and one for application testers. You need to create each required group in the Manifest file.

:::div{.success}
Make sure you replace the `NEWGUID`s with a generated GUID (unique per entry). You can find these online and use them as required. An example is the [Online GUID / UUID Generator](https://guidgenerator.com/).
:::

```json
{
  "appId": "myAppGuid",
  "appRoles": [
   {
      "id": "NEWGUID1",
      "allowedMemberTypes": ["User"],
      "description": "OctopusAdministrators",
      "displayName": "OctopusAdmins",
      "isEnabled": true,
      "value": "octopusAdmins"
   },
   {
      "id": "NEWGUID2",
      "allowedMemberTypes": ["User"],
      "description": "OctopusTesters",
      "displayName": "OctopusTesters",
      "isEnabled": true,
      "value": "octopusTesters"
   }
  ]
}
```

After you have completed editing the manifest, select the **Save** option.

:::figure
![Saving an App registration manifest](/docs/img/security/authentication/images/aad-save-app-registration-manifest.png)
:::

:::div{.hint}
The **value** property is the most important one. This value becomes the external Role ID you use later on when [adding this Role to a Team](/docs/security/users-and-teams) in Octopus Deploy.
:::

:::div{.success}
**Want a more advanced manifest?**
For more advanced scenarios, please see the [Azure manifest file documentation](https://learn.microsoft.com/en-us/entra/identity-platform/reference-app-manifest).
:::

#### Configure users and groups in Microsoft Entra ID (optional)

After the App Role(s) have been defined, users/groups from Microsoft Entra ID may be mapped into these Roles.

1. Under the App Registration, select your App registrations name under **Managed application in local directory**.

:::figure
![Editing App registration users](/docs/img/security/authentication/images/aad-edit-app-registration-users.png)
:::

1. Choose **Assign users and groups** and select **Add user/group** to create a new role assignment.

2. Select the users you would like to assign roles to. Next, under **Select Role**, specify one of the AppRoles that you added to the App registration manifest.

:::figure
![Editing App registration users role](/docs/img/security/authentication/images/aad-edit-app-registration-users-role.png)
:::

4. To save your changes, select the **Assign** button.

:::div{.hint}
If you have only one role, it will be automatically assigned. If you have multiple roles, a pop-up will appear when you click the **Assign** button so you can select the role to assign.
:::

## Configure Octopus Server

To complete the Octopus configuration, you need three values from the Microsoft Entra ID configuration: the **Client ID**, **Client Secret**, and **Issuer**.

### Get the Client ID and Issuer

In the Azure portal, you can see the **Application (client) ID** and **Directory (tenant) ID** on your App's Overview page.

:::figure
![Getting the App registration](/docs/img/security/authentication/images/aad-get-app-registration-id.png)
:::

### Generate the Client secret

In the Azure portal, navigate to the **Certificates & secrets** page and click **New client secret** to generate a new client secret for the App registration.

:::figure
![Generating a client secret](/docs/img/security/authentication/images/aad-client-secret.png)
:::

### Setting the Client ID, Client secret and Issuer in Octopus Deploy

:::div{.hint}
Support for OAuth code flow with PKCE was introduced in **Octopus 2022.2.4498**. If you are using a version older than this, the **Client secret** setting is not required.
:::

:::div{.hint}
If Microsoft Entra ID is used to synchronize external groups with the 'group' role claim type and the user is a member of more than 200 Microsoft Entra ID groups, the client secret field is required.
:::

To configure Octopus to use Microsoft Entra ID authentication, you'll need:

- The **Client ID**, which should be a GUID. This is the **Application (client) ID** in the Azure App Registration Portal.
- The **Client secret**, which should be a long string value. This is the **Value** of a client secret in the Azure App Registration Portal.
- The **Issuer**, which should be a URL like `https://login.microsoftonline.com/GUID` where the `GUID` is a particular GUID identifying your Microsoft Entra ID tenant. This is the **Directory (tenant) ID** in the Azure App Registration Portal.

When you have those values, run the following from a command prompt in the folder where you installed Octopus Server:

```powershell
Octopus.Server.exe configure --azureADIsEnabled=true --azureADIssuer=Issuer --azureADClientId=ClientID --azureADClientSecret=ClientSecret

# e.g.
# Octopus.Server.exe configure --azureADIsEnabled=true --azureADIssuer=https://login.microsoftonline.com/12341234-xxxx-xxxx-xxxx-xxxxxxxxxxxx --azureADClientId=43214321-xxxx-xxxx-xxxx-xxxxxxxxxxxx --azureADClientSecret=bCeXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```

Alternatively, these settings can be defined through the user interface by selecting **Configuration ➜ Settings ➜ Azure AD** and populating the fields **Issuer**, **ClientId**, **ClientSecret**, and **IsEnabled**. If you want to remove the ClientSecret you can use the delete button shown in the screenshot.

:::figure
![Settings](/docs/img/security/authentication/images/aad-azure-ad-settings.png)
:::

### Assign app registration roles to Octopus teams (optional)

If you followed the optional steps to modify the App registration's manifest to include new roles, you can assign them to **Teams** in the Octopus Portal.

1. Open the Octopus Portal and select **Configuration ➜ Teams**.

2. Either create a new **Team** or choose an existing one.

3. Under the **Members** section, select the option **Add External Group/Role**.
 
![Adding Octopus Teams from external providers](/docs/img/security/authentication/images/add-octopus-teams-external.png)

4. Enter the details from your App registration's manifest. In this example, we need to supply `octopusTesters` as the **Group/Role ID** and `OctopusTesters` as the **Display Name**.
 
![Add Octopus Teams Dialog](/docs/img/security/authentication/images/add-octopus-teams-external-dialog.png)

5. Save your changes by clicking the **Save** button.

### Octopus user accounts are still required

Even if you are using an external identity provider, Octopus still requires a [user account](/docs/security/users-and-teams/), so that you can assign those people to Octopus teams and subsequently grant permissions to Octopus resources. Octopus will automatically create a [user account](/docs/security/users-and-teams) based on the profile information returned in the security token, which includes an **Identifier**, **Name**, and **Email Address**.

**How Octopus matches external identities to user accounts**

When the security token is returned from the external identity provider, Octopus looks for a user account with a **matching Identifier**. If there is no match, Octopus looks for a user account with a **matching Email Address**. If a user account is found, the external identifier will be added to the user account for next time. If a user account is not found, Octopus will create one using the profile information in the security token.

:::div{.hint}
**Existing Octopus user accounts**

If you already have Octopus user accounts and you want to enable Microsoft Entra ID authentication:
- Make sure the **Email Address** and **Username** values for Octopus user accounts are both identical.
- Confirm the Octopus user **Email Address** and **Username** match the email address configured in Microsoft Entra ID.

This will maximize the chance for your existing users to sign in using Microsoft Entra ID and prevent duplicate Octopus user accounts from being created.
:::

### Getting permissions

If you are installing a clean instance of Octopus Deploy you will need to *seed* it with at least one admin user. This user will have access to create and configure other users as required. To add a user, execute the following command

```powershell
Octopus.Server.exe admin --username USERNAME --email EMAIL
```
The most important part of this command is the email, as usernames are not necessarily included in the claims from the external providers. When the user logs in the matching logic must be able to align their user record based on the email from the external provider or they will not be granted permissions.

## Next steps

Now that you're using an external identity provider, it is easy to increase your security. You could consider configuring [Multi-Factor Authentication](https://docs.microsoft.com/en-us/azure/multi-factor-authentication/multi-factor-authentication), after all, Octopus Deploy has access to your production environments!

You should also consider disabling any authentication providers you aren't using, like username and password authentication.

## Troubleshooting

If you are having difficulty configuring Octopus to authenticate with Microsoft Entra ID, check your [server logs](/docs/support/log-files) for warnings.

### Triple-check your configuration

Unfortunately, the security-related configuration is sensitive to everything. Make sure:

- You don't have any typos or copy-paste errors.
- Remember, things are case-sensitive.
- Remember to remove or add slash characters.

### Check the OpenID Connect metadata is working

You can see the OpenID Connect metadata by going to the Issuer address in your browser and adding `/.well-known/openid-configuration` to the end. In our example, this would be something like `https://login.microsoftonline.com/b91ebf6a-84be-4c6f-97f3-32a1d0a11c8a/.well-known/openid-configuration`.

### Inspect the contents of the security token

:::div{.hint}
When using OAuth code flow with PKCE, the JWT token will not be visible to the end user. To use this debugging method, please remove the client secret and ensure that your configuration lines up with the pre-PKCE method, [detailed above](/docs/security/authentication/azure-ad-authentication#enable-id-tokens-and-configure).
:::

Sometimes the contents of the security token sent back by Microsoft Entra ID aren't exactly what Octopus expects; certain claims might be missing or named differently. This will usually result in the Microsoft Entra ID user incorrectly mapping to a different Octopus user than expected. The best way to diagnose this is to inspect the JSON Web Token (JWT), which is sent from Microsoft Entra ID to Octopus via your browser. To inspect the contents of your security token:

1. Open your browser's Developer Tools and enable Network logging, making sure the network logging is preserved across requests.
2. In Chrome Dev Tools, this is called "Preserve Log".

:::figure
![Preserve Logs](/docs/img/security/authentication/images/5866122.png)
:::

3. Attempt to sign into Octopus using Microsoft Entra ID and find the HTTP POST coming back to your Octopus instance from Microsoft Entra ID on a route like `/api/users/authenticatedToken/azureAD`. You should see an **id_token** field in the HTTP POST body.
4. Grab the contents of the **id_token** field and paste that into [https://jwt.io/](https://jwt.io/), which will decode the token for you.

:::figure
![ID Token](/docs/img/security/authentication/images/5866123.png)
:::

5. Octopus uses most of the data to validate the token, but primarily uses the **sub**, **email**, and **name** claims. If these claims are not present, you will likely see unexpected behavior.

### EntraID Users with 200+ security groups

:::div{.hint}

If a user has more than 200 security groups assigned, we need to retrieve the user's security groups using the Graph API, which requires the `aio` claim to be present in the `id token` we send to the Graph API.

If this claim is missing, check the following:

- You don't have any wildcards `*` in the **Redirect URI**.
- You have enabled `ID Tokens` in the **App Registration**.

:::

### Contact Octopus Support

If you aren't able to resolve the authentication problems yourself using these troubleshooting tips, please reach out to our [support team](https://octopus.com/support) with:

1. The contents of your OpenID Connect Metadata or the link to download it (see above) can be different for each Azure AD App.
2. A copy of the decoded payload for some security tokens (see above) may work as expected, and others will not.
3. A screenshot of the Octopus User Accounts, including their username, email address, and name.
