Skip to main content

Github Actions Using Azure Login OIDC and MgGraph or Entra powershell

·617 words·3 mins
Table of Contents

TL:DR;
#

If you are using a federated identity for Github workflows to run the MgGraph or Entra powershell modules, you need to extract the token generated from Azure/Login in order to connect:

$token = (Get-AzAccessToken -ResourceTypeName MSGraph -AsSecureString -ErrorAction Stop).token
$null = Connect-Entra -AccessToken $token -ErrorAction Stop

Credit for the solution goes to Ondrej Sebela.

Problem
#

I hate managing secrets or certificates with Azure service principals. If you use Entra service principals for Github Actions, you should be configuring them to use a federated identity. You never have to touch a secret or certificate again, so it’s easier and more secure.

For those who are unfamiliar, configuring a federated identity essentially allows you to use the Azure/Login action using only your application and tenant ids, and as long as the action is running from the Github repo you configured, the workflow is now authenticated and can use the permissions associated with your service principal. It’s neat, easy and clean. We use these for almost everything, and the Azure Login action allows you to use either Azure/CLI or Azure/Powershell if you are writing workflows for automation.

Here is where I ran into my issue. I am authenticated using a federated identity with Azure/Login, and I want to run an Azure/Powershell step. If enable-AzPSSession: true is set on Azure/Login then this just works, as long as you are using any of the Az powershell modules. My problem is, I needed to use the Entra Powershell Module, which is basically just a wrapper for the MgGraph Powershell Module.

Problem: I could not get Connect-Entra or Connect-MgGraph to work with any of the available configurations from their docs using the federated identity from the Azure/Login step. It seems like it wasn’t going to work unless I created a certificate or secret for the service principal to use.

Solution
#

I tried every configuration specified in the documentation for Connect-Entra and nothing worked. I asked my co-workers if they had encountered this issue and they said they dealt with it by creating a Secret for the SP and using that instead. I wasn’t going to do that (see “I hate managing secrets or certificates” above).

Instead I dug into the Azure/Login action more closely to see if I could figure out how it was working so I could engineer it. You can see in the docs for that step that under the powershell section it only lists one command as an example: Get-AzContext. This means that the Az modules can and should work, and I ran that command from the workflow to validate.

I decided to do some research to see if I could use the authentication from that module for the Entra powershell instead, which led me to Ondrej Sebela’s blog post. Credit to him for the answer, though wrapping it in a custom function seems a little heavy handed. You can use just use one line to extract the token and use it:

$token = (Get-AzAccessToken -ResourceTypeName MSGraph -AsSecureString -ErrorAction Stop).token
$null = Connect-Entra -AccessToken $token -ErrorAction Stop

As a sample, here is the full job of the workflow:

jobs:
  powershell:
    name: Run My Script
    environment: auth-environment
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write
    steps:
      - name: Checkout Workflow/Actions Repo
        uses: actions/checkout@v4

      - name: Log in to Azure using OIDC
        uses: azure/login@v2
        with:
          client-id: ${{ env.ARM_CLIENT_ID }}
          tenant-id: ${{ env.ARM_TENANT_ID }}
          allow-no-subscriptions: true
          enable-AzPSSession: true
          
      - name: Install Powershell Module
        uses: azure/powershell@v2
        with:
          inlineScript: |
            Install-Module -Name Microsoft.Entra -Repository PSGallery -Scope CurrentUser -Force -AllowClobber            
          azPSVersion: "latest"

      - name: Run My Script
        uses: azure/powershell@v2
        with:
          inlineScript: |
            $token = (Get-AzAccessToken -ResourceTypeName MSGraph -AsSecureString -ErrorAction Stop).token
            $null = Connect-Entra -AccessToken $token -ErrorAction Stop

            . scripts/Run-MyScript.ps1

            Run-MyScript >> $env:GITHUB_STEP_SUMMARY            
          azPSVersion: "latest"

Related

Bulk assign devices to iOS Enrollment Profiles in Intune
·869 words·5 mins
TL;DR # This script can be used to do two things: get your iOS Enrollment Tokens and Profiles from your Intune tenant, and assign a list of devices to profiles using a csv input file.
Git Basics
·2169 words·11 mins
I will admit up front, there is a bit of imposter syndrome that comes with posting this, as I do not consider myself an expert in using git by any means.
Intune RBAC - How Intune Processes Multiple Assigned Roles
·1356 words·7 mins
TL;DR # Jump to the How Intune Evaluates Permissions from Multiple Roles section, and then review the Visualizing Multiple RBAC Assignments for a quick synopsis of the issue.