Skip to content

Commit

Permalink
fix(codebuild): missing permissions for SecretsManager environment va…
Browse files Browse the repository at this point in the history
…riables (aws#12121)

When creating a CodeBuild Project that uses environment variables from SecretsManager,
the Project fails execution with:

```
AccessDeniedException: User: arn:aws:sts::828671620168:assumed-role/role
is not authorized to perform: secretsmanager:GetSecretValue on resource:
arn:aws:secretsmanager:us-west-2:123456789012:secret:my-secret-GXyUCE
```

The solution is to automatically grant the Project's Role permissions to read all
Secrets whose names were provided as environment variables.


----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
skinny85 authored Dec 22, 2020
1 parent 3d1ba38 commit 1a13d8f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 6 deletions.
34 changes: 28 additions & 6 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ export class Project extends ProjectBase {
this.projectName = this.getResourceNameAttribute(resource.ref);

this.addToRolePolicy(this.createLoggingPermission());
this.addParameterStorePermission(props);
this.addEnvVariablesPermissions(props.environmentVariables);
// add permissions to create and use test report groups
// with names starting with the project's name,
// unless the customer explicitly opts out of it
Expand Down Expand Up @@ -922,12 +922,13 @@ export class Project extends ProjectBase {
});
}

private addParameterStorePermission(props: ProjectProps) {
if (!props.environmentVariables) {
return;
}
private addEnvVariablesPermissions(environmentVariables: { [name: string]: BuildEnvironmentVariable } | undefined): void {
this.addParameterStorePermissions(environmentVariables);
this.addSecretsManagerPermissions(environmentVariables);
}

const resources = Object.values(props.environmentVariables)
private addParameterStorePermissions(environmentVariables: { [name: string]: BuildEnvironmentVariable } | undefined): void {
const resources = Object.values(environmentVariables || {})
.filter(envVariable => envVariable.type === BuildEnvironmentVariableType.PARAMETER_STORE)
.map(envVariable =>
// If the parameter name starts with / the resource name is not separated with a double '/'
Expand All @@ -951,6 +952,27 @@ export class Project extends ProjectBase {
}));
}

private addSecretsManagerPermissions(environmentVariables: { [name: string]: BuildEnvironmentVariable } | undefined): void {
const resources = Object.values(environmentVariables || {})
.filter(envVariable => envVariable.type === BuildEnvironmentVariableType.SECRETS_MANAGER)
.map(envVariable => Stack.of(this).formatArn({
service: 'secretsmanager',
resource: 'secret',
// we don't know the exact ARN of the Secret just from its name, but we can get close
resourceName: `${envVariable.value}-??????`,
sep: ':',
}));

if (resources.length === 0) {
return;
}

this.addToRolePolicy(new iam.PolicyStatement({
actions: ['secretsmanager:GetSecretValue'],
resources,
}));
}

private renderEnvironment(
env: BuildEnvironment = {},
projectVars: { [name: string]: BuildEnvironmentVariable } = {}): CfnProject.EnvironmentProperty {
Expand Down
38 changes: 38 additions & 0 deletions packages/@aws-cdk/aws-codebuild/test/test.project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -889,5 +889,43 @@ export = {

test.done();
},

"grants the Project's Role read permissions to the SecretsManager environment variables"(test: Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
new codebuild.PipelineProject(stack, 'Project', {
environmentVariables: {
'ENV_VAR1': {
type: codebuild.BuildEnvironmentVariableType.SECRETS_MANAGER,
value: 'my-secret',
},
},
});

// THEN
expect(stack).to(haveResourceLike('AWS::IAM::Policy', {
'PolicyDocument': {
'Statement': arrayWith({
'Action': 'secretsmanager:GetSecretValue',
'Effect': 'Allow',
'Resource': {
'Fn::Join': ['', [
'arn:',
{ Ref: 'AWS::Partition' },
':secretsmanager:',
{ Ref: 'AWS::Region' },
':',
{ Ref: 'AWS::AccountId' },
':secret:my-secret-??????',
]],
},
}),
},
}));

test.done();
},
},
};

0 comments on commit 1a13d8f

Please sign in to comment.