[aws-kinesis] Read permissions to stream doesn't include kinesis:DescribeStream
See original GitHub issueWhen granting an IAM role read permissions on a Kinesis stream, the resulting policy does not include the “kinesis:DescribeStream” permission, which is needed for at least Kinesis Firehose to read from it, perhaps other consumers as well.
Reproduction Steps
from aws_cdk import (
core,
aws_kinesis as kds,
aws_iam as iam,
)
class DFPStack(core.NestedStack):
def __init__(
self, scope: core.Construct, id: str, *, stream=kds.Stream, **kwargs
) -> None:
self.kfh_reader = iam.Role(
self,
"KFHReader",
assumed_by=iam.ServicePrincipal(service="firehose.amazonaws.com"),
)
self.stream = stream
self.stream.grant_read(self.kfh_reader)
Results in the following output:
"KFHReaderDefaultPolicy98F05724": {
"Type": "AWS::IAM::Policy",
"Properties": {
"PolicyDocument": {
"Statement": [
{
"Action": [
"kinesis:DescribeStreamSummary",
"kinesis:GetRecords",
"kinesis:GetShardIterator",
"kinesis:ListShards",
"kinesis:SubscribeToShard"
],
"Effect": "Allow",
"Resource": {
"Ref": "referencetoLongboatkinesisNestedStackkinesisNestedStackResourceFA86427BOutputsLongboatkinesisstreamDE86A4D8Arn"
}
}
],
"Version": "2012-10-17"
},
"PolicyName": "KFHReaderDefaultPolicy98F05724",
"Roles": [
{
"Ref": "KFHReader8A09BD1B"
}
]
},
"Metadata": {
"aws:cdk:path": "Longboat/DFPStack/KFHReader/DefaultPolicy/Resource"
}
},
What did you expect to happen?
I expected the resulting IAM role and policy to actually be able to read from the supplied Kinesis stream when used by Kinesis Firehose. This would require the “kinesis:DescribeStream” permission to be given.
What actually happened?
Stack creation fails, because the “kinesis:DescribeStream” permission is lacking.
Cloudformation gives the following error:
Role arn:aws:iam::<account>:role/<role_name> is not authorized to perform: kinesis:DescribeStream on resource arn:aws:kinesis:eu-west-1:<account>:stream/<stream_name>. (Service: Firehose, Status Code: 400, Request ID: <request_id>, Extended Request ID: <extended_request_id>
Environment
- CLI Version: 1.66.0 (build 459488d)
- Framework Version: 1.66.0
- Node.js Version: v12.19.0
- OS: KDE Neon 5.19 (Ubuntu 20.04 focal)
- Language (Version): Python 3.8.5
Other
This is 🐛 Bug Report
Issue Analytics
- State:
- Created 3 years ago
- Reactions:3
- Comments:6 (3 by maintainers)
Top GitHub Comments
Hi @Alexander-D-Jensen - thanks for sharing the code. It was very helpful.
So there are actually two separate issues here:
First is that
stream.grantRead
does not grantkinesis:DescribeStream
operation. This was actually intentional because theDescribeStream
API is deprecated in favor ofDescribeStreamSummary
. Seems likeCfnDeliveryStream
still uses this deprecated API however.We will consider adding this action back to the policy.
Second is that the
CfnDeliveryStream
is created before the necessary policies are applied to the kinesis reader role. What happens here is that the reader policy is a separate resource (AWS::IAM::Policy
) that is created after the role is created, and since theCfnDeliveryStream
depends only on the role, not the policy, this race condition occurs.This type of thing is exactly what an L2 for a
CfnDeliveryStream
can solve, but until we have that, the way to tackle this problem is exactly what you did.I’ve created an issue for the L2 construct to make sure we consider this scenario when we start working on it.
Sure @iliapolo! I’ve redacted some info (account numbers, company name etc.) and a few tags, as well as services, modules etc. which aren’t of any consequence. Below should be as close to a complete setup needed to replicate the error as I can easily get.
This is stack A, the stack which had the issue:
This is stack B, which creates the Kinesis stream
And finally, we have the stack which coordinates the whole thing:
I hope this helps 😃