DEV Community

Olivier Miossec
Olivier Miossec

Posted on

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

Top comments (0)