GitHub actions and Azure without secrets
It is possible to have pipelines authenticating without secrets, I described in general in [../pipelines-without-secrets]. Now let’s have a look on how we actually do this. Here are the necessary steps to have a GitHub workflow deploying to Azure resources without any secrets.
We will need:
- An Entra Application configured with Federated Identity for GitHub
- GitHub workflow with necessary steps to authenticate to Azure
It is worth a consideration if you can just use one app for everything, and hereby using the same privileges as they are assigned to the app. Eg. to have different privileges for production with different subscriptions, clusters, etc. it might be worth creating multiple apps and configure accordingly.
In the following there will just be one app, but you can of course just do it several times with different app names, ids, environment names, etc.
GitHub token subject
When integrating with Azure Federated Identity, the allowed subjects are listed. Subject is embedded in the JWT from GitHub with the following rule1:
- For any deployments to environments (defined in the GitHub workflows), the subject will be
repo:<Organization/epository>:environment:<Name>
- For jobs without an environment the Subject will be based on the branch:
repo:<Organization/Repository>:ref:<ref path>
- For Pull Request the subject will be:
repo:<Organization/Repository>:pull_request
I tend to stay with the environment approach, so for building feature branches, a pseudo environment eg. “aks-build” can be used to allow all branches to authenticate with Azure.
If considering multiple applications with different privileges, this is also the place where you can ensure that only deployments to production can have access to the production resources etc.
It is also worth noting, that to be able to access this JWT, we need to provide that as a permission in the GitHub workflow specification (the yaml file):
|
|
Create Entra Application
I will here use Powershell and Azure CLI to create the Entra Application, I find it is the easiest way to reuse it, but this can all be done through the portal also. It only have to be done once.
For using the Azure CLI you need to be authenticated prior by running az login
I highly recommend to ensure the context is set properly, especially when using multiple clients and tenants. One way is by specifying the exact subscription by running az account set --subscription $subscriptionId
|
|
The client id and tenant id is needed for the actual authentication and those are not secrets as such.
Next step is to create the Federated Identity for the branches/environments that should authenticate. I will define those as powershell variables:
|
|
And then create the federated identity (if it is missing):
|
|
Now you should be able to find the app in Azure Portal within App registrations:
Assign required permissions
For the actual permissions, the service principal is assigned to the relevant resources. Example here is assigned Contributor role to a docker registry and AKS cluster, both identified by their object ids. ($assigneeObjectId
is the id of the service principal, so I am reusing the variable from when it was created)
|
|
Necessary pipeline variables
As promised, we don’t need any secrets in the GitHub workflow.However, we still need some identifiers. Here I will create the ids with the Github CLI gh
and the variables from above:
|
|
If you just have a single app, it can just be repository variables instead of being environment specific. Similar when using the branch and pull requests subjects, you would not use environment scoped variables.
The actual workflow steps
Now it is just a matter of using the variables and authenticate with the actions from Azure:
|
|
And that’s it. Hope it will help you (at least it will help me with remembering the steps.)