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

feat(aws-cdk): be aware of IAM and SecurityGroup changes #1240

Merged
merged 27 commits into from
Dec 10, 2018

Conversation

rix0rrr
Copy link
Contributor

@rix0rrr rix0rrr commented Nov 23, 2018

Add awareness of potentially risky permissions changes to the
cfnspec and diff tool, and surface those changes in an easily
digestible format.

This PR is still a work in progress.

Feature TODO:

  • Recognize AWS::Lambda::Permission objects
  • Recognize managed policies
  • Add support for SecurityGroup rules
  • Reverse engineer construct paths from logical IDs
  • [ ] Apply same logic to format inline diffs for IAM policy
    property updates.
  • Automatically diff and confirm statement additions on every
    'deploy'.

Quality TODO:

  • property tests on statement equality, parsing
  • tests on 'uncfn' routines
  • Replace CLI table library in aws-cdk to be the same as
    this one (supports newlines in cells and generally looks better).

Fixes #978.


Pull Request Checklist

Please check all boxes (including N/A items)

Testing

  • Unit test and/or integration test added
  • Toolkit change?: integration
    tests

    manually executed (paste output to the PR description)
  • Init template change?: coordinated update of integration tests
    (currently maintained in a private repo).

Documentation

  • README: README and/or documentation topic updated
  • jsdocs: All public APIs documented

Title and description

  • Change type: Title is prefixed with change type:
    • fix(module): <title> bug fix (patch)
    • feat(module): <title> feature/capability (minor)
    • chore(module): <title> won't appear in changelog
    • build(module): <title> won't appear in changelog
  • Title format: Title uses lower case and doesn't end with a period
  • Breaking change?: Last paragraph of description is: BREAKING CHANGE: <describe exactly what changed and how to achieve similar behavior + link to documentation/gist/issue if more details are required>
  • References: Indicate issues fixed via: Fixes #xxx or Closes #xxx

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license.

Rico Huijbers and others added 2 commits November 22, 2018 15:47
Add awareness of potentially risky permissions changes to the
cfnspec and diff tool, and surface those changes in an easily
digestible format.

This is an initial commit.

Feature TODO:

- [ ] Recognize AWS::Lambda::Permission objects
- [ ] Recognize managed policies
- [ ] Add support for SecurityGroup rules
- [ ] Reverse engineer construct paths from logical IDs
- [ ] Apply same logic to format inline diffs for IAM policy
  property updates.
- [ ] Automatically diff and confirm statement additions on every
  'deploy'.

Quality TODO:

- [ ] property tests on statement equality, parsing
- [ ] tests on 'uncfn' routines
- [ ] Replace CLI table library in aws-cdk to be the same as
  this one (supports newlines in cells and generally looks better).

Fixes #978.
@rix0rrr
Copy link
Contributor Author

rix0rrr commented Nov 23, 2018

Trivial example:

(Rico Huijbers/Isengard) test$ cdk -a integ.sns-lambda.js diff
Summary of IAM Changes
┌───┬────────────────────────────────┬────────┬────────────────┬──────────────────────────────┬───────────┐
│   │ Resource                       │ Effect │ Actions        │ Principals                   │ Condition │
├───┼────────────────────────────────┼────────┼────────────────┼──────────────────────────────┼───────────┤
│ + │ ${EchoServiceRoleBE28060B.Arn} │ Allow  │ sts:AssumeRole │ Service:lambda.amazonaws.com │           │
└───┴────────────────────────────────┴────────┴────────────────┴──────────────────────────────┴───────────┘

Resources
[+] AWS::SNS::Topic MyTopic MyTopic86869434 
[+] AWS::SNS::Subscription MyTopic/EchoSubscription MyTopicEchoSubscription021036AD 
[+] AWS::IAM::Role Echo/ServiceRole EchoServiceRoleBE28060B 
[+] AWS::Lambda::Function Echo Echo11F3FB29 
[+] AWS::Lambda::Permission Echo/MyTopic EchoMyTopicF6EBB45F 

Before, the json file would be loaded upon initialization of the
library, but the library would also be loaded in the build tool.

It's only because of some crazy lazy evaluation optimization done
by NodeJS that that didn't blow up before, but due to code changes it
does blow up now.
@rix0rrr
Copy link
Contributor Author

rix0rrr commented Nov 27, 2018

Current status:

