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
Add details on claim verification for protected branches #409
base: main
Are you sure you want to change the base?
Conversation
The Google documentation only suggests verifying the `repository_owner` claim, which is insufficient for most use cases. Adding notes from [this blog post](https://dev.to/suzukishunsuke/secure-github-actions-by-pullrequesttarget-641) to show how to use other claims to protect cloud resources from potentially malicious untrusted code. Signed-off-by: Siddarth Senthilkumar <sidsenkumar11@gmail.com>
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
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 looks great Sid! Thanks for putting it together.
|
||
You can also use the `workflow` attribute if you want to restrict access to specific workflows. | ||
|
||
### Create Attribute Conditions for Pull Requests |
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.
Suggestion: Have one more section for creating attributes based on Github Environments.
Environments are a Github Enterprise feature, so not everyone may have access, but using environments make it marginally easier to categorize branches within an attribute. For example in a github action workflow you can set an if conditional like so:
if: github.ref_protected == true && github.event_name == 'push'
Which you'll note encapsulates all protected branches (not just main). If the repo only has a single protected repository, it's equivalent to your section on Attribute Conditions for Protected Main Branch, but in your section you have to individually set attribute.ref
to the branch. Whereas if you use the sub
claim of the attribute which references a Github Environment, you can have the environment be a superset of all protected branches. And would look something like this:
attribute.sub == "repo:octo-org/octo-repo:environment:Production"
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.
One thing I'm not 100% sure about is why we need to add the if
condition to the workflow. The claim verification is done on the cloud provider's side, right? Even if random, unprotected branches triggered the workflow, they wouldn't be able to access the cloud provider's resources.
@@ -19,6 +19,66 @@ assertion.repository_owner == 'my-github-org' | |||
Never use a "*" in an IAM Binding unless you absolutely know what you are doing! | |||
|
|||
|
|||
## Set up Repository & Branch Protection | |||
|
|||
An attribute condition checking just the `repository_owner` assertion is most likely insufficient. Since your workflow may access secrets and other sensitive cloud resources, it should only be run on trusted code. Untrusted code can come from other repositories in the same organization, or even unreviewed branches in the same repository. The only code that should be trusted is code that has been reviewed and merged into a protected main branch. |
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 wrap at the column as shown elsewhere in this file.
@@ -19,6 +19,66 @@ assertion.repository_owner == 'my-github-org' | |||
Never use a "*" in an IAM Binding unless you absolutely know what you are doing! | |||
|
|||
|
|||
## Set up Repository & Branch Protection |
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.
Branch Protection is deprecated and GitHub recommends rulesets now. That being said, I don't think the auth
GitHub Action should be responsible for re-iterating GitHub security best practices.
I'm amenable to documenting "pull_request" vs "pull_request_target" things, but I don't want to become a documentation hub for GitHub repo security best practices. Perhaps we can link to GitHub documentation instead?
You can use the following mappings to provide Google with enough information to verify the GitHub OIDC token. | ||
|
||
``` | ||
attribute.repository = assertion.repository |
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.
There are many valid business reasons why you might have a single Workload Identity Pool and Provider for all repositories in an organization.
|
||
### Create Attribute Conditions for Protected Main Branch | ||
|
||
Once the GitHub assertions have been mapped to Google STS token attributes, you can create attribute conditions to verify that the caller is coming from a trusted source. For example, the following conditions verify that the GitHub OIDC token was generated after a push to the `main` branch of the `octo-org/octo-repo` repository. |
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.
Once the GitHub assertions have been mapped to Google STS token attributes, you can create attribute conditions to verify that the caller is coming from a trusted source. For example, the following conditions verify that the GitHub OIDC token was generated after a push to the `main` branch of the `octo-org/octo-repo` repository. | |
Once the GitHub assertions have been mapped to Google STS token attributes, you can create attribute conditions on any of the mapped attributes to verify that the caller is coming from a trusted source. For example, the following conditions verify that the GitHub OIDC token was generated after a push to the `main` branch of the `octo-org/octo-repo` repository. |
|
||
### Scalably Granting Access to Multiple Protected Branches | ||
|
||
As your repository grows in complexity, you might create multiple protected branches that access the same cloud resources. Manually adding protected branch names to the attribute conditions can be cumbersome and error-prone. You can simplify the attribute conditions by checking for GitHub Environment names instead of individual branch names. |
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 a business-specific organization decision that does not match how all businesses use and organize their GitHub repositories. I'm 👎 on including it.
|
||
### Create Attribute Conditions for Pull Requests | ||
|
||
You may wish to access cloud resources using a less privileged service account when code is submitted as a pull request to the repository. In this case, simply create another set of attribute conditions that allow the caller to retrieve a token to impersonate the less privileged service account. |
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 generally won't work, because GitHub doesn't inject secrets into PRs from forks (and therefore there's no OIDC token).
The Google documentation only suggests verifying the
repository_owner
claim, which is insufficient for most use cases. Adding notes from this blog post to show how to use other claims to protect cloud resources from potentially malicious untrusted code.