-
Notifications
You must be signed in to change notification settings - Fork 12
Create Workload Identity Federation that can create other workload identity federations #160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
|
This is a work-in-progress. Policy prevents merging luckily. I get both the policy and rest of the code and see how to improve the commit header and text later. :) |
quickstart-templates/workload-identity-creates-workload-identities/README.md
Show resolved
Hide resolved
quickstart-templates/workload-identity-creates-workload-identities/main.bicep
Outdated
Show resolved
Hide resolved
quickstart-templates/workload-identity-creates-workload-identities/main.bicep
Outdated
Show resolved
Hide resolved
quickstart-templates/workload-identity-creates-workload-identities/README.md
Outdated
Show resolved
Hide resolved
| - **Efficient Management:** Streamlines the process of managing resource access across multiple projects and teams. | ||
|
|
||
|
|
||
| ```sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should start adding a table with least privileged permissions required to run the template for both delegated and app-only modes - showing permissions required to deploy both the ARM resources and the Graph/Entra resources declared in the template.
This could be part of a readme "template" we provide for all such samples...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where could I find this template? Also, how can one systematically ensure the minimum privileges without just blindly trying or "happening to know"? :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This template doesn't exist :(
To run the Bicep template that creates the "creator workload identity app", the user would need (I think, but please verify):
- Entra RBAC permissions: Application Administrator and Privileged Role Administrator
- Azure RBAC permissions: Role-based access control administrator
The Entra permissions are extremely privileged, especially the 2nd one. I would advise either that this permissions are temporarily assigned for the purpose of just running the bootstrap Bicep template, or are assigned via Privileged Identity Management (if the tenant has Entra licenses/subscriptions for this).
This Bicep template itself needs to assign permissions to the creator workload identity (to create other apps, to create managed identities and assign Azure roles) and you can describe those in the template's comments.
quickstart-templates/workload-identity-creates-workload-identities/main.bicep
Outdated
Show resolved
Hide resolved
quickstart-templates/workload-identity-creates-workload-identities/main.bicep
Outdated
Show resolved
Hide resolved
quickstart-templates/workload-identity-creates-workload-identities/main.bicep
Outdated
Show resolved
Hide resolved
quickstart-templates/workload-identity-creates-workload-identities/main.bicep
Show resolved
Hide resolved
quickstart-templates/workload-identity-creates-workload-identities/main.bicep
Show resolved
Hide resolved
dkershaw10
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a few comments and thoughts.
You may need to reference some other documentation too, on configuring GitHub actions.
d7dc725 to
317e978
Compare
@microsoft-github-policy-service agree |
quickstart-templates/workload-identity-creates-workload-identities/README.md
Outdated
Show resolved
Hide resolved
|
|
||
| ## Example scenario | ||
|
|
||
| A high-privilege user creates an initial, bootstrap workload identity federation token between Azure and a certain GitHub repository. The workload in this repository is then allowed to access Microsoft Entra to create further workload identity federation tokens and assign them to other repositories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this mean a user that is a member of a privileged role or a user that has consented to a high privilege permission?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Either works? Actually, now that I think of this and your previous question, it's probably worth being more accurate and use the correct terms etc. Can you help with that? How could I phrase this part?
F.ex. while I deployed to root structures I ran az role assignment list --scope "/" --query "[?roleDefinitionName=='User Access Administrator'].{Username:principalName, ObjectId:objectId}" --output table returned my user name. Consequently I started to think that OK, I probably need to set up some small things to set up more from a GitHub and then delegate further to smaller privileged GitHub actions further things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think there are multiple things going on here, that probably need more explanation in the usage sections and maybe in the template comments. At this point you probably just need something high level.
The multiple things I'm thinking are:
- Delegated perms to create the "creator" workload identity (part 1): Just to "start" the picture, although this is somewhat transparent for most users. For delegated permissions, the calling application must also have the necessary privileges. In this case, Azure PS or Azure CLI has been pre-authorized with those permissions. They're also pre-authorized for full delegated access to ARM - so that both these apps are delegated to access ARM APIs as the signed-in user (they have whatever privileges the signed in user has).
- Delegated perms to create the "creator" workload identity (part 2): This is the high-privileged user that you mention. They need to have the privileges:
- to create apps/service principals (i.e. create the creator workload identity) AND to grant that workload identity the permissions it needs to create other "repo" workload identities. These privileges are normally assigned to users through Entra RBAC roles.
- if the repo workload identities (that are created via the creator workload identity) need access to Azure resources, then the creator workload identity needs to be assigned the privileges that allows it to create managed identities (for FIC) and assign (scoped) Azure roles to repo workload identities. My assumption here is that this signed-in user's (privileged Azure RBAC permissions/roles) are scoped to an Azure resource group, which allow them to assign the necessary Azure permissions/roles to the creator workload identity.
- Permissions in GitHub and GitHub actions: I think you allude to this in your last sentence. This is about how the workload identities' access is scoped in GitHub. I have less familiarity with this and not sure if there is any repo hierarchy, but I could imagine that the creator workload identity is scoped to an organization, which would allow it to create workload identities scoped to all repos in the organization. Or maybe the creator is scoped to a single repo, and that's the only place if can create GitHub actions. However, like I say, you probably have a better idea on this than me.
quickstart-templates/workload-identity-creates-workload-identities/README.md
Outdated
Show resolved
Hide resolved
317e978 to
6908872
Compare
…entity federations - Establish an initial workload identity federation token between Azure and a specific GitHub repository using a high-privilege user. - Enable workloads in the repository to access Microsoft Entra for creating additional workload identity federation tokens. New created federated workload identity tokens can be assigned to other repositories, reducing the need for high-privilege access. This enhances security by limiting the usage of high-privilege credentials and providing scalable identity management. Closes microsoftgraph#154
6908872 to
5e1103b
Compare
|
|
||
| ## The Idea | ||
|
|
||
| Create federated identity credentials (FIC) at appropriate scopes and controls to deploy company and project specific resource. The process is rooted in a Git pull request review process in order to introduce checkpoints, audit trail and repeatability to process. This should restrict the need for manual work requiring high privileges. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Create federated identity credentials (FIC) at appropriate scopes and controls to deploy company and project specific resource. The process is rooted in a Git pull request review process in order to introduce checkpoints, audit trail and repeatability to process. This should restrict the need for manual work requiring high privileges. | |
| Create federated identity credentials (FIC) at appropriate scopes and controls to automate deployment of company and project specific resources. The process use Git pull request reviews to introduce checkpoints, audit trail and repeatability. This should remove the need for manual work requiring high privileges. |
|
|
||
| ## Example scenario | ||
|
|
||
| A high-privilege user creates an initial, bootstrap workload identity federation token between Azure and a certain GitHub repository. The workload in this repository is then allowed to access Microsoft Entra to create further workload identity federation tokens and assign them to other repositories. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would remove the work "token" in this sentence - so instead: "A high-privileged user creates an initial, bootstrap workload identity federation between Azure and a certain GitHub repository."
| gh auth login | ||
|
|
||
| # Deploy the Bicep template and capture the output as JSON. | ||
| deploymentOutput=$(az deployment tenant create --name bootstrap --location WestEurope --template-file ./main.bicep --parameters ./main.bicepparam --output json) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be more scoped to create the creator app scoped to a resource group (this is more about scoping the Azure access - Entra/Graph don't know anything about Azure scoping like resource groups or subscriptions)?
Or do we think each developer that is creating their project workload identities will do so under their own resource group scope?
| - **Scalability:** Facilitates the growth of projects by enabling the creation of new identity federations as needed. | ||
| - **Efficient Management:** Streamlines the process of managing resource access across multiple projects and teams. | ||
|
|
||
| ## Usage could look something like this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| ## Usage could look something like this | |
| ## To bootstrap the Creator workload identity, run the following scripts in CLI or PS |
| @@ -0,0 +1,70 @@ | |||
| # Create Workload Identity Federation that can create other workload identity federations | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder whether to fully round out the scenario, that we should provide another Bicep template - i.e an example template that is created by and checked-in by project developers, picked up by the CI/CD pipeline and deployed via the privileged Creator workload identity.:
folder structure:
workload-identity-creates-workload-identities
- README.md
- Creator-workload-identity
- bicepconfig.json
- main.bicep
- main.bicepparam
- Repo-workload-identity-example
- bicepconfig.json
- main.bicep
- main.bicepparam
Thoughts?
| var microsoftEntraAudience = 'api://AzureADTokenExchange' | ||
|
|
||
| // In order for the Azure and GitHub Actions to communicate with each other, an | ||
| // application for GitHub Actions is created to Azure Entra. This application is then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // application for GitHub Actions is created to Azure Entra. This application is then | |
| // application for GitHub Actions is registered in Microsoft Entra. This application is then |
Entra is not part of Azure (any more) - yes it used to be Azure AD, but part of the rebranding was to decouple from Azure, as we are pushing Entra to be a multi-cloud offering (and not tied to Azure in any way).
|
|
||
| // In order for the Azure and GitHub Actions to communicate with each other, an | ||
| // application for GitHub Actions is created to Azure Entra. This application is then | ||
| // assigned an application role that allows it to access the Microsoft Graph API. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // assigned an application role that allows it to access the Microsoft Graph API. | |
| // configured as a workload identity via federated identity credentials creation. |
Assigning a role comes later. Here we are configuring it as a workload identity
| } | ||
|
|
||
|
|
||
| // This is the Azure service principal the GitHub Actions application is assigned to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // This is the Azure service principal the GitHub Actions application is assigned to. | |
| // This is the service principal representing the GitHub Actions application. |
|
|
||
| // The identifier '00000003-0000-0000-c000-000000000000' is a well-known identifier | ||
| // for Microsoft first part application 'Microsoft Graph', see more at | ||
| // https://learn.microsoft.com/en-us/troubleshoot/azure/entra/entra-id/governance/verify-first-party-apps-sign-in. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // https://learn.microsoft.com/en-us/troubleshoot/azure/entra/entra-id/governance/verify-first-party-apps-sign-in. | |
| // https://learn.microsoft.com/troubleshoot/azure/entra/entra-id/governance/verify-first-party-apps-sign-in#application-ids-of-commonly-used-microsoft-applications. |
Recommend using the deep link above.
|
|
||
|
|
||
| // The identifier '00000003-0000-0000-c000-000000000000' is a well-known identifier | ||
| // for Microsoft first part application 'Microsoft Graph', see more at |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // for Microsoft first part application 'Microsoft Graph', see more at | |
| // for Microsoft first party application 'Microsoft Graph', see more at |
| // This searches the used application role permission by its friendly name. There should be only one, | ||
| // so the fist one is taken to be used in the symbolic name. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // This searches the used application role permission by its friendly name. There should be only one, | |
| // so the fist one is taken to be used in the symbolic name. | |
| // This searches for a Microsoft Graph application role (appRole) by its friendly name. |
app role "value" has a uniqueness constraint, so it's guaranteed to be the only one. Bicep filter always returns an array, so we need to pick the first one. Not sure that the additional stuff adds much value here.
| // This searches the used application role permission by its friendly name. There should be only one, | ||
| // so the fist one is taken to be used in the symbolic name. | ||
| // See at https://learn.microsoft.com/en-us/graph/permissions-reference#applicationreadwriteownedby | ||
| // for the actual description. Look also at https://www.azadvertizer.net/azEntraIdAPIpermissionsAdvertizer.html?targetPermissionId=18a4783c-866b-4cc7-a460-3d5e5662c884 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your call - but I wouldn't mention the azadvertizer web app. Not that it isn't great or useful, but I don't think it adds much here, and too many comments detract from the template code.
If it's your web app and you're trying to advertise its usage, then that's different :)
|
|
||
| // Assign the GitHub Actions service principal the Application.ReadWrite.OwnedBy permission, | ||
| // which allows the service principal to be able to create and manage the applications and service principals is creates/owns. | ||
| resource symbolicname 'Microsoft.Graph/[email protected]' = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You still have symbolicname here, which I think is odd.
| // for the actual description. Look also at https://www.azadvertizer.net/azEntraIdAPIpermissionsAdvertizer.html?targetPermissionId=18a4783c-866b-4cc7-a460-3d5e5662c884 | ||
| // how one can search for permissions GUIDs. Using clear names is clearer. | ||
| // | ||
| // TODO: At the moment 'Application.ReadWrite.All' is used because there's a bug in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah - we're close here on getting the fix out.
The is going through ring deployments - we'll verify it in an early ring, but if that checks out, this should complete rollout fingers-crossed, before end of the week.
| appRoleId: appRoleDetail.id | ||
| principalId: gitHubIdentityActionsServicePrincipal.id | ||
| resourceId: microsoftGraphServicePrincipal.id | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Like I said earlier, I think this template is missing assigning Azure roles to this Creator workload identity, and more specifically the Role-based access control administrator. This role assignment should probably be scoped to a resource group or subscription.
If this isn't done, then when the Creator tries to "deploy" repo workload identity Bicep templates that specify what Azure roles the repo workload identity needs, it'll fail.
dkershaw10
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please take a look at the suggestions and thoughts.
LMK if this makes sense.
If it would be better, we could schedule a brief conversation (and see if Eric and/or Jason could attend too).
|
@dkershaw10 They make sense, but at least next week I am not able to do much about this sample. Maybe we are not in a hurry, and then it becomes possible to remove the TODO comment and refactor that part. The case here is such that I have thought it will be a human who deploys the creator and it will have priviledges to deploy things to mangement groups, subcriptions and so on. This way it would be possible for this initial, seed FIC to create e.g. a resource group to Azure, create a FIC that is allowed to operate for that resource group. This isn't shown at the moment. I have not documented the required privileges this human needs to deploy the initial FIC and repository. |
Establish an initial workload identity federation token between Azure and a specific GitHub repository using a high-privilege user.
Enable workloads in the repository to access Microsoft Entra for creating additional workload identity federation tokens.
New created federated workload identity tokens can be assigned to other repositories, reducing the need for high-privilege access. This enhances security by limiting the usage of high-privilege credentials and providing scalable identity management.
Closes #154
Microsoft Reviewers: Open in CodeFlow