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
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 :
$githubOrga = “myOraName”
$environmentName = “devTo-test” $subjectUri = “repo:$($githubOrga)/$($repoName):environment:$($environmentName)“
Now we can create the federated credential.
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.
test-identity:
name: run azure workflow
runs-on: ubuntu-latest
environment: devTo-test
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.
uses: azure/login@v1
with:
client-id: principal ID
tenant-id: Tenant ID
subscription-id: Target Subscription ID
enable-AzPSSession: true
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.
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
When you do not need the federate credential, you can run