How to authenticate to Entra ID protected APIs with a certificate—step-by-step

How to authenticate to Entra ID protected APIs with a certificate—step-by-step

Last updated on November 10, 2024

If you are looking to authenticate to an API protected by Entra ID with application permissions from an Azure solution, I recommend you read my blog post about authentication with Azure Managed Identities.

This blog post is meant to serve as one place to get all the info you need to set up certificate authentication. This scenario is vital when you want to authenticate to an API with application permissions but can’t use an Azure Managed Identity, and the API does not support using a client secret.

You may encounter such a situation if you, for example, want to call the SharePoint Online REST API with application permissions while debugging because it does not support authentication with a client secret, and you can’t use an Azure Managed Identity when debugging locally. And even if an API supported authentication with a client secret (e.g., the Microsoft Graph API), using a certificate is still recommended for production scenarios—if Azure Managed Identity can’t be used—as it is more secure than using a secret. You can also use these steps to authenticate to a custom API protected by Entra ID.

I wanted to write this article because whenever I had to set up certificate authentication, there wasn’t just one article I could look at to find all the steps that I needed to take. I want this article to be such a place, so do let me know in the comments if you notice a step missing or if you think something should be elaborated on more to make following the steps easier. Hopefully, this is also a guide you can give to your tenant admin if you don’t have the required permissions to perform all the steps yourself.

Table of contents

  1. Create the certificate
  2. Create an Entra ID application registration
  3. Store the certificate on Azure Key Vault
  4. Certificate authentication in Azure App Service
  5. Certificate authentication in Azure Logic Apps and Power Automate
  6. Afterword

Create the certificate

The first thing we need to do is to generate the required certificate files (.cer and .pfx). You can do that by running the script below. Before running the script, adjust the $commonName and $password variable values to match your scenario. The certificate files will appear in the same directory where you execute the script.

Before running the script below, you must have the PnP.PowerShell module installed. Also, if you install PnP.PowerShell version 2.0.0 or higher, you need to run the script using PowerShell 7. You can find instructions for installing PowerShell 7 on Microsoft documentation.

Create an Entra ID application registration

If you don’t yet have an existing app registration, here are the steps. If you do, you can skip this section and go to the Add the certificate to the app registration section.

  1. Go to https://portal.azure.com
  2. Click on Microsoft Entra ID on the left navigation
  3. Under Manage, click on App registrations
  4. New registration:
    • Give it a descriptive name
    • Select Accounts in this organizational directory only (Single tenant)
    • No need to specify a redirect URI

After your app has been created, note down the following information from the Overview tab; you’ll need these in your solution.

  • Application (client) ID
  • Directory (tenant) ID

Add the certificate to the app registration

In your application registration:

  1. Go to Certificates & secrets
  2. Open the Certificates tab
  3. Click Upload certificate
  4. Select the .cer file we generated with the PowerShell script, and click Add.

Configure the required API permissions

Don’t forget to configure the permissions that are required to use the desired API.

  1. On the application registration, go to API permissions.
  2. Click Add a permission.
  3. Select the API you want to use, e.g., SharePoint or Microsoft Graph. Custom APIs can be found on the My APIs tab.
  4. Select Application permissions.
  5. Tick the permissions you need. Typically, the API documentation tells you what permissions you need to perform different API operations.
  6. Click on Add permissions.
  7. And finally, you also need to click the Grant admin consent for organization button and then Yes. If you don’t have the permission to do this, you need to ask your tenant admin to hit the button for you.

When permissions have been granted successfully, the warning triangles are replaced with green checkmarks in the view.

Store the certificate on Azure Key Vault

Azure Key Vault offers a secure place to store the certificate so that our app can access it during runtime.

Enable the Azure app’s Managed Identity

Your app needs permission to get the certificate from the key vault. The best way for Azure apps is to enable the app’s managed identity and grant it the required permissions.

  1. Open the Identity blade under Settings.
  2. Change the system assigned managed identity Status to On.
  3. Click on Save and Yes when prompted
  4. Copy the Object ID that appears upon saving to, e.g., Notepad. You’ll need this later.

