-
Notifications
You must be signed in to change notification settings - Fork 486
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
feat: added OIDC #262
feat: added OIDC #262
Conversation
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.
Looks great @richardhboyd ! Mostly just some some recommendations for troubleshooting 🙏
README.md
Outdated
| Field | Provided | Provided | Provided | Provided | | ||
| ----------- | :------: | :------------------------------------: | :------------------------------------: | :------------------------------------: | | ||
| aws-access-key-id | Y | Y | N | N | | ||
| role-to-assume | N | Y | Y | Y | | ||
| web-identity-token-file | N | N | Y | N | | ||
| **Identity Used** | IAM User | Assume Role using IAM User credentials | Assume Role using WebIdentity Token File credentials | Assume Role directly using GitHub OIDC provider | |
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.
nit: I find this table a bit hard to parse, but it might be just me! For some reason my brain took a while to register that i should be looking at each column separately instead of the rows 😅
What do you think of the following format?
| **Identity Used** | `aws-access-key-id` | `role-to-assume` | `web-identity-token-file` |
|-----------------------------------------------------------------|---------------------|------------------|---------------------------|
| IAM User | ✔ | | |
| Assume Role using IAM User credentials | ✔ | ✔ | |
| Assume Role using WebIdentity Token File credentials | | ✔ | ✔ |
| [✅ Recommended] Assume Role directly using GitHub OIDC provider | | ✔ | |
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 like it. I'll change it I'm moving the recommended approach to the top row.
README.md
Outdated
### Sample IAM Role CloudFormation Template | ||
```yaml |
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.
🤩
What do you think of adding a "Launch stack" button to make this easy to create for folks? (maybe something like this: https://github.com/buildkite/cloudformation-launch-stack-button-svg)
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 love to. I need to get an S3 bucket approved for storing this and that'll take longer than the slack we have in the schedule right now. I will create an Issue for adding that.
@@ -43,6 +45,10 @@ async function assumeRole(params) { | |||
let roleArn = roleToAssume; | |||
if (!roleArn.startsWith('arn:aws')) { | |||
// Supports only 'aws' partition. Customers in other partitions ('aws-cn') will need to provide full ARN | |||
assert( | |||
isDefined(sourceAccountId), | |||
"Source Account ID is needed if the Role Name is provided and not the Role Arn." |
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.
Can the user provide this information? I wonder if we can provide a suggested action here if we end up in this error scenario 🤔
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 what I was struggling with. It seems like we're trying to help the customer by saying "if you only provide a Role Name, we'll try our best to figure out which account you're talking about". Customers will encounter this exception if they supply a Role Name for use with the OIDC. Our current logic has the STS client call "get-caller-identity" and parse the response to get an account ID. I feel like this is a bit too much magic for customers who may be running this in a self-hosted runner with some limited permissions in AccountA and we might try to accidentally assume another role in accountA. I'd prefer that for the OIDC users we ask them to explicitly provide the Arn and we can relax it later.
I think I squashed the commits correctly so we don't spam the commit history. |
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.
!
The default session duration is 6 hours, but if you would like to adjust this you can pass a duration to `role-duration-seconds`. | ||
We recommend using GitHub's OIDC provider to get short-lived credentials needed for your actions. | ||
Specifying `role-to-assume` without providing an `aws-access-key-id` or a `web-identity-token-file` will signal to the action that you wish to use the OIDC provider. | ||
The default session duration is 1 hour when using the OIDC provider to directly assume an IAM Role. |
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 may be misunderstanding this documentation, but it doesn't look like this logic was implemented in the PR and the default is still using MAX_ACTION_RUNTIME
regardless of method. I think 3600 seconds is the default on new roles and that would mean we'd need to set role-duration-seconds
on every use of the plugin or change the maximum session duration on our roles. I like the 1 hour default if using OIDC.
I'm really excited for this to land and it's been working great in testing.
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 was a really good catch! Thank you! I'm fixing it now. It'll default to 3600 for GH OIDC provider Roles and remain 6hrs (for backwards compatibility reasons) for the rest.
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.
That sounds perfect, thanks!
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.
Fixed, and I updated the test to validate it.
@@ -99,48 +119,52 @@ Example: | |||
``` | |||
In this example, the secret `AWS_ROLE_TO_ASSUME` contains a string like `arn:aws:iam::123456789100:role/my-github-actions-role`. To assume a role in the same account as the static credentials, you can simply specify the role name, like `role-to-assume: my-github-actions-role`. | |||
|
|||
### Permissions for assuming a role |
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.
Can we also remove permissions to assuming a role from the Table of Contents
README.md
Outdated
} | ||
] | ||
} | ||
### Sample IAM Role CloudFormation Template |
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.
Can we add this to Table of Contents
and link them here
index.js
Outdated
let sourceAccountId; | ||
let webIdentityToken; | ||
if(useGitHubOIDCProvider()) { | ||
webIdentityToken = await getWebIdentityToken(maskAccountId, region); |
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.
Do we need to send maskAccountId and region to getWebIdentityToken for pulling OIDC credentials?
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.
fixed
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.
HI @richardhboyd , Thanks for this cool feature implementation. I have couple of questions and suggestions for you otherwise it looks fine to me 🎉
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 minor suggestion around reading role-duration-seconds
and a general question I can't seem to answer regarding the id-token
permission for the workflow.
index.js
Outdated
if(isDefined(webIdentityTokenFile)) { | ||
core.debug("webIdentityTokenFile provided. Will call sts:AssumeRoleWithWebIdentity and take session tags from token contents.") | ||
assumeRoleRequest.WebIdentityToken = webIdentityToken; | ||
assumeRoleRequest.DurationSeconds = 3600; |
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.
We would still want the ability to set role-duration-seconds
using the input. There are a few roles for us that I specifically would want to intentionally shorten this value. I think a default of 3600 for OIDC to match the role default in AWS makes a lot of sense, so the normal path is to not have to worry about setting anything. I think this should probably just be toggling the default value based on useGitHubOIDCProvider()
type logic near the definition. Conditional defaults may be a little odd, but I think you're right about wanting to maintain backwards compatibility, and I think this lines up with the new documentation.
Maybe something like const roleDurationSeconds = core.getInput('role-duration-seconds', {required: false}) || getDefaultRoleDurationSeconds(???);
?
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.
Again, another good catch. I shouldn't have tried to write this code so early on a Monday.
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.
What are your thoughts on
if(useGitHubOIDCProvider()) {
webIdentityToken = await getWebIdentityToken(maskAccountId, region);
roleDurationSeconds = core.getInput('role-duration-seconds', {required: false}) || DEFAULT_ROLE_DURATION_FOR_OIDC_ROLES;
Then I removed the manual change I just made. My only challenge with the code you provided is that I'd have to pass a bunch of env variables into the getDefaultRoleSDurationSeconds() which may not have been set yet so the behavior of the program might change based on where the call was made from, which seemed a bit hard to maintain.
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.
That looks great to me.
|
||
### Examples | ||
|
||
```yaml |
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 have a general question I've been struggling to find documentation on from Github. What I'm seeing in my test pipelines is we need to set the id-token: write
permission in the job permissions field in order to be provided the token for OIDC. I can't find this documented by Github anywhere. I'm also finding that when I set that, and thus go down the road of defining the permissions
block at all, it undoes any other default permissions. This means I need to do something like:
permissions:
id-token: write
contents: read
In order to both get the OIDC token and continue to be able to use the token for normal actions/checkout@v2
checkouts.
The google auth plugin did seem to allude to this setting when they updated for OIDC I noticed - https://github.com/google-github-actions/auth#usage
I can't find any Github documentation around this, which I assume is because this actual feature is still beta? If AWS or anyone understands how this thing works, maybe it could be documented here :)
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.
we're also still waiting on official documenation
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.
Awesome, thanks for verifying I'm not just missing something.
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.
Looks good to me for the role-duration-seconds
Bumps [jest](https://github.com/facebook/jest) from 27.2.1 to 27.2.2. - [Release notes](https://github.com/facebook/jest/releases) - [Changelog](https://github.com/facebook/jest/blob/main/CHANGELOG.md) - [Commits](jestjs/jest@v27.2.1...v27.2.2) --- updated-dependencies: - dependency-name: jest dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [ansi-regex](https://github.com/chalk/ansi-regex) from 5.0.0 to 5.0.1. - [Release notes](https://github.com/chalk/ansi-regex/releases) - [Commits](chalk/ansi-regex@v5.0.0...v5.0.1) --- updated-dependencies: - dependency-name: ansi-regex dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [aws-sdk](https://github.com/aws/aws-sdk-js) from 2.991.0 to 2.996.0. - [Release notes](https://github.com/aws/aws-sdk-js/releases) - [Changelog](https://github.com/aws/aws-sdk-js/blob/master/CHANGELOG.md) - [Commits](aws/aws-sdk-js@v2.991.0...v2.996.0) --- updated-dependencies: - dependency-name: aws-sdk dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
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.
Looks good to me. 💯 🎉
the Action supports ID token issued by GitHub OIDC and GitHub Acitons can assume the specified role using IAM identity provider. See aws-actions/configure-aws-credentials#262 for more details.
Description of changes:
Added the ability to use GitHub provided OIDC token. If a user supplies a Role Arn and doesn't supply either an Access Key Id or a WebIdentityTokenFile we will attempt to load the OIDC Token from the environment variable provided by GitHub. If the Environment variable isn't set (because this could be running in a self-hosted runner) then we will fall back to the default credential provider as previously outlined in the
README.md
.Updated the
README.md
to remove most mentions of using IAM Users as we expect future users to rely on the OIDC implementation, but the IAM User use-case is still defined (it's just not highlighted any more in the documentation).Thanks to @aidansteele for the reference implmentation.
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.