Skip to content
Docs

Connect to Microsoft Azure

Secure backend access with OIDC federation is available on all plans

To understand how Azure supports OIDC through Workload Identity Federation, consult the Azure documentation.

    • Navigate to All services
    • Select Identity
    • Select Manage Identities and select Create
    • Choose your Azure Subscription, Resource Group, Region and Name
    • Go to Federated credentials and select Add Credential
    • In the Federated credential scenario field select Other
    • Enter the Issuer URL, the URL will depend on the issuer mode setting:
      • Team: https://oidc.vercel.com/[TEAM_SLUG], replacing [TEAM_SLUG] with the path from your Vercel team URL
      • Global: https://oidc.vercel.com
    • In the Subject identifier field use: owner:[TEAM_SLUG]:project[PROJECT_NAME]:environment:[preview | production | development]
    • In the Name field, use a name for your own reference such as: [Project name] - [Environment]
    • In the Audience field, you have two options:
      • Default: Enter https://vercel.com/[TEAM_SLUG], replacing [TEAM_SLUG] with your team identifier from the Vercel team URL
      • Recommended: Enter api://AzureADTokenExchange. When using this value, you must also pass a matching audience in your code. See the custom audience section below

    Azure does not allow for partial claim conditions so you must specify the Subject and Audience fields exactly. However, it is possible to create mutliple federated credentials on the same managed identity to allow for the various sub claims.

  1. In order to connect to the Azure service that you would like to use, you need to allow your Managed Identity to access it.

    For example, to use Azure CosmosDB, associate a role definition to the Managed Identity using the Azure CLI, as explained in the Azure CosmosDB documentation.

    You are now ready to connect to your Azure service from your project's code. Review the example below.

By default, the OIDC token's aud claim is set to https://vercel.com/[TEAM_SLUG]. Azure recommends using api://AzureADTokenExchange as the audience for workload identity federation. To use this value, pass the audience option to getVercelOidcToken:

import { getVercelOidcToken } from '@vercel/oidc';
 
const token = await getVercelOidcToken({
  audience: 'api://AzureADTokenExchange',
});

When using a custom audience, set the Audience field in your federated credential to the same value (api://AzureADTokenExchange).

In the following example, you create a Vercel function in a Vercel project where you have defined Azure account environment variables. The function will connect to Azure using OIDC and use a specific resource that you have allowed the Managed Identity to access.

Install the following packages:

Terminal
pnpm i @azure/identity @azure/cosmos @vercel/oidc
Terminal
yarn add @azure/identity @azure/cosmos @vercel/oidc
Terminal
npm i @azure/identity @azure/cosmos @vercel/oidc
Terminal
bun add @azure/identity @azure/cosmos @vercel/oidc

In the API route for this function, use the following code to perform a database SELECT query from an Azure CosmosDB instance:

/api/azure-cosmosdb/route.ts
import {
  ClientAssertionCredential,
  AuthenticationRequiredError,
} from '@azure/identity';
import * as cosmos from '@azure/cosmos';
import { getVercelOidcToken } from '@vercel/oidc';
 
/**
 * The Azure Active Directory tenant (directory) ID.
 * Added to environment variables
 */
const AZURE_TENANT_ID = process.env.AZURE_TENANT_ID!;
 
/**
 * The client (application) ID of an App Registration in the tenant.
 * Added to environment variables
 */
const AZURE_CLIENT_ID = process.env.AZURE_CLIENT_ID!;
const COSMOS_DB_ENDPOINT = process.env.COSMOS_DB_ENDPOINT!;
const COSMOS_DB_ID = process.env.COSMOS_DB_ID!;
const COSMOS_DB_CONTAINER_ID = process.env.COSMOS_DB_CONTAINER_ID!;
 
const tokenCredentials = new ClientAssertionCredential(
  AZURE_TENANT_ID,
  AZURE_CLIENT_ID,
  getVercelOidcToken,
);
 
const cosmosClient = new cosmos.CosmosClient({
  endpoint: COSMOS_DB_ENDPOINT,
  aadCredentials: tokenCredentials,
});
 
const container = cosmosClient
  .database(COSMOS_DB_ID)
  .container(COSMOS_DB_CONTAINER_ID);
 
export async function GET() {
  const { resources } = await container.items
    .query('SELECT * FROM my_table')
    .fetchAll();
 
  return Response.json(resources);
}

This example uses Azure's recommended api://AzureADTokenExchange audience:

/api/azure-cosmosdb/route.ts
import {
  ClientAssertionCredential,
  AuthenticationRequiredError,
} from '@azure/identity';
import * as cosmos from '@azure/cosmos';
import { getVercelOidcToken } from '@vercel/oidc';
 
const AZURE_TENANT_ID = process.env.AZURE_TENANT_ID!;
const AZURE_CLIENT_ID = process.env.AZURE_CLIENT_ID!;
const COSMOS_DB_ENDPOINT = process.env.COSMOS_DB_ENDPOINT!;
const COSMOS_DB_ID = process.env.COSMOS_DB_ID!;
const COSMOS_DB_CONTAINER_ID = process.env.COSMOS_DB_CONTAINER_ID!;
 
const tokenCredentials = new ClientAssertionCredential(
  AZURE_TENANT_ID,
  AZURE_CLIENT_ID,
  () => getVercelOidcToken({ audience: 'api://AzureADTokenExchange' }),
);
 
const cosmosClient = new cosmos.CosmosClient({
  endpoint: COSMOS_DB_ENDPOINT,
  aadCredentials: tokenCredentials,
});
 
const container = cosmosClient
  .database(COSMOS_DB_ID)
  .container(COSMOS_DB_CONTAINER_ID);
 
export async function GET() {
  const { resources } = await container.items
    .query('SELECT * FROM my_table')
    .fetchAll();
 
  return Response.json(resources);
}
Last updated August 11, 2026

Was this helpful?

supported.