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
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)"
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
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
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
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
When you do not need the federate credential, you can run
remove-AzFederatedIdentityCredentials -ResourceGroupName managed-identity -IdentityName mi-test -Name fic-test
Top comments (0)