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"