Skip to content
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

fix(cli): credential provider plugins cannot be used with modern synthesis #11350

Merged
merged 12 commits into from
Nov 19, 2020

Conversation

IainCole
Copy link
Contributor

@IainCole IainCole commented Nov 7, 2020

I'm not currently able to use CDK pipelines because I use a credential provider. I believe this is because the new bootstrap uses assumed roles. When assuming a role, only defaultCredentials is checked, I'm not sure if this was intentional or not because there is a comment that seems to mention this (that I will edit if this PR has any merit), but it seems odd to not allow a credential provider here.

I'm not 100% sure why I had to change the account ID in the tests, but I did and all the tests seem to still pass.

@gitpod-io
Copy link

gitpod-io bot commented Nov 7, 2020

@IainCole IainCole marked this pull request as draft November 7, 2020 00:27
@mergify
Copy link
Contributor

mergify bot commented Nov 7, 2020

Title does not follow the guidelines of Conventional Commits. Please adjust title before merge.

@IainCole IainCole changed the title fix(sdk-provider) allow withAssumedRole to use obtainCredentials instead of defaultCredentials fix(sdk-provider): allow withAssumedRole to use obtainCredentials instead of defaultCredentials Nov 7, 2020
@IainCole IainCole marked this pull request as ready for review November 7, 2020 01:03
@rix0rrr
Copy link
Contributor

rix0rrr commented Nov 16, 2020

Wait, how do you intend to use this?

There is an assumed role, sure. Your credential provider is going to give you credentials to use to assume the role, is that right?

Our intended use of this feature was that you would use your default (user/developer) credentials to account A to federate into another account B (assuming that account B had given you permissions to do so by using --trust).

Can you describe your use case in more detail? What kind of credential provider are you using?

Copy link
Contributor

@rix0rrr rix0rrr left a comment

Choose a reason for hiding this comment

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

If we agree that this is a useful change, you're going to have to add a test to assert that the credentials returned by the provider will be used to assume the role.

Changing the call signatures of the function in existing tests does not constitute sufficient testing, we didn't test the new functionality yet :).

@IainCole
Copy link
Contributor Author

IainCole commented Nov 16, 2020

Yeah, I want the credentials to come from a credential provider. I work for a large IaaS company and have a lot of AWS accounts I need to be using with CDK, I also don't want to have loads of creds on my machine if at all possible. So I use a credential provider to authenticate me and retrieve credentials for use in CDK which works great, but I can't use any of the new bootstrap assumeRole stuff because it can't get the credentials from the plugin, happy to add tests and stuff if we think this is a useful change, changing the call signatures was just to make it build :).

@rix0rrr
Copy link
Contributor

rix0rrr commented Nov 17, 2020

Okay I do see the use case here. Feeling slightly uneasy about the change (as there are now 2 federation mechanisms fighting), but given that we don't really have anything better in place and you need to be unblocked, I'll go ahead and okay it after you add that test.

@mergify mergify bot dismissed rix0rrr’s stale review November 17, 2020 21:37

Pull request has been modified.

@rix0rrr rix0rrr changed the title fix(sdk-provider): allow withAssumedRole to use obtainCredentials instead of defaultCredentials fix(cli): credential provider plugins cannot be used with modern synthesis Nov 19, 2020
@mergify
Copy link
Contributor

mergify bot commented Nov 19, 2020

Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildProject6AEA49D1-qxepHUsryhcu
  • Commit ID: 4be5b89
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify
Copy link
Contributor

mergify bot commented Nov 19, 2020

Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit 9e91306 into aws:master Nov 19, 2020
@IainCole IainCole deleted the ic_assumerole_credentials branch November 19, 2020 19:48
rix0rrr added a commit that referenced this pull request Dec 9, 2020
This addresses a regression introduced in #11350 and reported in #11792.

The original PR added support for using a credential provider as a source
for credentials that will be used to assume the CDK Deploy Roles
(created by Modern Bootstrapping and used by Default Synthesis).

However, by doing so, it broke support for using current AWS credentials
to do the same.

Closes #11792.
mergify bot pushed a commit that referenced this pull request Dec 11, 2020
This addresses a regression introduced in #11350 and reported in #11792.

The original PR added support for using a credential provider as a source
for credentials that will be used to assume the CDK Deploy Roles
(created by Modern Bootstrapping and used by Default Synthesis).

However, by doing so, it broke support for using current AWS credentials
to do the same.

## Original Behavior

- In case of legacy stack, use "current credentials" if they are for the right account, otherwise ask credential provider plugins, fail if current credentials are for the wrong account
- In case of DefaultSynthesized stack, always use "current credentials" to assume role

## Broken Behavior

