CI/CD Pipelines & PAL
Workload identities securely using OpenID Connect are becoming the prevailing standard. As they don't have client secrets then using a dedicated workflow is another approach to create a 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.
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
vars
tosecrets
if 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