Summary of IAM Changes
┌───┬─────────────────────────┬────────┬───────────────────────┬──────────────────────────────┬─────────────────────────────────┐
│   │ Resource                │ Effect │ Action                │ Principal                    │ Condition                       │
├───┼─────────────────────────┼────────┼───────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ ${Echo}                 │ Allow  │ lambda:InvokeFunction │ Service:sns.amazonaws.com    │ "ArnLike": {                    │
│   │                         │        │                       │                              │   "AWS:SourceArn": "${MyTopic}" │
│   │                         │        │                       │                              │ }                               │
├───┼─────────────────────────┼────────┼───────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ ${Echo/ServiceRole.Arn} │ Allow  │ sts:AssumeRole        │ Service:lambda.amazonaws.com │                                 │
└───┴─────────────────────────┴────────┴───────────────────────┴──────────────────────────────┴─────────────────────────────────┘

┌───┬─────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│   │ Resource                │ Managed Policy ARN                                                             │
├───┼─────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${Echo/ServiceRole.Arn} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴─────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘

@rix0rrr
Copy link
Contributor Author

rix0rrr commented Nov 28, 2018

Status so far

Summary of Security Group Changes
┌───┬──────────────────────────────────┬─────┬────────────┬──────────────────────────────────┐
│   │ Group                            │ Dir │ Protocol   │ Peer                             │
├───┼──────────────────────────────────┼─────┼────────────┼──────────────────────────────────┤
│ + │ ${LB/SecurityGroup.GroupId}      │ In  │ TCP 80     │ Everyone (IPv4)                  │
│ + │ ${LB/SecurityGroup.GroupId}      │ Out │ TCP 80     │ ${Service/SecurityGroup.GroupId} │
├───┼──────────────────────────────────┼─────┼────────────┼──────────────────────────────────┤
│ + │ ${Service/SecurityGroup.GroupId} │ In  │ TCP 80     │ ${LB/SecurityGroup.GroupId}      │
│ + │ ${Service/SecurityGroup.GroupId} │ Out │ Everything │ Everyone (IPv4)                  │
└───┴──────────────────────────────────┴─────┴────────────┴──────────────────────────────────┘

@rix0rrr
Copy link
Contributor Author

rix0rrr commented Nov 28, 2018

This deployment will make potentially sensitive changes.
Please confirm you intend to make the following modifications:

IAM Statement Changes
┌───┬─────────────────────────┬────────┬───────────────────────┬──────────────────────────────┬─────────────────────────────────┐
│   │ Resource                │ Effect │ Action                │ Principal                    │ Condition                       │
├───┼─────────────────────────┼────────┼───────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ ${Echo}                 │ Allow  │ lambda:InvokeFunction │ Service:sns.amazonaws.com    │ "ArnLike": {                    │
│   │                         │        │                       │                              │   "AWS:SourceArn": "${MyTopic}" │
│   │                         │        │                       │                              │ }                               │
├───┼─────────────────────────┼────────┼───────────────────────┼──────────────────────────────┼─────────────────────────────────┤
│ + │ ${Echo/ServiceRole.Arn} │ Allow  │ sts:AssumeRole        │ Service:lambda.amazonaws.com │                                 │
└───┴─────────────────────────┴────────┴───────────────────────┴──────────────────────────────┴─────────────────────────────────┘
IAM Policy Changes
┌───┬─────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│   │ Resource                │ Managed Policy ARN                                                             │
├───┼─────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${Echo/ServiceRole.Arn} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴─────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘

Do you wish to deploy these changes (y/n)? n
Aborted by user

Copy link
Contributor

@eladb eladb left a comment

Choose a reason for hiding this comment

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

  • Please add a statement at the bottom of the security diff indicating this is an experimental feature and that users should consult the JSON diff as well to ensure no unexpected broadening of permissions happens. We need to let this bake for a bit before we let people trust this blindly.

  • Might have missed that, but I expected cdk diff to always print any security related changes (not only broadening).

