aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.35k stars 3.77k forks source link

(aws-dynamodb): Granting permissions with tables any dynamodb.grant* methods will provide wildcard permissions to KMS #23991

Open heikkima opened 1 year ago

heikkima commented 1 year ago

Describe the bug

Granting permissions with Table's grantReadWriteData() or grantReadData() methods (possibly other grant* methods as well) will grant kms permissions to all kms keys within the AWS account.

Expected Behavior

Expecting Table grant* methods to grant minimal permissions to the specific KMS key that the dynamoDb table is encrypted with.

Current Behavior

Table's grantReadData() method grants KMS permissions to all KMS keys in the AWS account. Does not matter if KMS key is created within the same CDK application or with Key.fromLookup()

The following statement is appended to the IAM role's inline policy

        {
            "Action": [
                "kms:Decrypt",
                "kms:DescribeKey"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }

Reproduction Steps

const encryptionKey = new Key(this, 'MyKey', {
  enableKeyRotation: true,
})

const table = new Table(this, 'MyTable', {
  partitionKey: { name: 'id', type: AttributeType.STRING },
  tableName: 'my-table',
  encryption: TableEncryption.CUSTOMER_MANAGED,
  encryptionKey
})

table.grantReadData(iamRole)

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.63.0 (build 7f4e35e)

Framework Version

No response

Node.js Version

v18.12.1

OS

macOS 13.0.1

Language

Typescript

Language Version

4.9.5

Other information

No response

khushail commented 1 year ago

Hi @heikkima , thanks for reaching out. We tried to reproduce the issue as you described but we are not able to. The policy we generated contains the access to KMS key only and not the one to all resources. Is there any other information would you like to provide to replicate the issue?

github-actions[bot] commented 1 year ago

This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

heikkima commented 1 year ago

Further testing indicates that this happens if the IAM role is provided as a stack prop to the template (the IAM role is created in another CDK template but within the same CDK application).

I tried creating the IAM role in the same template as the KMS key and DynamoDB table and this works as expected:

    const encryptionKey = new Key(this, 'MyKey', {
      enableKeyRotation: true,
    })

    const table = new Table(this, 'MyTable', {
      partitionKey: { name: 'id', type: AttributeType.STRING },
      tableName: 'my-table',
      encryption: TableEncryption.CUSTOMER_MANAGED,
      encryptionKey
    })

    const iamRole = new Role(this, 'Role', {
      permissionsBoundary: ManagedPolicy.fromManagedPolicyName(this, 'boundary-policy', 'default-permission-boundary'),
      assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
      description: 'Example role...',
      path: '/app/',
      roleName: 'my-role'
    })

    table.grantReadData(iamRole)

But if I import the IAM role from another stack it does the reported behaviour:

    const { iamRole } = props

    const encryptionKey = new Key(this, 'MyKey', {
      enableKeyRotation: true,
    })

    const table = new Table(this, 'MyTable', {
      partitionKey: { name: 'id', type: AttributeType.STRING },
      tableName: 'my-table',
      encryption: TableEncryption.CUSTOMER_MANAGED,
      encryptionKey
    })

    table.grantReadData(iamRole)
heikkima commented 1 year ago

I discovered that the issue is most likely in the stack's environment configurations.

In my CDK project I have two stacks. First stack which I create IAM roles and the second where I create dynamodb table. In the project I use an existing KMS key (created outside of the CDK project) to encrypt the dynamodb table, so I use Key.fromLookup() function to import it inside the dynamodb stack. For Key.fromLookup() function to work I need to configure env: { account: '2383838383', region: 'eu-west-1' } in the stack's instance options. The IAM stack instance is configured: env: { region: 'eu-west-1' }

If I modify IAM stack's instance options to env: { account: '2383838383', region: 'eu-west-1' } then the correct KMS key arn is added to the IAM role's inline policy, otherwise * is used

khushail commented 1 year ago

Hi @heikkima , I tried to repro the issue creating mentioned stacks but could not succeed with multiple configurations. Could you please share the full code(including stacks and multiple configs) and provide more insights on this ?

heikkima commented 1 year ago

@khushail I created a public repository where you can find the whole source code to replicate this issue https://github.com/heikkima/aws-cdk-issue-23991

khushail commented 1 year ago

Thanks @heikkima for sharing the repo. I was able to reproduce the issue and could confirm the issue as stated by you.

Although this seems valid, I am marking this issue as p2, which means that we are unable to work on this immediately. We use +1s to help prioritize our work, and are happy to revaluate this issue based on community feedback. You can reach out to the cdk.dev community on Slack to solicit support for reprioritization.