- In case of legacy stack, use "current credentials" if they are for the right account, otherwise ask credential provider plugins for credentials to the target account, fail if current credentials are for the wrong account
- In case of DefaultSynthesized stack, 
  - Use "current credentials" if they are for the right account, otherwise ask credential provider plugins for credentials to the target account, fail if current credentials are for the wrong account (reusing the logic from legacy stacks)
  - Then assume role using credentials obtained in the previous step

The reuse of the same "credential obtaining" logic here broke cross-account role assumption, because we'd fail as soon as the current credentials would be for the wrong account instead of still trying to use them for AssumeRole.

## New Behavior

- Try to get "base credentials" for a target environment: 
  - Use "current credentials" if they are for the right account
  - Ask credential provider plugins
  - Use "current credentials" if they are for the wrong account (but remember that they were wrong)
- In case of a legacy stack:
  - If the credentials are for the wrong account, fail
- In case of a DefaultSynthesized stack:
  - Use the set of "base credentials" to try to assume the target role
  - If that succeeds, we're done
  - (Fallback) If it fails and the base credentials were already for the right account, use them after all. This fallback will allow people already using credential plugins to keep on using them, even when interoperating with DefaultSynthesized stacks. It will also allow people who seed their terminal with "ReadOnly" credentials (which might not have `sts:AssumeRole` permissions) to still run `cdk diff` as in the past.

## Changes to tests

There has been a major refactoring of the tests around this.

The current way of testing (mocking some calls left and right) was completely insufficient to test these mechanisms properly. I've therefore resorted to implementing a fake, in-memory version of STS's `GetCallerIdentity` and `AssumeRole`, and using the testing library `nock` to redirect network calls to that in-memory service. This will allow us to test the entire chain from our code down to and including the SDK's behavior, and make sure the right behavior happens without worrying about exact call orders.

At the same time, the single gigantic test fixture (with the `~/.aws/credentials` and `~/.aws/config` files) was becoming rather cumbersome. Instead, each test now includes just the one or two profile sections it uses, and a helper function creates both the config files as well as immediately creates those users in-memory in the fake STS service.

Closes #11792.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
flochaz pushed a commit to flochaz/aws-cdk that referenced this pull request Jan 5, 2021
This addresses a regression introduced in aws#11350 and reported in aws#11792.

The original PR added support for using a credential provider as a source
for credentials that will be used to assume the CDK Deploy Roles
(created by Modern Bootstrapping and used by Default Synthesis).

However, by doing so, it broke support for using current AWS credentials
to do the same.

## Original Behavior

- In case of legacy stack, use "current credentials" if they are for the right account, otherwise ask credential provider plugins, fail if current credentials are for the wrong account
- In case of DefaultSynthesized stack, always use "current credentials" to assume role

## Broken Behavior

- In case of legacy stack, use "current credentials" if they are for the right account, otherwise ask credential provider plugins for credentials to the target account, fail if current credentials are for the wrong account
- In case of DefaultSynthesized stack, 
  - Use "current credentials" if they are for the right account, otherwise ask credential provider plugins for credentials to the target account, fail if current credentials are for the wrong account (reusing the logic from legacy stacks)
  - Then assume role using credentials obtained in the previous step

The reuse of the same "credential obtaining" logic here broke cross-account role assumption, because we'd fail as soon as the current credentials would be for the wrong account instead of still trying to use them for AssumeRole.

## New Behavior

- Try to get "base credentials" for a target environment: 
  - Use "current credentials" if they are for the right account
  - Ask credential provider plugins
  - Use "current credentials" if they are for the wrong account (but remember that they were wrong)
- In case of a legacy stack:
  - If the credentials are for the wrong account, fail
- In case of a DefaultSynthesized stack:
  - Use the set of "base credentials" to try to assume the target role
  - If that succeeds, we're done
  - (Fallback) If it fails and the base credentials were already for the right account, use them after all. This fallback will allow people already using credential plugins to keep on using them, even when interoperating with DefaultSynthesized stacks. It will also allow people who seed their terminal with "ReadOnly" credentials (which might not have `sts:AssumeRole` permissions) to still run `cdk diff` as in the past.

## Changes to tests

There has been a major refactoring of the tests around this.

The current way of testing (mocking some calls left and right) was completely insufficient to test these mechanisms properly. I've therefore resorted to implementing a fake, in-memory version of STS's `GetCallerIdentity` and `AssumeRole`, and using the testing library `nock` to redirect network calls to that in-memory service. This will allow us to test the entire chain from our code down to and including the SDK's behavior, and make sure the right behavior happens without worrying about exact call orders.

At the same time, the single gigantic test fixture (with the `~/.aws/credentials` and `~/.aws/config` files) was becoming rather cumbersome. Instead, each test now includes just the one or two profile sections it uses, and a helper function creates both the config files as well as immediately creates those users in-memory in the fake STS service.

Closes aws#11792.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants