Skip to content

Conversation

@veikkoeeva
Copy link

@veikkoeeva veikkoeeva commented Aug 4, 2024

  • 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

@veikkoeeva veikkoeeva requested a review from a team as a code owner August 4, 2024 21:06
@veikkoeeva
Copy link
Author

veikkoeeva commented Aug 4, 2024

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. :)

- **Efficient Management:** Streamlines the process of managing resource access across multiple projects and teams.


```sh
Copy link
Collaborator

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...

Copy link
Author

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"? :)

Copy link
Collaborator

@dkershaw10 dkershaw10 Aug 19, 2024

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):

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.

Copy link
Collaborator

@dkershaw10 dkershaw10 left a 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.

@veikkoeeva veikkoeeva force-pushed the workload-identity-creates-workload-identities branch from d7dc725 to 317e978 Compare August 11, 2024 14:59
@veikkoeeva veikkoeeva changed the title Create initial workload identity federation Create Workload Identity Federation that can create other workload identity federations Aug 11, 2024
@veikkoeeva
Copy link
Author

@veikkoeeva please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree

@dkershaw10 dkershaw10 added the template sample Bicep template example demonstrating use of Microsoft Graph resources label Aug 12, 2024

## 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.
Copy link
Contributor

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?

Copy link
Author

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.

Copy link
Collaborator

@dkershaw10 dkershaw10 Aug 19, 2024

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:

  1. 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).
  2. 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.
  3. 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.

@veikkoeeva veikkoeeva force-pushed the workload-identity-creates-workload-identities branch from 317e978 to 6908872 Compare August 17, 2024 09:55
…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
@veikkoeeva veikkoeeva force-pushed the workload-identity-creates-workload-identities branch from 6908872 to 5e1103b Compare August 17, 2024 10:06

## 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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.
Copy link
Collaborator

@dkershaw10 dkershaw10 Aug 19, 2024

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)
Copy link
Collaborator

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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
## 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
Copy link
Collaborator

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
Copy link
Collaborator

@dkershaw10 dkershaw10 Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// for Microsoft first part application 'Microsoft Graph', see more at
// for Microsoft first party application 'Microsoft Graph', see more at

Comment on lines +62 to +63
// 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.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// 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
Copy link
Collaborator

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]' = {
Copy link
Collaborator

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
Copy link
Collaborator

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
}
Copy link
Collaborator

@dkershaw10 dkershaw10 Aug 19, 2024

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.

Copy link
Collaborator

@dkershaw10 dkershaw10 left a 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).

@veikkoeeva
Copy link
Author

veikkoeeva commented Aug 19, 2024

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

template sample Bicep template example demonstrating use of Microsoft Graph resources

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Looks like not possible to deploy workload identity with role microsoft.directory/applications/create in Bicep

3 participants