Skip to content

Commit

Permalink
fix: Allow KMS access for lambda role (#18)
Browse files Browse the repository at this point in the history
Allows the lambda role to publish to the encrypted SNS topic.
  • Loading branch information
joostvanderborg authored Oct 27, 2023
1 parent 050b660 commit dca4c41
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
6 changes: 4 additions & 2 deletions src/ApiStage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ export class ApiStage extends Stage {
Tags.of(this).add('Project', Statics.projectName);
Aspects.of(this).add(new PermissionsBoundaryAspect());

const storageStack = new StorageStack(this, 'storage');
const configuration = props.configuration;

const apiStack = new ApiStack(this, 'api', { configuration: props.configuration } );
const storageStack = new StorageStack(this, 'storage', { configuration });

const apiStack = new ApiStack(this, 'api', { configuration } );
apiStack.addDependency(storageStack);
}
}
43 changes: 39 additions & 4 deletions src/StorageStack.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
import { Duration, Stack } from 'aws-cdk-lib';
import { Duration, Stack, StackProps } from 'aws-cdk-lib';
import { AttributeType, BillingMode, Table, TableEncryption } from 'aws-cdk-lib/aws-dynamodb';
import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam';
import { Key } from 'aws-cdk-lib/aws-kms';
import { Bucket, BucketEncryption, ObjectOwnership } from 'aws-cdk-lib/aws-s3';
import { Secret } from 'aws-cdk-lib/aws-secretsmanager';
import { StringParameter } from 'aws-cdk-lib/aws-ssm';
import { Construct } from 'constructs';
import { Configurable } from './Configuration';
import { Statics } from './statics';


interface StorageStackProps extends StackProps, Configurable {};

/**
* Contains all API-related resources.
*/
export class StorageStack extends Stack {
constructor(scope: Construct, id: string) {
super(scope, id);
constructor(scope: Construct, id: string, props: StorageStackProps) {
super(scope, id, props);

const key = this.key();
/**
Expand Down Expand Up @@ -48,13 +53,16 @@ export class StorageStack extends Stack {
this.addParameters();
}

private key() {
private key(crossAccountIds?: string[]) {
const crossAccountPrincipalArns = this.crossAccountIdArns(crossAccountIds);
const key = new Key(this, 'kmskey', {
enableKeyRotation: true,
description: 'encryption key for user data',
alias: `${Statics.projectName}/user-data`,
});

this.allowCrossAccountKeyAccess(crossAccountPrincipalArns, key);

// Store key arn to be used in other stacks/projects
new StringParameter(this, 'key', {
stringValue: key.keyArn,
Expand All @@ -64,6 +72,33 @@ export class StorageStack extends Stack {
return key;
}

private allowCrossAccountKeyAccess(crossAccountPrincipalArns: string[] | null, key: Key) {
if (crossAccountPrincipalArns) {
key.addToResourcePolicy(new PolicyStatement({
effect: Effect.ALLOW,
actions: [
'kms:GenerateDataKey',
'kms:Decrypt',
],
resources: [key.keyArn],
conditions: {
ArnLike: {
'aws:PrincipalArn': crossAccountPrincipalArns,
},
},
}), false);
}
}

private crossAccountIdArns(crossAccountIds: string[] | undefined) {
if (crossAccountIds && crossAccountIds.length > 0) {
return crossAccountIds.map(
(accountId) => `arn:aws:iam::${accountId}:role/storesubmissions-lambda-role`,
);
}
return null;
}

private addArnToParameterStore(id: string, arn: string, name: string) {
new StringParameter(this, id, {
stringValue: arn,
Expand Down

0 comments on commit dca4c41

Please sign in to comment.