aws / aws-cdk

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
https://aws.amazon.com/cdk
Apache License 2.0
11.68k stars 3.93k forks source link

(rds): Permission Boundary Aspect with Secret Rotation #19649

Open patrickdomnick opened 2 years ago

patrickdomnick commented 2 years ago

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

skinny85 commented 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

patrickdomnick commented 2 years ago

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');
    }
  }
}
skinny85 commented 2 years ago

Thanks @Crapatrick! And can you also show how you use the Aspect (where do you apply it)?

robertd commented 2 years ago

Permission Boundary part already discussed here https://github.com/aws/aws-cdk/issues/3242?

github-actions[bot] commented 2 years ago

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.

patrickdomnick commented 2 years ago

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.

skinny85 commented 2 years ago

@patrickdomnick any updates here? Do you maybe have that example?

Thanks, Adam

patrickdomnick commented 2 years ago

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();
skinny85 commented 2 years ago

@peterwoodworth I'm leaving this one for you to triage or reassign 🙂.

MitchWijt commented 2 years ago

Are there any updates on this perhaps? I am currently running in the same problem.

peterwoodworth commented 1 year ago

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

Saberos commented 1 year ago

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?

asifma commented 1 year ago

Facing similar challenge. Anyone that has a workaround?

RambabuPatina commented 2 months ago

We are facing same issue, do you have any known workaround?