CI/CD pipelines & OpenID Connect
Pipelines or workflows commonly use service principals. Authenticating these securely using OpenID Connect is recommended to avoid the use of secrets or certificates. Here we show how to use a dedicated workflow to create the Partner Admin Link.
Table of Contents
Introduction
This scenario is for when you no longer have the secret or cert for a service principal, but you do have permission to create or modify pipelines or workflows in your CI/CD platform. These commonly use service principals when interacting with Azure environments. Historically they would have the client secret stored as a pipeline secret whereas it is now increasingly common to leverage OpenID Connect (OIDC) using a federated workload credential.
Note that if you have access to the secret or certificate then you can also use the Service Principals with credentials page.
Check the subject in the federated credential
With OpenID Connect the service principal uses a federated credential to define the trust relationship to another identity provider and the context in which that is valid. This is far more secure than having a client secret that may be used for manual authentication, exactly as shown in the section above. (Removing the maintenance overhead of rotating secrets is another benefit.)
-
Open the Entra admin portal
-
Open Entra ID > App Registrations
-
Click on All applications, filter the app registrations using the displayName or appId / clientId, and select ℹ️ If you don’t know the appId then you can search the Enterprise apps for the service principal’s objectId and retrieve the appId from there.
-
Click on Certificates and secrets to view the federated credential’s Subject identifier or claims matching expression

The subject identifier for the example is repo:azurecitadel/my-terraform-workload-repo:ref:refs/heads/main, so OpenID Connect will only succeed for workflows run from this repository’s main branch. Here are the most common entity types supported for GitHub.
Entity Type Example Environment repo:azurecitadel/my-terraform-workload-repo:environment:prod Branch repo:azurecitadel/my-terraform-workload-repo:ref:refs/heads/main Pull request repo:azurecitadel/my-terraform-workload-repo:pull_request Tag repo:azurecitadel/my-terraform-workload-repo:ref:refs/tags/v1.0
After examining the federated credential, you can determine where the workflow needs to be run from to be successful.
Create and run a workflow
This step assumes you have the permissions to create, commit, and run workflows that meet the subject criteria in the federated credential.
-
Create a new branch, e.g.
pal -
Create a new workflow, e.g.
.github/workflows/pal.yml -
Add in the example YAML workflow
# Partner Admin Link using the Azure CLI with OpenID Connect name: Configure PAL using the Azure CLI on: workflow_dispatch: inputs: action: type: choice description: 'Action to perform' default: 'Create' options: - Create - Delete required: true partnerId: description: 'Partner ID' required: true permissions: id-token: write contents: read jobs: PAL: runs-on: ubuntu-latest steps: - name: Login to Azure using OIDC uses: azure/login@v2 with: tenant-id: ${{ vars.ARM_TENANT_ID }} client-id: ${{ vars.ARM_CLIENT_ID }} allow-no-subscriptions: true - name: ${{ github.event.inputs.action }} the Partner Admin Link uses: azure/cli@v2 with: azcliversion: latest inlineScript: | az extension add --name managementpartner az managementpartner ${{ github.event.inputs.action == 'Create' && 'create' || 'delete' }} --partner-id ${{ github.event.inputs.partnerId }} --output jsonc# Partner Admin Link using PowerShell with OpenID Connect name: Configure PAL using PowerShell on: workflow_dispatch: inputs: action: type: choice description: 'Action to perform' default: 'Create' options: - Create - Delete required: true partnerId: description: 'Partner ID' required: true permissions: id-token: write contents: read jobs: PAL: runs-on: ubuntu-latest steps: - name: Login to Azure using OIDC uses: azure/login@v2 with: tenant-id: ${{ vars.ARM_TENANT_ID }} client-id: ${{ vars.ARM_CLIENT_ID }} allow-no-subscriptions: true enable-AzPSSession: true - name: ${{ github.event.inputs.action }} the Partner Admin Link uses: azure/powershell@v2 with: azPSVersion: latest inlineScript: | Install-Module -Name Az.ManagementPartner -Repository PSGallery -Force ${{ github.event.inputs.action == 'Create' && 'New-AzManagementPartner' || 'Remove-AzManagementPartner' }} -PartnerId ${{ github.event.inputs.partnerId }}Check your GitHub Actions secrets and variables in your GitHub repo’s Settings > Secrets and variables section. The workflows are preconfigured for common Terraform environment variables.
- Change the prefix from
varstosecretsif they are defined as secrets. - Change the names if required, e.g.
AZURE_CLIENT_ID
The workflow is set for manual deployment. Feel free to change the trigger.
- Change the prefix from
-
Commit and push the new branch
-
Create a pull request and merge to the main branch
-
Click on Actions
-
Select the workflow
-
Click on Run workflow