Reputation: 1928
Some new roles are created during execution of cdk-pipelines. How can we force attachment of Permission Boundary to these newly created role?
Background: Our AWS account only allow creation of role with a specific permission boundary. Role creation will fail if no permission bounary is specified.
My CDK project failed when it tries to create new roles within the pipeline.
API: iam:CreateRole User: arn:aws:sts::305326993135:assumed-role/cdk-hnb659fds-cfn-exec-role-305326993135-ap-southeast-1/AWSCloudFormation is not authorized to perform: iam:CreateRole on resource: arn:aws:iam::305326993135:role/whitespace-web-cloudfront-CustomS3AutoDeleteObject-16P4QGQ0QPJIR with an explicit deny
Upvotes: 1
Views: 3976
Reputation: 41
Theres a new runtime context property that works
Add this to your cdk json
"@aws-cdk/core:permissionsBoundary": {
"name": "YourPermissionBoundaryPolicyName"
}
You wont require an aspect, it will automatically attach to all created roles.
Upvotes: 3
Reputation: 1388
You don't need an aspect for adding permissions boundary globally anymore because the latest versions of CDK support this out of the box:
// This imports an existing policy.
const boundary = iam.ManagedPolicy.fromManagedPolicyArn(this, 'Boundary', 'arn:aws:iam::123456789012:policy/boundary');
// This creates a new boundary
const boundary2 = new iam.ManagedPolicy(this, 'Boundary2', {
statements: [
new iam.PolicyStatement({
effect: iam.Effect.DENY,
actions: ['iam:*'],
resources: ['*'],
}),
],
});
// Directly apply the boundary to a Role you create
declare const role: iam.Role;
iam.PermissionsBoundary.of(role).apply(boundary);
// Apply the boundary to an Role that was implicitly created for you
declare const fn: lambda.Function;
iam.PermissionsBoundary.of(fn).apply(boundary);
// Apply the boundary to all Roles in a stack
iam.PermissionsBoundary.of(this).apply(boundary);
// Remove a Permissions Boundary that is inherited, for example from the Stack level
declare const customResource: CustomResource;
iam.PermissionsBoundary.of(customResource).clear();
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_iam-readme.html#permissions-boundaries https://docs.aws.amazon.com/cdk/api/v2/python/aws_cdk.aws_iam/PermissionsBoundary.html
Upvotes: 3
Reputation: 1928
I found following class from somewhere when I searched for solution some time ago. (Sorry, cannot remember where is the origin)
import cdk = require("@aws-cdk/core");
export class PermissionsBoundary implements cdk.IAspect {
private readonly permissionsBoundaryArn: string;
constructor(permissionBoundaryArn: string) {
this.permissionsBoundaryArn = permissionBoundaryArn;
}
public visit(node: cdk.IConstruct): void {
if (
cdk.CfnResource.isCfnResource(node) &&
node.cfnResourceType === "AWS::IAM::Role"
) {
node.addPropertyOverride(
"PermissionsBoundary",
this.permissionsBoundaryArn
);
}
}
}
In your code, add permission boudary to your pipeline stack, where AWS_POLICY_PERM_BOUNDARY
is ARN of your permission boundary.
cdk.Aspects.of(pipelineStack).add(
new PermissionsBoundary(AWS_POLICY_PERM_BOUNDARY)
);
Upvotes: 0
Reputation: 2400
The Automatically generated roles of any construct within CDK can be accessed and modified with the your_construct.Role
attribute. You can then use (using python since im most familiar, but they exist in all CDK languages) various methods like your_construct.Role.add_to_principle_policy
or add_policy
to add additional statements to the existing in-line policy or even entirely new ones (from the aws_iam.PolicyStatement
or aws_iam.Policy
constructs.)
You can also define a role yourself using the aws_iam.Role
constructs and attach it to the pipeline (using the role
property of its constructor). If you do that, it overrides the automatically generated role so make sure you know all the permissions that role would need before attaching it and you have defined them yourself (This is actually a good end goal in any case as it allows you to lock down and give minimal permissions to all your constructs in order to have good best practice security)
Upvotes: 0