Open patrickdomnick opened 2 years ago
Hey @Crapatrick,
thanks for opening the issue. Can you share a little bit more how you implement Permission Boundaries with Aspects?
Thanks, Adam
Sure we are applying the boundary like this:
import { CfnRole } from '@aws-cdk/aws-iam';
import { Annotations, CfnResource, IAspect, IConstruct } from '@aws-cdk/core';
export class IamRoleAttachPermissionBoundary implements IAspect {
public visit(node: IConstruct): void {
// See that we're dealing with a CfnRole
if (node instanceof CfnRole ) {
if (!node.permissionsBoundary) {
node.permissionsBoundary = 'arn:aws:iam::07354411483:policy/cdk-bootstrap-boundary-base-boundary';
}
} else if ( node instanceof CfnResource && node.cfnResourceType == 'AWS::IAM::Role' ) {
node.addPropertyOverride('PermissionsBoundary', 'arn:aws:iam::07354411483:policy/cdk-bootstrap-boundary-base-boundary');
}
}
}
Thanks @Crapatrick! And can you also show how you use the Aspect (where do you apply it)?
Permission Boundary part already discussed here https://github.com/aws/aws-cdk/issues/3242?
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.
Thanks @Crapatrick! And can you also show how you use the Aspect (where do you apply it)?
We are using it on the App level. Meaning it should be applied to all Stacks.
Permission Boundary part already discussed here #3242?
This looks like the solution which we are currently using. Is it now? However, because of the nature of nested stacks and SAM, these roles can not be changed as it is a fixed construct. I will work on a minimal example featuring a RDS with a Single Rotation Lambda and this IAM Aspect with Permission Boundary.
@patrickdomnick any updates here? Do you maybe have that example?
Thanks, Adam
Hi there, sorry for the long silence. I had tried a few different approaches which were unsuccessful. Anyway, here is a small examples with some additional information:
import { Vpc } from "@aws-cdk/aws-ec2";
import { CfnRole } from "@aws-cdk/aws-iam";
import { DatabaseInstance, DatabaseInstanceEngine } from "@aws-cdk/aws-rds";
import { CfnFunction } from "@aws-cdk/aws-sam";
import { App, CfnResource, Construct, Stack, StackProps } from "@aws-cdk/core";
// Example Stack Created by Projen
export class MyStack extends Stack {
constructor(scope: Construct, id: string, props: StackProps = {}) {
super(scope, id, props);
// Use some existing VPC or create a new one
const vpc = new Vpc(this, "Default");
// Create any Database
const db = new DatabaseInstance(this, "Database", {
engine: DatabaseInstanceEngine.POSTGRES,
vpc: vpc,
});
// Add Rotation for User
db.addRotationSingleUser();
}
}
// Set Environment Values for CDK
const env = {
account: process.env.CDK_DEFAULT_ACCOUNT,
region: process.env.CDK_DEFAULT_REGION,
};
// Create new App for the Stack
const app = new App();
const stack = new MyStack(app, "rdsrotation", { env });
// Apply boundary to every Role
const boundary = `arn:aws:iam::${env.account}:policy/cdk-bootstrap-boundary-base-boundary`;
stack.node.children.forEach((node) => {
// Works just fine for everything Cloudformation related
if (node instanceof CfnRole) {
if (!node.permissionsBoundary) {
node.permissionsBoundary = boundary;
}
} else if (
node instanceof CfnResource &&
node.cfnResourceType == "AWS::IAM::Role"
) {
node.addPropertyOverride("PermissionsBoundary", boundary);
} else if (node instanceof CfnFunction) {
// We have a sam.Application which is not compatible with boundary
// This function is in a new Stack and no Boundary will be applied
// We also can use Globals because we are using CloudFormation with a Application
node.permissionsBoundary = boundary;
}
});
// The Cloudformation Role can only create Roles with this $boundary attached to it
/*
{
"Condition": {
"StringEquals": {
"iam:PermissionsBoundary": [
"arn:aws:iam::*:policy/cdk-bootstrap-boundary-base-boundary"
]
}
},
"Action": [
"iam:CreateRole",
"iam:AttachRolePolicy",
"iam:PutRole*",
"iam:DetachRolePolicy",
"iam:DeleteRolePolicy"
],
"Resource": [
"*",
],
"Effect": "Allow"
},
...a lot of wildcard permissions to create resources
*/
app.synth();
@peterwoodworth I'm leaving this one for you to triage or reassign 🙂.
Are there any updates on this perhaps? I am currently running in the same problem.
This cannot be configured currently through the specified application when using Serverless::Application
. I've brought up a request to the template owners (SecretsManager team) to allow this configurability in the template.
In the meantime, instead of using SAM (which our methods use under the hood), you can deploy your own password rotation lambda. All of our rotation lambdas are posted here: https://github.com/aws-samples/aws-secrets-manager-rotation-lambdas
Unfortunately the request for permission boundary support has been open for over 2 years on the rotation lambda project side: https://github.com/aws-samples/aws-secrets-manager-rotation-lambdas/issues/27
I don't suppose there is any chance CDK will provide a workaround by not using SAM under the hood?
Facing similar challenge. Anyone that has a workaround?
We are facing same issue, do you have any known workaround?
Description
Using RDS Secrets Rotation will create a SAM Stack which does not apply IAM Permission Boundaries via Aspects because they are in a Nested Stack.
Use Case
Our Cloudformation Role can only create IAM Roles with attached Permission Boundaries, which we roll out via Aspects.
Proposed Solution
Use a different approach for the Secrets Rotation Lambda which does not rely on SAM.
Other information
No response
Acknowledge