Create an Azure Key Vault

On Azure Portal, go to the resource group that contains your app. Then, click the button to create a new resource and search for Key Vault on the Marketplace. Then, create one with the following settings.

  1. Ensure the correct subscription and resource group are selected.
  2. Give the key vault a name according to your organization’s naming conventions.
  3. Select the region you wish to use, probably the same as what your app is using.
  4. Leave the pricing tier to Standard
  5. Consider if you wish to enable Purge protection.
  6. Proceed to the Access configuration tab and ensure Azure role-based access control (recommended) is selected.
  7. If you want, you can tag the resource.
  8. Click on Review + create

When the Key Vault resource has been provisioned, go to it.

Configure the vault permissions

You need to grant yourself permission to add the certificate to the vault before you can do so.

  1. Go to the Access control (IAM) blade
  2. Click on Add role assignment
  3. Select the Key Vault Certificates Officer permission, and click Next
  4. Click on Select members and add yourself.
  5. Click on Review + assign

You also need to grant your Azure app’s Managed Identity permissions to read the certificate from the vault.

  1. Go to the Access control (IAM) blade
  2. Click on Add role assignment
  3. Select the Key Vault Certificates User permission, and click Next
  4. Select Managed identity, click on Select members, and add your app resource.
  5. Click on Review + assign
If you are planning on using certificate authentication in a Power Automate flow, you need to grant the permissions to the service account you are using for running the flow instead. In this case, you’d choose Select members instead of Managed identity. However, using certificate authentication typically indicates that you are implementing an application for an organization and not for a single user, in which case I highly recommend considering implementing your app as an Azure Logic App instead. Azure Logic Apps can offer easier governability and cost savings because of the licensing differences. Plus, you can use the more secure Managed Identity for authenticating to the key vault, if not even for calling the API directly!

Add the certificate to the vault

  1. Navigate to the Certificates blade under Objects.
  2. Click on the Generate/Import button at the top.
  3. Select Import from the Method of Certificate Creation dropdown.
  4. Give a descriptive name for the vault object.
  5. Upload the .pfx certificate file you generated earlier.
  6. Provide the same password as what you used when generating the certificate.

To reference the certificate in your app later, you’ll need its URL.

  1. Click on the certificate you just added to the key vault.
  2. Similarly, also click on the current certificate version.
  3. Copy the Certificate Identifier (URL) to, e.g., Notepad. You can remove the version (GUID) from the end of the URL. This way, the latest version of the certificate will always be used. We’ll need this value in just a second!

Now, you can remove the permissions you added for yourself earlier, as they are no longer needed.

