pipelines: default behavior created overly permissive policy
andreprawira opened this issue · comments
Describe the bug
im using the pipelines construct to deploy resources cross account through the pipelines. When the pipeline kicks in, it will create 2 roles (1 in the account where the pipeline is created, and another 1 in the account where we deploy the resources), one of the resources the pipeline deploy is an IAM role named xxxxx-deploy-role-<account-id>-<region->
that has an inline policy named default
this is what is inside the default
inline policy (along with other stuff)
{
"Condition": {
"StringEquals": {
"kms:ViaService": "s3.us-east-2.amazonaws.com"
}
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "PipelineCrossAccountArtifactsKey"
},
The problem of this policy is that it creates a problem in our SecurityHub findings
My question is, is there a way to make this policy not overly permissive instead of supressing the finding in the SecurityHub? Or other alternatives that i cant think of? Thx
Expected Behavior
The default
inline policy isnt overly permissive
Current Behavior
The overly permissive default
inline policy is found to be a problem in SecurityHub findings
Reproduction Steps
please view the description above
Possible Solution
No response
Additional Information/Context
No response
CDK CLI Version
2.143.0
Framework Version
No response
Node.js Version
20.13.0
OS
windows
Language
Python
Language Version
3.9.16
Other information
No response
@andreprawira , thanks for reporting this.
Default role is created by CDK to assume to initiate a deployment in this environment- Code ref - and which adds the KMS:Decrypt policy.
AFAIK, the default role policy can't be changed. One has to take measures to bypass it.
I have checked the feature flags but did not notice any flag which could help restrict the policies created.
cc : @pahud
@khushail how do i bypass it in cdk?
This role seems to be the deploy-role
created when you first cdk bootstrap
the account/region and it should be
cdk-hnb659fds-deploy-role-<YOUR_ACCOUNT_ID>-<REGION>
Can you confirm if it's the role you mentioned?
What’s happening for x-account deployment pipeline:
-
pipeline account A would have a codebuild phase that run
cdk synth
and another phase forcdk deploy
using the synthesized cloudassembly. -
In that deploy phase, codebuild would run
cdk deploy
as a role from Account A -
What’s happening here is this role would assume the
cdk-hnb659fds-deploy-role-<YOUR_ACCOUNT_ID>-<REGION>
of account B so it could run the cloudformation SDK calls to deploy account B as that deploy-role. -
cdk-hnb659fds-deploy-role-<YOUR_ACCOUNT_ID>-<REGION>
this role is provisioned when youcdk bootstrap
account B, not created by the pipeline.
@pahud its not that role, its the role that is created by CDK in account B (Where we deploy the actual resources, not the pipeline, the pipeline is in account A), in my end the role name is cdk-<@aws-cdk/core:bootstrapQualifier>-deploy-role-<account-number>-us-east-1
and below is the full default
inline policy that it has
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"cloudformation:CreateChangeSet",
"cloudformation:DeleteChangeSet",
"cloudformation:DescribeChangeSet",
"cloudformation:DescribeStacks",
"cloudformation:ExecuteChangeSet",
"cloudformation:CreateStack",
"cloudformation:UpdateStack"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "CloudFormationPermissions"
},
{
"Condition": {
"StringNotEquals": {
"s3:ResourceAccount": "<my-account-id>"
}
},
"Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*",
"s3:Abort*",
"s3:DeleteObject*",
"s3:PutObject*"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "PipelineCrossAccountArtifactsBucket"
},
{
"Condition": {
"StringEquals": {
"kms:ViaService": "s3.us-east-1.amazonaws.com"
}
},
"Action": [
"kms:Decrypt",
"kms:DescribeKey",
"kms:Encrypt",
"kms:ReEncrypt*",
"kms:GenerateDataKey*"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "PipelineCrossAccountArtifactsKey"
},
{
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::<my-account-id>:role/cdk-<@aws-cdk/core:bootstrapQualifier>-cfn-exec-role-<my-account-id>-us-east-1",
"Effect": "Allow"
},
{
"Action": [
"cloudformation:DescribeStackEvents",
"cloudformation:GetTemplate",
"cloudformation:DeleteStack",
"cloudformation:UpdateTerminationProtection",
"sts:GetCallerIdentity"
],
"Resource": "*",
"Effect": "Allow",
"Sid": "CliPermissions"
},
{
"Action": [
"s3:GetObject*",
"s3:GetBucket*",
"s3:List*"
],
"Resource": [
"arn:aws:s3:::cdk-<@aws-cdk/core:bootstrapQualifier>-assets-<my-account-id>-us-east-1",
"arn:aws:s3:::cdk-<@aws-cdk/core:bootstrapQualifier>-assets-<my-account-id>-us-east-1/*"
],
"Effect": "Allow",
"Sid": "CliStagingBucket"
},
{
"Action": [
"ssm:GetParameter"
],
"Resource": [
"arn:aws:ssm:us-east-1:<my-account-id>:parameter/cdk-bootstrap/<@aws-cdk/core:bootstrapQualifier>/version"
],
"Effect": "Allow",
"Sid": "ReadVersion"
}
]
}
that inline rule is what triggers securityhub findings
its the role that is created by CDK in account B (Where we deploy the actual resources, not the pipeline, the pipeline is in account A), in my end the role name is cdk-<@aws-cdk/core:bootstrapQualifier>-deploy-role--us-east-1 and below is the full default inline policy that it has
Hi,
The cdk-<@aws-cdk/core:bootstrapQualifier>-deploy-role-<account-number>-us-east-1
role you mentioned in account B is created when you cdk bootstrap
on account B, which is defined here.
Per How does bootstrapping work:
Resources and their configuration that are used by the CDK are defined in an AWS CloudFormation template. This template is created and managed by the CDK team. For the latest version of this template, see bootstrap-template.yaml in the aws-cdk GitHub repository.
To bootstrap an environment, you use the AWS CDK Command Line Interface (AWS CDK CLI) cdk bootstrap command. The CDK CLI retrieves the template and deploys it to AWS CloudFormation as a stack, known as the bootstrap stack. By default, the stack name is CDKToolkit. By deploying this template, CloudFormation provisions the resources in your environment. After deployment, the bootstrap stack will appear in the AWS CloudFormation console of your environment.
You can also customize bootstrapping by modifying the template or by using CDK CLI options with the cdk bootstrap command.
My questions:
- Why do you believe
cdk-<@aws-cdk/core:bootstrapQualifier>-deploy-role-<account-number>-us-east-1
of account B is actually created by account A? - Can you check the cloudformation console on Account B, view the Resources of the
CDKToolkit
stack and see if you can find this IAM role resource in theCDKToolkit
stack?
You can use AWS CLI to check that as well.
From Account B:
aws cloudformation list-stack-resources \
--stack-name CDKToolkit \
--query 'StackResourceSummaries[?ResourceType==`AWS::IAM::Role`].[ResourceType, PhysicalResourceId]' \
--output text
You should see this
AWS::IAM::Role cdk-hnb659fds-cfn-exec-role-<AWS_ACCOUNT_ID>-us-east-1
AWS::IAM::Role cdk-hnb659fds-deploy-role-<AWS_ACCOUNT_ID>-us-east-1
AWS::IAM::Role cdk-hnb659fds-file-publishing-role-<AWS_ACCOUNT_ID>-us-east-1
AWS::IAM::Role cdk-hnb659fds-image-publishing-role-<AWS_ACCOUNT_ID>-us-east-1
AWS::IAM::Role cdk-hnb659fds-lookup-role-<AWS_ACCOUNT_ID>-us-east-1
They are the IAM roles created when you cdk bootstrap
Account B.
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.
Comments on closed issues and PRs are hard for our team to see. If you need help, please open a new issue that references this one.