packages/@aws-cdk/cfnspec/build-tools/scrutiny.ts Outdated Show resolved Hide resolved
packages/@aws-cdk/cfnspec/lib/index.ts Outdated Show resolved Hide resolved
packages/@aws-cdk/cloudformation-diff/lib/format.ts Outdated Show resolved Hide resolved
packages/@aws-cdk/cloudformation-diff/lib/uncfn.ts Outdated Show resolved Hide resolved
@@ -53,6 +54,7 @@ async function parseCommandLineArguments() {
.command('bootstrap [ENVIRONMENTS..]', 'Deploys the CDK toolkit stack into an AWS environment', yargs => yargs
.option('toolkit-stack-name', { type: 'string', desc: 'the name of the CDK toolkit stack' }))
.command('deploy [STACKS..]', 'Deploys the stack(s) named STACKS into your AWS account', yargs => yargs
.option('prompt', { type: 'string', choices: ['never', 'on-add'], default: 'on-add', desc: 'prompt if security-sensitive changes are about to be deployed' })
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd rename this option to safety or security and I envision three options:

  • ignore -- like "never" - basically ignores any security changes
  • require-approval - a future mode, which should be the default I think, where some form of an approval hash can be stored in cdk.json. This will allow CI/CD to protect against unsolicited changes instead of ignoring everything
  • always-prompt - similar to the current on-add where it will always prompt even if there is an approval in cdk.json

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think there are two axes: one the one hand, what the change are that should trigger the approval workflow. On the other hand, how the approval is given (viz. interactive vs CI/CD workflows).

This flag was intended to select along the first axis--though I agree that the name was poorly chosen.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

always-prompt never makes sense in CI/CD, so I don't see why we should offer that option.

@rix0rrr
Copy link
Contributor Author

rix0rrr commented Dec 5, 2018

Might have missed that, but I expected cdk diff to always print any security related changes (not only broadening).

It does. It's cdk deploy that does it conditionally.

@rix0rrr
Copy link
Contributor Author

rix0rrr commented Dec 5, 2018

  • We should also trigger specially on AWS::IAM::User objects.

@rix0rrr
Copy link
Contributor Author

rix0rrr commented Dec 6, 2018

============================================================================================
test-cdk-context.sh
============================================================================================
Testing for the context value
Context value contextkey reset. It will be refreshed on the next SDK synthesis run.
No context value with key contextkey
✅  success
============================================================================================
test-cdk-deploy-all.sh
============================================================================================
| ensuring cdk-toolkit-integration-test-1 is cleaned up
| ensuring cdk-toolkit-integration-test-2 is cleaned up
cdk-toolkit-integration-test-1
cdk-toolkit-integration-test-1: deploying...
cdk-toolkit-integration-test-1: creating CloudFormation changeset...
 0/2 | 10:27:14 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic (topic69831491) 
 0/2 | 10:27:15 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic (topic69831491) Resource creation Initiated
 1/2 | 10:27:25 | CREATE_COMPLETE      | AWS::SNS::Topic | topic (topic69831491) 
 2/2 | 10:27:27 | CREATE_COMPLETE      | AWS::CloudFormation::Stack | cdk-toolkit-integration-test-1 

 ✅  cdk-toolkit-integration-test-1

Stack ARN:
cdk-toolkit-integration-test-2
cdk-toolkit-integration-test-2: deploying...
cdk-toolkit-integration-test-2: creating CloudFormation changeset...
 0/3 | 10:27:40 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic2 (topic2A4FB547F) 
 0/3 | 10:27:40 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic1 (topic152D84A37) 
 0/3 | 10:27:41 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic2 (topic2A4FB547F) Resource creation Initiated
 0/3 | 10:27:41 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic1 (topic152D84A37) Resource creation Initiated
 1/3 | 10:27:51 | CREATE_COMPLETE      | AWS::SNS::Topic | topic2 (topic2A4FB547F) 
 2/3 | 10:27:51 | CREATE_COMPLETE      | AWS::SNS::Topic | topic1 (topic152D84A37) 
 3/3 | 10:27:53 | CREATE_COMPLETE      | AWS::CloudFormation::Stack | cdk-toolkit-integration-test-2 

 ✅  cdk-toolkit-integration-test-2

Stack ARN:
Stack deployed successfully
cdk-toolkit-integration-test-1: destroying...

 ✅  cdk-toolkit-integration-test-1: destroyed
cdk-toolkit-integration-test-2: destroying...

 ✅  cdk-toolkit-integration-test-2: destroyed
✅  success
============================================================================================
test-cdk-deploy.sh
============================================================================================
| ensuring cdk-toolkit-integration-test-1 is cleaned up
| ensuring cdk-toolkit-integration-test-2 is cleaned up
cdk-toolkit-integration-test-2: deploying...
cdk-toolkit-integration-test-2: creating CloudFormation changeset...
 0/3 | 10:28:24 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic2 (topic2A4FB547F) 
 0/3 | 10:28:24 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic1 (topic152D84A37) 
 0/3 | 10:28:24 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic2 (topic2A4FB547F) Resource creation Initiated
 0/3 | 10:28:24 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic1 (topic152D84A37) Resource creation Initiated
 1/3 | 10:28:35 | CREATE_COMPLETE      | AWS::SNS::Topic | topic2 (topic2A4FB547F) 
 2/3 | 10:28:35 | CREATE_COMPLETE      | AWS::SNS::Topic | topic1 (topic152D84A37) 
 3/3 | 10:28:36 | CREATE_COMPLETE      | AWS::CloudFormation::Stack | cdk-toolkit-integration-test-2 

 ✅  cdk-toolkit-integration-test-2

Stack ARN:
Stack deployed successfully
| assert that last command returned 1 line(s)
cdk-toolkit-integration-test-2: destroying...

 ✅  cdk-toolkit-integration-test-2: destroyed
✅  success
============================================================================================
test-cdk-deploy-with-role.sh
============================================================================================

An error occurred (NoSuchEntity) when calling the ListRolePolicies operation: The role with name cdk-integ-test-role cannot be found.

An error occurred (NoSuchEntity) when calling the DeleteRole operation: The role with name cdk-integ-test-role cannot be found.
Role does not exist yet
Sleeping a bit to improve chances of the role having propagated
| ensuring cdk-toolkit-integration-test-1 is cleaned up
| ensuring cdk-toolkit-integration-test-2 is cleaned up
cdk-toolkit-integration-test-2: deploying...
cdk-toolkit-integration-test-2: creating CloudFormation changeset...
 0/3 | 10:29:10 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic1 (topic152D84A37) 
 0/3 | 10:29:10 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic1 (topic152D84A37) Resource creation Initiated
 0/3 | 10:29:11 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic2 (topic2A4FB547F) 
 0/3 | 10:29:11 | CREATE_IN_PROGRESS   | AWS::SNS::Topic | topic2 (topic2A4FB547F) Resource creation Initiated
 1/3 | 10:29:21 | CREATE_COMPLETE      | AWS::SNS::Topic | topic1 (topic152D84A37) 
 2/3 | 10:29:21 | CREATE_COMPLETE      | AWS::SNS::Topic | topic2 (topic2A4FB547F) 
 3/3 | 10:29:23 | CREATE_COMPLETE      | AWS::CloudFormation::Stack | cdk-toolkit-integration-test-2 

 ✅  cdk-toolkit-integration-test-2

Stack ARN:
Stack deployed successfully
| assert that last command returned 1 line(s)
cdk-toolkit-integration-test-2: destroying...

 ✅  cdk-toolkit-integration-test-2: destroyed
✅  success
============================================================================================
test-cdk-diff.sh
============================================================================================
| ensuring cdk-toolkit-integration-test-1 is cleaned up
| ensuring cdk-toolkit-integration-test-2 is cleaned up
| assert that last command returned 2 line(s)
| assert that last command returned 3 line(s)
✅  success
============================================================================================
test-cdk-iam-diff.sh
============================================================================================
| ensuring cdk-toolkit-integration-test-1 is cleaned up
| ensuring cdk-toolkit-integration-test-2 is cleaned up
| running nonfailing_diff cdk-toolkit-integration-iam-test
✅  success
============================================================================================
test-cdk-ls.sh
============================================================================================
| ensuring cdk-toolkit-integration-test-1 is cleaned up
| ensuring cdk-toolkit-integration-test-2 is cleaned up
| running cdk ls
✅  success
============================================================================================
test-cdk-synth.sh
============================================================================================
| ensuring cdk-toolkit-integration-test-1 is cleaned up
| ensuring cdk-toolkit-integration-test-2 is cleaned up
| running cdk synth cdk-toolkit-integration-test-1
| running cdk synth cdk-toolkit-integration-test-2
✅  success

docs/src/tools.rst Show resolved Hide resolved
@@ -23,18 +23,18 @@
},
"license": "Apache-2.0",
"dependencies": {
"@aws-cdk/cfnspec": "^0.18.1",
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we bumping?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't know why this even shows up. But because 0.19.0 has been released on master in the mean time.

formatter.formatIamChanges(templateDiff.iamChanges);
formatter.formatSecurityGroupChanges(templateDiff.securityGroupChanges);

formatter.warning(`(This feature is experimental -- it might not be complete. See http://bit.ly/cdk-2EhF7Np)`);
Copy link
Contributor

Choose a reason for hiding this comment

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

TBH, I am not even sure this is just because this is an experimental feature. There could always be security related changes at the application level that we will never know about. So maybe something like this:

WARNING: there may be security-related changes which do not appear in this list. See <URL> for details.

Maybe we should ask our security folks what would be the best wording here?

@rix0rrr rix0rrr merged commit 9e121a7 into master Dec 10, 2018
@rix0rrr rix0rrr deleted the huijbers/iam-aware-diffs branch December 10, 2018 13:36
@NGL321 NGL321 added the contribution/core This is a PR that came from AWS. label Sep 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution/core This is a PR that came from AWS.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

toolkit: surface potentially risky changes and enforce confirmation
3 participants