Certificate authentication in Azure App Service (C# .NET 8)

I’m assuming that the API you are connecting to does not support authentication with Azure Managed Identity, for if it did, you could also grant the app’s Managed Identity permissions to call the API directly.

Configure the app’s environment variables

The app needs the following three pieces of information for authentication: the tenant ID, the client ID, and the certificate. We will provide the app with this information by adding them as App settings on the Environment variables blade.

Name Value Description
TenantId The Entra ID application registration tenant ID You copied this earlier from the app registration Overview blade. This setting is needed for authentication.
ClientId The Entra ID application registration client ID You copied this earlier from the app registration Overview blade. This setting is needed for authentication.
Certificate @Microsoft.KeyVault(SecretUri=
https://yourvaultname.vault.azure.net
/certificates/yourcertname)
This is called a key vault reference. It allows our Azure app to retrieve the certificate from the vault using its Azure Managed Identity. You must paste the certificate identifier URL we copied as the SecretUri value. This setting is needed for authentication.
WEBSITE_LOAD_USER_PROFILE 1 This setting is required to ensure the app service can fetch the certificate from the key vault (needed for authentication).

C# .NET 8 code for certificate authentication

You can use the code below for certificate authentication both when running the app on Azure and when debugging locally because the code checks if a debugger is attached or not and, based on that information, directs the execution to use the correct method. If the debugger is NOT attached, it means the code is running on Azure, and the code will use the certificate that is now readily available in the app settings, thanks to the key vault reference. However, if the debugger is attached, the code will use the local certificate file path and its password that are specified on the local.user.settings file (example after the code snippet).

Here’s an example of the local variables you need for debugging.

Please note that the local.user.settings file should never be checked into version control (luckily, it is excluded by default, so do not include it!), and you should use a different certificate and application registration for debugging so you do not store the production certificate password in a text file even on your machine. Ideally, you’d have an entirely separate developer tenant for development and initial testing purposes, especially if your application uses the tenant data, e.g., via Microsoft Graph or SharePoint Online REST API.

For the code to compile, you’ll also need to add the related interface to your project.

For the code to actually work, you also need to add the service to be available via dependency injection on the Program.cs file. The file syntax can vary a bit depending on the project type, but regardless, you need to include the services.AddSingleton<IAuthService, AuthService>(); line there in one form or another. The following code snippet is for an Azure Function App.

Certificate authentication in Azure Logic Apps and Power Automate

Before you begin these configurations, ensure you’ve granted your Azure Logic App or Power Automate flow service account permissions to read the certificate from the vault as described in the Configure the vault permissions section.

Fetch the certificate with the Get secret action

As the first thing, we want to get the certificate in its base64 format from the Azure Key Vault we created and configured earlier. We can do this with the Get secret action found under Azure Key Vault.

Before we configure the action itself, we need to form the connection to the key vault. For Azure Logic Apps, we should use its Managed identity for authenticating to the vault, which you should have already enabled as instructed in the Enable the Azure app’s Managed Identity section. For Power Automate, you should choose Default Microsoft Entra ID application for OAuth as the Authentication Type; otherwise, the parameters are the same.

As I mentioned before, using certificate authentication typically indicates that you are implementing an application for an organization and not for a single user, in which case I highly recommend considering implementing your app as an Azure Logic App instead of Power Automate. Azure Logic Apps can offer easier governability and cost savings because of the licensing differences. Plus, you can use the more secure Managed Identity for authenticating to the key vault, if not even for calling the API directly!

If you have successfully granted the required permissions to the key vault as instructed earlier in the Configure the vault permissions section, you should now be able to select the certificate from the dropdown.

Now, because the certificate value should be kept a secret, we should go to the Settings tab and flip the Secure outputs switch to ensure the certificate value does not show up on the run logs.

Authenticate to the API in an HTTP action

After the Get secret action, you should add an HTTP action for calling the API. To be able to specify the authentication parameters, you first need to open the Advanced parameters dropdown and select Authentication. Then, as the Authentication Type, you need to select Active Directory OAuth.

In the view that opens, you need to specify the Tenant ID and Client ID, which you should have already noted down somewhere if you followed the instructions in the Create an Entra ID application registration section. I recommend that you add these values as Parameters (Type: String) so they can be easily adjusted between environments if needed. You can open the Parameters configuration panel via the button at the top of the logic app editor view. Then, reference the created parameter values in the HTTP action settings.

The Audience field requires you to insert the base URL of the API you wish to call. For example, to call the SharePoint REST API, you’d insert the tenant base URL.

As the Credential Type, you should select Certificate and after that reference the value output variable from the earlier Get secret action. That’s it! There’s no need to add the certificate password here because it was already previously supplied when the certificate was added to the vault.

Afterword

I hope you enjoyed reading this article and found it helpful. As I mentioned in the beginning, I want this post to serve as a place to get all the info you need to set up certificate authentication. Let me know if you notice a step missing or if you feel like something should be elaborated on more!

If you’d like to subscribe to my blog to get notified when I publish something new or follow me on social media, you can find buttons for those in the sidebar or at the bottom for mobile.

Thank you for reading; it is much appreciated, as always. Until next time!

Laura



38 thoughts on “How to authenticate to Entra ID protected APIs with a certificate—step-by-step”

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.