How do I build Resource ARNs in CDK?

1k views Asked by At

Using the C# CDK library, I'm building various IAM roles that are used to limit permissions for my CI/CD pipelines to deploy Elastic Beanstalk applications. Right now, I set the Resources property of my PolicyStatementProps object to ["*"], but this is far too permissive.

Using the AWSServiceRoleForElasticBeanstalk managed policy as an example to go by, I see they add ARNs like the following:

"arn:aws:cloudformation:*:*:stack/awseb-*"

I imagine I'll want something like this for my custom IAM role, but I'm not sure how to build these resource ARNs using the CDK. I feel like this shouldn't be just a hard-coded string due to the dynamic and variable nature of the infrastructure itself, but I don't have the experience to know for sure.

I do know that I want to limit the ARN to only specific accounts (which is * in the example above, instead of a real account ID). Wildcards are probably appropriate to keep it simple, especially if there's no way to use the EB-specific objects in my CDK code to obtain the resource ARNs to attach to my role's inline policy automatically.

What is the best and most idiomatic method of setting up the resource ARNs in my custom IAM role?

2

There are 2 answers

0
fedonev On BEST ANSWER

Applying least-privilege permissions is a fundamental AWS security best practice. What counts as "least privilege" depends on the context. Sometimes "*" is the least-privilege option, often it is not.

The CDK helps with permissions in several ways:

  1. Higher level constructs will sometimes add the necessary permissions under the hood. For instance, the Lambda addEventSource method will add the permissions appropriate for the source (e.g. allow Lambda to poll a SQS Queue event source).
  2. Constructs expose their ARNs as a property. For instance, properties like DynamoDB table's tableArn property can be passed around in your code. The CDK converts the property to a reference that CloudFormation resolves at deploy-time.
  3. Constructs often have permissions-related methods, like the Lambda function's grantInvoke and addPermission methods, that help with adding permissions. Note that these do not automatically enforce least priviledge.
  4. The CDK exposes ARN manipulation methods as an alternative to assembling an ARN yourself with string interpolation. For instance, the Stack.formatArn method conveniently re-uses the Stack's partition, account and region by default.
  5. Consider adding the cdk-nag package's AwsSolutionsChecks construct to your app. It checks your template against a set of standard rules. Some of the default rules are relevant to IAM permissions. For instance, cdk-nag will complain if you use an AWS managed policy or if your policies include wildcards.
0
Pahud Hsieh On

According to Amazon resource name format for Elastic Beanstalk, if you need to build the application ARN, you can use Stack.formatArn, e.g.

// Builds "arn:<PARTITION>:elasticbeanstalk:<REGION>:<ACCOUNT>:application:AppName"

const resourceArn = cdk.Stack.of(this).formatArn({
  service: 'elasticbeanstalk',
  resource: 'application',
  resourceName: 'AppName',
  arnFormat: cdk.ArnFormat.COLON_RESOURCE_NAME,
});

new CfnOutput(stack, 'ARN', { value: resourceArn };

You get the Output: arn:aws:elasticbeanstalk:us-east-1:<deducted>:application:AppName