Azure Service Principal

Prerequisites

Overview

Dynamic Secrets are a powerful way to improve the auditability and security of your secrets.

Typically, when an Azure Service Principal client secret is created, it is used across services with no enforced expiration or revocation policy. This allows credentials to accumulate and sprawl.

By adopting a dynamic secrets pattern with Azure Service Principals, each lease provisions a new, unique client secret on the target application with a mandatory TTL. When the lease expires, Doppler automatically revokes the client secret. No manual rotation or cleanup is required.

Requirements

Dynamic Secret Integration

  • A Service Principal that Doppler uses to create and revoke client secrets on the target application. This Service Principal must have one of the following Microsoft Graph API application permissions:
    • Application.ReadWrite.All, or
    • Application.ReadWrite.OwnedBy (the Service Principal must be an owner of the target application)
  • Admin consent must be granted for the selected permission

Dynamic Secret Configuration

  • The Object ID of the target application (app registration) whose client secrets will be dynamically provisioned

Configuration

Configure the Managing Service Principal

The managing Service Principal authenticates with the Microsoft Graph API on behalf of Doppler. If you already have a Service Principal configured for Doppler (e.g., for rotated secrets), you can reuse it.

  1. In the Azure Portal, navigate to App registrations
  2. Select an existing app registration or create a new one to serve as the managing Service Principal
  3. Under API permissions, add one of the following Application permissions:
    • Microsoft Graph > Application.ReadWrite.All, or
    • Microsoft Graph > Application.ReadWrite.OwnedBy if the managing SP is an owner of the target application
  4. Grant admin consent for the permission
  5. Navigate to Certificates & secrets and create a new client secret for the managing SP. Save the Client Secret value — you will need it when creating the Doppler integration
  6. From the managing SP's Overview page, note the Application (Client) ID and Directory (Tenant) ID

Make the Managing SP an Owner (if using OwnedBy)

If using the Application.ReadWrite.OwnedBy permission, the managing Service Principal must be an owner of the target application.

🚧

The Azure Portal's Owners UI only supports adding users, not service principals. You must use the Azure CLI to add a Service Principal as an owner.

Using the Azure CLI:

  1. Get the Object ID of the managing Service Principal:

    az ad sp show --id <managing-sp-client-id> --query id -o tsv
  2. Add the managing Service Principal as an owner of the target application:

    az ad app owner add --id <target-app-object-id> --owner-object-id <managing-sp-object-id>
  3. Verify the owner was added:

    az ad app owner list --id <target-app-object-id> --query "[].{displayName:displayName, id:id}" -o table
📘

If the managing SP and target application are the same (self-management), use the same application's Client ID and Object ID in the commands above.

Create the Dynamic Secret in Doppler

  1. Navigate to the config that you want to add the dynamic secret to
  2. In the Dynamic Secrets section, click Add Dynamic Secret
  3. Select Azure Service Principal as the integration type
  4. If you've previously created an integration you'd like to reuse, select it. Otherwise, select Create New Connection
  5. Name the integration and provide the managing Service Principal credentials:
    • Client ID: the Application (Client) ID of the managing SP
    • Client Secret: the client secret value of the managing SP
    • Tenant ID: the Directory (Tenant) ID
  6. Click Connect
  7. Choose the Doppler project and config the dynamic secret will be created in, enter the prefix name that will prepend all the credential secrets the dynamic secret will inject into the config, and provide the Target Application Object ID — the Object ID of the app registration whose credentials will be dynamically provisioned (found on the app's Overview page)

Usage

Leasing an Azure Service Principal client secret can be done via the CLI or API. Each time you lease, a new client secret is created on the target application, with its properties returned to you.

📘

Dynamic Secret taxonomy

In the examples below, AZURE_SP is the name of the example dynamic secret. In your setup, the prepended value will be whatever you named your dynamic secret.

CLI

Dynamic secrets are supported in the doppler secrets download and doppler run commands.

doppler secrets download --no-file | jq .
{
  "AZURE_SP_TENANT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "AZURE_SP_CLIENT_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "AZURE_SP_CLIENT_SECRET": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "AZURE_SP_LEASE_EXPIRATION": "2026-03-10T18:00:00.000Z",
  "AZURE_SP_LEASE_ID": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "DOPPLER_CONFIG": "dev",
  "DOPPLER_ENVIRONMENT": "dev",
  "DOPPLER_PROJECT": "my-project"
}

To override the default 30-minute TTL, use --dynamic-ttl:

doppler secrets download --dynamic-ttl 2h --no-file | jq .AZURE_SP_LEASE_EXPIRATION
"2026-03-10T20:00:00.000Z"

API

Leasing dynamic secrets via the API is analogous to the CLI. The /config/secrets/download and /config/secrets/ endpoints each support dynamic secrets. Set include_dynamic_secrets to true at request time. dynamic_secrets_ttl_sec is also available for overriding the 30-minute default TTL.

Injected Values

After creating the Azure Service Principal dynamic secret, three credential secrets will be available in each lease (plus the lease metadata). Each is prefixed with the name of your dynamic secret.

For example, a dynamic secret named AZURE_SP would inject:

  • AZURE_SP_TENANT_ID — the Directory (Tenant) ID
  • AZURE_SP_CLIENT_ID — the Application (Client) ID of the target app
  • AZURE_SP_CLIENT_SECRET — the dynamically provisioned client secret
  • AZURE_SP_LEASE_ID — the lease ID (use to revoke early if needed)
  • AZURE_SP_LEASE_EXPIRATION — when the lease expires and the client secret will be revoked