Azure Citadel
  • Blogs

  • ARM
  • Azure Arc
    • Overview
    • Azure Arc-enabled Servers
      • Prereqs
      • Scenario
      • Hack Overview
      • Azure Landing Zone
      • Arc Pilot resource group
      • Azure Monitoring Agent
      • Additional policy assignments
      • Access your on prem VMs
      • Create onboarding scripts
      • Onboarding using scripts
      • Inventory
      • Monitoring
      • SSH
      • Windows Admin Center
      • Governance
      • Custom Script Extension
      • Key Vault Extension
      • Managed Identity
    • Azure Arc-enabled Kubernetes
      • Prereqs
      • Background
      • Deploy Cluster
      • Connect to Arc
      • Enable GitOps
      • Deploy Application
      • Enable Azure AD
      • Enforce Policy
      • Enable Monitoring
      • Enable Azure Defender
      • Enable Data Services
      • Enable Application Delivery
    • Useful Links
  • Azure CLI
    • Install
    • Get started
    • JMESPATH queries
    • Integrate with Bash
  • Azure Landing Zones
    • Prereqs
    • Day 1
      • Azure Baristas
      • Day 1 Challenge
    • Day 2
      • Example
      • Day 2 Challenge
    • Day 3
      • Day 3 Challenge
    • Useful Links
  • Azure Lighthouse
    • Minimal Lighthouse definition
    • Using service principals
    • Privileged Identity Management
  • Azure Policy
    • Azure Policy Basics
      • Policy Basics in the Azure Portal
      • Creating Policy via the CLI
      • Deploy If Not Exists
      • Management Groups and Initiatives
    • Creating Custom Policies
      • Customer scenario
      • Policy Aliases
      • Determine the logic
      • Create the custom policy
      • Define, assign and test
  • Azure Stack HCI
    • Overview
    • Useful Links
    • Updates from Microsoft Ignite 2022
  • Marketplace
    • Introduction
      • Terminology
      • Offer Types
    • Partner Center
    • Offer Type
    • Publish a VM Offer HOL
      • Getting Started
      • Create VM Image
      • Test VM Image
      • VM Offer with SIG
      • VM Offer with SAS
      • Publish Offer
    • Other VM Resources
    • Publish a Solution Template HOL
      • Getting Started
      • Create ARM Template
      • Validate ARM Template
      • Create UI Definition
      • Package Assets
      • Publish Offer
    • Publish a Managed App HOL
      • Getting Started
      • Create ARM Template
      • Validate ARM Template
      • Create UI Definition
      • Package Assets
      • Publish Offer
    • Managed Apps with AKS HOL
    • Other Managed App Resources
    • SaaS Offer HOLs
    • SaaS Offer Video Series
      • Video 1 - SaaS Offer Overview
      • Video 2 - Purchasing a SaaS Offer
      • Video 3 - Purchasing a Private SaaS Plan
      • Video 4 - Publishing a SaaS Offer
      • Video 5 - Publishing a Private SaaS Plan
      • Video 6 - SaaS Offer Technical Overview
      • Video 7 - Azure AD Application Registrations
      • Video 8 - Using the SaaS Offer REST Fulfillment API
      • Video 9 - The SaaS Client Library for .NET
      • Video 10 - Building a Simple SaaS Landing Page in .NET
      • Video 11 - Building a Simple SaaS Publisher Portal in .NET
      • Video 12 - SaaS Webhook Overview
      • Video 13 - Implementing a Simple SaaS Webhook in .NET
      • Video 14 - Securing a Simple SaaS Webhook in .NET
      • Video 15 - SaaS Metered Billing Overview
      • Video 16 - The SaaS Metered Billing API with REST
  • Microsoft Fabric
    • Theory
    • Prereqs
    • Fabric Capacity
    • Set up a Remote State
    • Create a repo from a GitHub template
    • Configure an app reg for development
    • Initial Terraform workflow
    • Expanding your config
    • Configure a workload identity
    • GitHub Actions for Microsoft Fabric
    • GitLab pipeline for Microsoft Fabric
  • Packer & Ansible
    • Packer
    • Ansible
    • Dynamic Inventories
    • Playbooks & Roles
    • Custom Roles
    • Shared Image Gallery
  • Partner Admin Link
    • Understanding PAL
    • User IDs & PAL
    • Service Principals & PAL
    • CI/CD Pipelines & PAL
    • Azure Lighthouse & PAL
    • PAL FAQ
  • REST API
    • REST API theory
    • Using az rest
  • Setup
  • Terraform
    • Fundamentals
      • Initialise
      • Format
      • Validate
      • Plan
      • Apply
      • Adding resources
      • Locals and outputs
      • Managing state
      • Importing resources
      • Destroy
    • Working Environments for Terraform
      • Cloud Shell
      • macOS
      • Windows with PowerShell
      • Windows with Ubuntu in WSL2
    • Using AzAPI
      • Using the REST API
      • azapi_resource
      • Removing azapi_resource
      • azapi_update_resource
      • Data sources and outputs
      • Removing azapi_update_resource
  • Virtual Machines
    • Azure Bastion with native tools & AAD
    • Managed Identities

  • About
  • Archive
  1. Home
  2. Partner Admin Link
  3. CI/CD Pipelines & PAL

Table of Contents

  • Introduction
    • Check the subject in the federated credential
    • Create and run a workflow
  • Next

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
    • Check the subject in the federated credential
    • Create and run a workflow
  • Next

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.)

  1. Open the Entra admin portal

  2. Open Entra ID > App Registrations

  3. 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.

  4. Click on Certificates and secrets to view the federated credential’s Subject identifier or claims matching expression

    App registration’s federated credential for a GitHub repo’s main branch

    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.

If your service principal is set with a client secret then you can skip the step checking the federated credential. Customise the workflow to match Azure/login’s service principal secret guidance.

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.

  1. Create a new branch, e.g. pal

  2. Create a new workflow, e.g. .github/workflows/pal.yml

  3. 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 to secrets 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.

  4. Commit and push the new branch

  5. Create a pull request and merge to the main branch

  6. Click on Actions

  7. Select the workflow

  8. Click on Run workflow

Next

Source: https://www.azurecitadel.com/pal/cicd/
Published: 10 Oct 2025
Printed:
Service Principals & PAL CI/CD Pipelines & PAL Azure Lighthouse & PAL