Configure federated identity between GitHub and Azure with PowerShell

omiossec

Olivier Miossec

Posted on April 4, 2024

Configure federated identity between GitHub and Azure with PowerShell

Usually, when you want to connect a GitHub workflow to Azure, in order to manage resources, you use an Entra ID application (Azure AD). The main problem with using an App is that you need to manage a secret or a certificate. Most of the time people use a secret, it needs to be stored as a secret in GitHub, and it transits through the Internet when connecting to Azure.
But if instead of using a secret you can use a federated identity credential. It is a trust relationship between two entities, one entity can request a token and use this token to authenticate to Azure. In this case, no secret is exchanged.
Federated identity works with an Entra ID app or a user-managed identity (but not with a system-managed identity). In the following example, I will use a user-managed identity.

The first step is to create a user-managed identity in a resource group

$managedIdentity = New-AzUserAssignedIdentity -Name mi-test -ResourceGroupName managed-identity -Location northeurope 
Enter fullscreen mode Exit fullscreen mode

This instruction creates the identity name mi-test in the North Europe Azure region in the resource group name managed-identity.
Now we can create the federated credential to be used in GitHub.
You will need several pieces of information:

  • The organization, your account name for individual users, or your GitHub organization name.
  • The repository name.
  • Which entity to use, GitHub you can use:
    • The environment is an entity in GitHub where you can store secrets, environment variables, and other configuration settings.
    • Branch, the identity will be used when a workflow runs on this branch.
    • Pull Request, the identity will be used with each pull request.
    • Tag, the identity will be used when the tag is used.

For this example, I will use environment, as is simpler to understand.
In a GitHub repo, go to settings and then environment. Create a new environment, for this example, I will use devTo-test.
To create the federated credential for the newly managed identity we need, at least, two things, an issuer (who requests the identity), for GitHub it is https://token.actions.githubusercontent.com, and a subject. The subject is a URI starting with “repo” and with all the information needed, organization, repository name, ... everything separated by a :

$repoName = "devtoDemo"
$githubOrga = "myOraName"
$environmentName = "devTo-test"

$subjectUri =  "repo:$($githubOrga)/$($repoName):environment:$($environmentName)"
Enter fullscreen mode Exit fullscreen mode

Now we can create the federated credential.

New-AzFederatedIdentityCredentials -ResourceGroupName managed-identity -IdentityName mi-test -Name $managedIdentity.name -Issuer "https://token.actions.githubusercontent.com" -Subject $subjectUri
Enter fullscreen mode Exit fullscreen mode

Now we can configure a workflow in the GitHub repository. To allow a workflow to connect to Azure with the federated identity you need to configure a workflow. In the YAMl file defining the workflow, you need to indicate which environment you use.
You can do it when you configure a job.

jobs:

  test-identity:
    name: run azure workflow
    runs-on: ubuntu-latest
    environment: devTo-test
Enter fullscreen mode Exit fullscreen mode

Then when you need to log in to Azure you just need to use the azure/login step without needing to add a secret or anything else. You just need to indicate the tenant ID and the client-id of the managed identity (you can get it with $managedIdentity.PrincipalId.

      - name: Login to Azure
        uses: azure/login@v1
        with:
          client-id: principal ID
          tenant-id: Tenant ID
          subscription-id:  Target Subscription ID 
          enable-AzPSSession: true
Enter fullscreen mode Exit fullscreen mode

Nothing else is needed, no secret or certificate. The best practice is to get the client ID, Tenant ID, and Subscription ID as a secret from the environment.

      - name: Login to Azure
        uses: azure/login@v1
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id:  ${{ secrets.AZURE_SUBSCRIPTION_ID }}
          enable-AzPSSession: true
Enter fullscreen mode Exit fullscreen mode

When you do not need the federate credential, you can run

remove-AzFederatedIdentityCredentials -ResourceGroupName managed-identity -IdentityName mi-test -Name fic-test
Enter fullscreen mode Exit fullscreen mode
💖 💪 🙅 🚩
omiossec
Olivier Miossec

Posted on April 4, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related