Home > Blockchain >  AWS CDK grant decrypt permission to Kinesis Data Stream's AWS managed CMK
AWS CDK grant decrypt permission to Kinesis Data Stream's AWS managed CMK

Time:01-27

I'm provisioning Kinesis Data Stream with AWS managed KMS key as well as Delivery Stream reading from stream. There's a problem on how to add decrypt policy on delivery stream role for managed key. The code is showing below and the issue is that getting key with 'aws/kinesis' alias doesn't work unless I have a way to add dependency to 'kinesisStream' resource. But there's no 'addDependsOn' method in IKey-interface. How can I ensure that Stream (and it's managed KMS key) is created before I try to fetch that key?

const kinesisStream = new kinesis.Stream(this, 'kinesisStream', {
  streamName: `my-stream`,
  shardCount: 1,
  encryption: kinesis.StreamEncryption.MANAGED,
  retentionPeriod: cdk.Duration.days(1),
});

const kinesisStreamRole = new iam.Role(this, 'kinesisStreamRole', {
  assumedBy: new iam.ServicePrincipal('firehose.amazonaws.com'),
});

// How to add dependency to kinesisStream resource to ensure it's created before trying to fetch KMS key using 'fromLookup'?
// Now getting:
// [Error at /my-stack] Could not find any key with alias named aws/kinesis
const managedKinesisKmsKey = kms.Key.fromLookup(this, 'managedKinesisKmsKey', {
  aliasName: 'aws/kinesis',
});

const managedKinesisKmsKeyPolicy = new iam.Policy(this, 'managedKinesisKmsKeyPolicy', {
    roles: [kinesisStreamRole],
    statements: [
        new iam.PolicyStatement({
            effect: iam.Effect.ALLOW,
            resources: [managedKinesisKmsKey.keyArn],
            actions: ['kms:Decrypt'],
        }),
    ],
});

CodePudding user response:

You can use the key alias to grant the access to this AWS managed key. We know that the alias for Kinesis service specific AWS managed key is "aws/kinesis".

AWS developer guide for using aliases to control access to KMS keys: https://docs.aws.amazon.com/kms/latest/developerguide/alias-authorization.html

CodePudding user response:

Working solution

const kinesisStream = new kinesis.Stream(this, 'kinesisStream', {
    streamName: `my-stream`, 
    shardCount: 1, 
    encryption: kinesis.StreamEncryption.MANAGED, 
    retentionPeriod: cdk.Duration.days(1),
});

const kinesisStreamRole = new iam.Role(this, 'kinesisStreamRole', {
    assumedBy: new iam.ServicePrincipal('firehose.amazonaws.com'),
});

const managedKinesisKmsKeyPolicy = new iam.Policy(this, 'managedKinesisKmsKeyPolicy', {
    roles: [kinesisStreamRole],
    statements: [
        new iam.PolicyStatement({
            effect: iam.Effect.ALLOW,
            resources: ['*'],
            actions: ['kms:Decrypt'],
            conditions: {
                StringLike: {
                    'kms:RequestAlias': 'aws/kinesis',
                },
            },
        }),
    ],
});
  • Related