-
Notifications
You must be signed in to change notification settings - Fork 4k
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(iam): validate policies for missing resources/principals #9269
Conversation
Also remove unneeded validation in Alias construct - this will be performed automatically since it will contain Key as a child node if validation is necessary.
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.
Thanks for the hard work you've been putting in here.
A couple of small tweaks and I'm happy to ship this!
public validateForAnyPolicy(): string[] { | ||
const errors = new Array<string>(); | ||
if (this.action.length === 0 && this.notAction.length === 0) { | ||
errors.push('A PolicyStatement must specify at least one allow or deny action.'); |
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.
Yes, however, there is also effect: Allow | Deny
, so I wonder if this might not be confusing what the actual check is.
Allow NotActions
is not the same as Deny Actions
.
errors.push('A PolicyStatement must specify at least one allow or deny action.'); | |
errors.push('A PolicyStatement must specify at least one \'action\' or \'notAction\'.'); |
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.
Good catch - I forgot about this distinction!
protected validate(): string[] { | ||
const errors = super.validate(); | ||
errors.push(...this.assumeRolePolicy?.validateForResourcePolicy() || []); | ||
for (const policyName of Object.keys(this.inlinePolicies)) { |
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.
You can iterate over Object.values()
instead.
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 CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
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). |
This PR #9269, implemented `validate()` on the KMS key construct. Since this methods override `Construct` `validate` it must have the same visibility modifier - `protected`. Changing visibility modifier on override methods breaks `jsii-pacmak`, specifically C# packaging.: ``` amazon/CDK/AWS/KMS/Key.cs(97,34): error CS0507: 'Key.Validate()': cannot change access modifiers when overriding 'protected' inherited member 'Construct_.Validate()' [/tmp/npm-packtcwuee/Amazon.CDK.AWS.KMS/Amazon.CDK.AWS.KMS.csproj] ``` ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
Adds policy statement validation checks for all constructs that contain IAM policies.
Fixes #7615
Note: sensitive module (requires 2 PR approvers). I am not sure if the changes presented here are considered breaking or not.
I'm looking to get early feedback for this commit! I'm not an IAM subject matter expert, so this is my best interpretation of the AWS docs I've read so far - but I'm still trying to figure out what details and edge cases I'm missing if any. 😅
Problem
To recap what rix0rrr mentions in #7897, my understanding is that there are two main kinds of IAM policies we are interested in checking:
I am not aware of any other kinds of policies mentioned in the AWS docs here that can be constructed in the CDK.
Based on this IAM docs page, it seems to me that there are at least four types of distinct policy statements errors that we could feasibly try to check right before synthesis time:
The reason we need to perform these checks right before synthesis is because it can't be done at constructor time, since CDK users can add actions, principals, etc. after creation / out of order.
Design
Since we want the validation logic to happen at synthesis time, the best option is to override the validate() method for the appropriate Construct child subclasses that we want these rules to apply to. The following is the list of constructs I found that directly contain policy documents:
All other constructs that have some kind of role/policy statement functions (e.g. iam.User, lambda.Function) automatically get the validations transitively through one of the constructs above.
In my commits, I've added appropriate methods to PolicyStatement and PolicyDocument to perform validation of various kinds, and then called these methods in the appropriate construct's validate() methods.
Other considerations:
It's also possible we could add calls to the PolicyStatement validation methods inside other methods such as addToResourcePolicy() found within several classes - but I think this could make the library less flexible, since a statement can still be modified after it has been added to a PolicyDocument (correct me if wrong).
An alternative design I considered for the case of Resource constructs was extending the interface of IResourceWithPolicy with a validatePolicy() method, but it doesn't make a lot of sense to make the method public (which would have been required by TypeScript), and in the end all I want to do is overwrite the protected Construct#validate() method anyway. Since IResourceWithPolicy is just an interface (and not a class), I don't see any way to cleanly enforce that all Resources with policies will perform the policy validation, but I think the current solution is adequate.
Examples
These are examples of the four errors presented above that you can easily verify will fail during deployment (but aren't caught at compile or synth time), and which I've tested fail with my added changes.
Issues
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license