cfn-language-discussion
cfn-language-discussion copied to clipboard
Intrinsic function for simplified IAM permissions
Community Note
- Please vote on this issue by adding a 👍 reaction to the original issue to help the community and maintainers prioritize this request
- Please do not leave "+1" or "me too" comments, they generate extra noise for issue followers and do not help prioritize the request
- If you are interested in working on this issue or have submitted a pull request, please leave a comment
Tell us about your request
Wanted to get community feedback about the potential for adding an intrinsic function to simplify generation of minimal IAM policy permissions.
Tell us about the problem you are trying to solve. What are you trying to do, and why is it hard?
Today when authoring declarative templates, writing minimal IAM permissions is difficult. For example, if I want to add minimal permissions allowing read/write data access to a specific DynamoDB table, I have to lookup the DynamoDB IAM actions and determine which are associated with reading and writing data, add them to a policy document and then determine the right resource ARN to use for the DynamoDB table, either via manually constructing the ARN via Fn::Sub or if the table is defined in the template, using Fn::GetAtt to fetch the ARN.
Are you currently working around this issue?
There are a few workarounds:
- Follow the manual process described above, but it's time consuming and error-prone (easy to miss needed actions, e.g., for certain DDB write operations,
dynamodb:ConditionCheckItemaction is required, but this is an easy one to overlook). - Use a managed policy like
AmazonDynamoDBFullAccess. Downside is this doesn't follow minimal permissions best practice (includes more actions than needed, usesResource: *). - Migrate to CDK as it has a really slick solution for this: grants. Downside is migration to CDK can be costly or blocked on updating internal customer deployment tooling.
What is the expect behavior with this new feature
Wondering about taking inspiration from CDK's grant methods and creating something like Fn::Grant that can be used by declarative template authors to create minimal permission sets for common use cases. Picturing something like this:
Resources:
Table:
Type: AWS::DynamoDB::Table
Properties:
# ...
Key:
Type: AWS::KMS::Key
Properties:
# ...
Role:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Fn::Grant
- Table
- ReadWriteData
- Fn::Grant
- Key
- EncryptDecrypt
This would be equivalent to this:
Resources:
Table:
Type: AWS::DynamoDB::Table
Properties:
# ...
Key:
Type: AWS::KMS::Key
Properties:
# ...
Role:
Type: AWS::IAM::Policy
Properties:
PolicyDocument:
Statement:
- Action:
- dynamodb:BatchGetItem
- dynamodb:GetRecords
- dynamodb:GetShardIterator
- dynamodb:Query
- dynamodb:GetItem
- dynamodb:Scan
- dynamodb:ConditionCheckItem
- dynamodb:BatchWriteItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
- dynamodb:DescribeTable
Effect: Allow
Resource:
- !GetAtt Table.Arn
- !Sub ${Table.Arn}/index/*
- Action:
- kms:Decrypt
- kms:Encrypt
- kms:ReEncrypt*
- kms:GenerateDataKey*
Effect: Allow
Resource: !GetAtt Key.Arn
Note, the above examples take the logical resource of a resource defined in the same template as the first argument, but this could potentially be enhanced to allow you to pass an arbitrary ARN value in as well.
I support simplifying IAM in every way possible.
So far all intrinsic functions are resource agnostic, but this is specific to IAM policies, so it'll be adding a new dimension to intrinsic functions imo, but maybe that's unavoidable.
Instead of specifying
Fn::Grant:
- Table
- ReadWrite
I think it'd be nice to be able to specify a grant per api action. Something like:
Fn::Grant:
- Table
- - Query
- PutItem
Otherwise it gets difficult for the developer to understand what the ReadWrite includes. Does it allow DeleteItem for example?
This does have some drawbacks.
Grants are yet another thing for users to learn, and for AWS to maintain and document. We already have policies to define collections of permissions. Perhaps they could be improved.
From a security point of view, I'd still need to understand which permissions are part of the grant. Already we see @ljacobsson's question about whether ReadWrite implies DeleteItem. I'd still need to look up the documentation whether I was choosing actions or grants.
I'd hope that individual grants would only apply to a specific resource type (S3 buckets vs. objects, not both), which increases the number of grant definitions and would pull them closer to the complexity of actions.