Skip to content
This repository was archived by the owner on Feb 19, 2025. It is now read-only.

Commit 16596e5

Browse files
verinderpbverind
andauthored
release v1.2.0 (#25)
Co-authored-by: Verinder Singh <[email protected]>
1 parent add1e52 commit 16596e5

File tree

139 files changed

+5985
-1944
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

139 files changed

+5985
-1944
lines changed

CHANGELOG.md

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Changelog
22

3+
## [1.2.0] - 2023-08-08
4+
5+
### Added
6+
7+
- Integrated CfnGuard and Checkov as additional IaC scanning tools for pattern validation.
8+
- Added user role based access to the solution UI
9+
10+
### Fixed
11+
12+
- Pull request comments max size issue.
13+
314
## [1.1.0] - 2023-05-03
415

516
### Added

README.md

+42-2
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,15 @@ By default, all solution data (S3 buckets, DynamoDB tables) will be removed when
178178
179179
**Identity Provider configuration (optional)**
180180
181-
Users can sign into the solution web UI either directly through the user pool, or federate through a third-party identity provider (IdP) that supports OpenID Connect authentication. To federate through a third-party identity provider via OpenID Connect, add the following parameters to `source/cdk.json`:
181+
Users can sign into the solution web UI either directly through the user pool, or federate through a third-party identity provider (IdP) that supports OpenID Connect authentication.
182+
183+
The solution by default creates two user groups in Amazon Cognito user pool:
184+
- SYSTEM_ADMIN: This user group has permissions to access all pages in the UI. The default user created by the solution is automatically added to this group when the solution is deployed.
185+
- PATTERN_PUBLISHER: This group has permissions to create, update and view patterns. This group also allows you to view pattern attributes. To update or delete pattern attributes you would need to be in SYSTEM_ADMIN group.
186+
187+
If you are federating through a third-party identity provider via OpenID Connect, please add a claim type of `group` in your IdP and map the roles that should relate to `SYSTEM_ADMIN` and `PATTERN_PUBLISHER` roles in Amazon Cognito. In absence of this mapping the federated user would only have read only access to the solution UI.
188+
189+
To federate through a third-party identity provider via OpenID Connect, add the following parameters to `source/cdk.json`:
182190
183191
```
184192
"identityProviderInfo": {
@@ -202,11 +210,14 @@ Example: Identity provider configuration to federate through Auth0.
202210
"oidcIssuer": "https://dev-abcdefgx.us.auth0.com",
203211
"attributeMapping": {
204212
"email": "EMAIL",
205-
"username": "sub"
213+
"username": "sub",
214+
"custom:groups": "groups"
206215
}
207216
}
208217
```
209218
219+
It's important to note that if you want to use user groups from your IdP please make sure you add `attributeMapping` to map your groups claim name with `custom:groups` (as in the example above).
220+
210221
**AWS WAF configuration (optional)**
211222
212223
This solution provisions AWS WAF Web ACL for API Gateway resources, by default. For a CloudFront distribution WAF Web ACL, the solution allows users to associate their existing AWS WAF Web ACL for CloudFront with the CloudFront distribution created by the solution. Refer to the configuration options below for configuring your AWS WAF Web ACL. Note: The WAF configuration is optional. If you need to configure it, add this information to `source/cdk.json`.
@@ -231,6 +242,35 @@ Example WAF Configuration:
231242
}
232243
```
233244
245+
**Security scanning tool configuration (optional)**
246+
247+
This solution uses [CfnNag](https://github.com/stelligent/cfn_nag) as the default IaC security scanning tool. In addition to CfnNag, this solution also supports below security scanning tools:
248+
249+
- [AWS CloudFormation Guard](https://github.com/aws-cloudformation/cloudformation-guard):
250+
AWS CloudFormation Guard is a policy-as-code evaluation tool that is open source and can be used for checking the security posture of AWS CloudFormation templates. The solution also supports [AWS Rule Registry](https://github.com/aws-cloudformation/aws-guard-rules-registry) and allows users to configure [managed rule sets](https://github.com/aws-cloudformation/aws-guard-rules-registry#managed-rule-sets) against which the CloudFormation templates should be evaluated.
251+
252+
- [Checkov](https://www.checkov.io/):
253+
Checkov is another policy-as-code security evaluation tool which has over 1000 built in policies that covers security and compliance best practices for AWS
254+
255+
If you need to configure it, add this information to `source/cdk.json`.
256+
257+
```
258+
"securityScanTool": {
259+
"name": "<Security scan tool name. Valid values are CfnNag, CfnGuard, Checkov>",
260+
"cfnGuardManagedRuleSets": [(This is optional and only applicable if the name property is 'CfnGuard'. If not specified it defaults to 'wa-Security-Pillar' and 'wa-Reliability-Pillar'). A list of AWS managed rule sets against which the security posture of CloudFormation template needs to be evaluated.]
261+
}
262+
```
263+
264+
Example securityScanTool configuration:
265+
266+
```
267+
"securityScanTool": {
268+
"name": "CfnGuard",
269+
"cfnGuardManagedRuleSets": [ "wa-Security-Pillar" ]
270+
}
271+
```
272+
273+
234274
### Build and deploy
235275
236276
1. Clone the solution source code from the GitHub repository.

source/.eslintrc.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module.exports = {
1818
tsconfigRootDir: __dirname,
1919
project: ['./tsconfig.json'],
2020
},
21-
plugins: ['@typescript-eslint', 'header'],
21+
plugins: ['@typescript-eslint', 'header', 'import'],
2222
rules: {
2323
'header/header': [2, path.join(__dirname, 'LicenseHeader.txt')],
2424

@@ -35,7 +35,7 @@ module.exports = {
3535
{ selector: 'typeLike', format: ['PascalCase'] },
3636
],
3737
'@typescript-eslint/no-confusing-void-expression': ['error'],
38-
'@typescript-eslint/no-duplicate-imports': ['error'],
38+
'import/no-duplicates': ['error'],
3939
'@typescript-eslint/no-empty-interface': ['warn'],
4040
'@typescript-eslint/no-inferrable-types': ['warn'],
4141
'@typescript-eslint/no-invalid-void-type': ['error'],

source/bin/blueprint-service-infra.ts

+31-21
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ if (githubConfig && !githubConfig.githubOrganization) {
5858
throw new Error('githubConfig is missing GitHubOrganization');
5959
}
6060

61+
// Validate securityScanTool config input, if not provided, use CfnNag as default
62+
const supportedScanningTools = ['CfnNag', 'CfnGuard', 'Checkov'];
63+
let securityScanTool = app.node.tryGetContext('securityScanTool');
64+
securityScanTool = securityScanTool ?? { name: 'CfnNag' };
65+
66+
if (!supportedScanningTools.includes(securityScanTool.name)) {
67+
throw new Error(`Unsupported security scanning tool: ${securityScanTool.name}`);
68+
}
69+
6170
const stackName = 'ApoStack';
6271

6372
const blueprintStack = new BlueprintStack(app, {
@@ -77,6 +86,7 @@ const blueprintStack = new BlueprintStack(app, {
7786
wafInfo,
7887
removalPolicy,
7988
logLevel,
89+
securityScanTool,
8090
});
8191

8292
Aspects.of(app).add(new AwsSolutionsChecks());
@@ -89,7 +99,7 @@ Aspects.of(app).add(
8999
solutionName,
90100
applicationType: 'AWS-Solutions',
91101
applicationName: 'Application-Pattern-Orchestrator-on-AWS',
92-
})
102+
}),
93103
);
94104

95105
// CFk Nag suppression for UpdateBlueprintInfrastructureProjectRole default policy
@@ -102,7 +112,7 @@ NagSuppressions.addResourceSuppressionsByPath(
102112
reason: 'The IAM permission has wildcard attached as suffix to specific permission.',
103113
},
104114
],
105-
true
115+
true,
106116
);
107117

108118
// CFk Nag suppression for BlueprintArtifactsApiRole default policy
@@ -115,7 +125,7 @@ NagSuppressions.addResourceSuppressionsByPath(
115125
reason: 'The IAM permission has wildcard attached as suffix to specific permission.',
116126
},
117127
],
118-
true
128+
true,
119129
);
120130

121131
// CFk Nag suppression for CDKBucketDeployment service role
@@ -128,7 +138,7 @@ NagSuppressions.addResourceSuppressionsByPath(
128138
reason: 'Needs managed policy AWSLambdaBasicExecutionRole',
129139
},
130140
],
131-
true
141+
true,
132142
);
133143
NagSuppressions.addResourceSuppressionsByPath(
134144
blueprintStack,
@@ -139,7 +149,7 @@ NagSuppressions.addResourceSuppressionsByPath(
139149
reason: 'The IAM permission has wildcard attached as suffix to specific permission.',
140150
},
141151
],
142-
true
152+
true,
143153
);
144154
NagSuppressions.addResourceSuppressionsByPath(
145155
blueprintStack,
@@ -150,7 +160,7 @@ NagSuppressions.addResourceSuppressionsByPath(
150160
reason: 'Needs managed policy AWSLambdaBasicExecutionRole',
151161
},
152162
],
153-
true
163+
true,
154164
);
155165
NagSuppressions.addResourceSuppressionsByPath(
156166
blueprintStack,
@@ -161,7 +171,7 @@ NagSuppressions.addResourceSuppressionsByPath(
161171
reason: 'The IAM permission has wildcard attached as suffix to specific permission.',
162172
},
163173
],
164-
true
174+
true,
165175
);
166176

167177
// CFk Nag suppression for LogRetention default policy
@@ -174,7 +184,7 @@ NagSuppressions.addResourceSuppressionsByPath(
174184
reason: 'Needs managed policy AWSLambdaBasicExecutionRole.',
175185
},
176186
],
177-
true
187+
true,
178188
);
179189
NagSuppressions.addResourceSuppressionsByPath(
180190
blueprintStack,
@@ -185,7 +195,7 @@ NagSuppressions.addResourceSuppressionsByPath(
185195
reason: 'Autogenerated by CDK.',
186196
},
187197
],
188-
true
198+
true,
189199
);
190200

191201
// CFk Nag suppression for UpdateBlueprintInfraStatusLambda default policy
@@ -198,7 +208,7 @@ NagSuppressions.addResourceSuppressionsByPath(
198208
reason: 'The IAM permission has wildcard attached as suffix to specific permission.',
199209
},
200210
],
201-
true
211+
true,
202212
);
203213

204214
// CDK Nag CloudFront Distribution Suppression
@@ -219,7 +229,7 @@ NagSuppressions.addResourceSuppressionsByPath(
219229
reason: 'This is subject to customer and it uses Cloudfront certificates',
220230
},
221231
],
222-
true
232+
true,
223233
);
224234

225235
// CDK Nag API Gateway suppressions
@@ -235,7 +245,7 @@ NagSuppressions.addResourceSuppressionsByPath(
235245
id: 'AwsSolutions-COG4',
236246
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
237247
},
238-
]
248+
],
239249
);
240250
NagSuppressions.addResourceSuppressionsByPath(
241251
blueprintStack,
@@ -249,7 +259,7 @@ NagSuppressions.addResourceSuppressionsByPath(
249259
id: 'AwsSolutions-COG4',
250260
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
251261
},
252-
]
262+
],
253263
);
254264
NagSuppressions.addResourceSuppressionsByPath(
255265
blueprintStack,
@@ -263,7 +273,7 @@ NagSuppressions.addResourceSuppressionsByPath(
263273
id: 'AwsSolutions-COG4',
264274
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
265275
},
266-
]
276+
],
267277
);
268278
NagSuppressions.addResourceSuppressionsByPath(
269279
blueprintStack,
@@ -277,7 +287,7 @@ NagSuppressions.addResourceSuppressionsByPath(
277287
id: 'AwsSolutions-COG4',
278288
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
279289
},
280-
]
290+
],
281291
);
282292
NagSuppressions.addResourceSuppressionsByPath(
283293
blueprintStack,
@@ -291,7 +301,7 @@ NagSuppressions.addResourceSuppressionsByPath(
291301
id: 'AwsSolutions-COG4',
292302
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
293303
},
294-
]
304+
],
295305
);
296306
NagSuppressions.addResourceSuppressionsByPath(
297307
blueprintStack,
@@ -305,7 +315,7 @@ NagSuppressions.addResourceSuppressionsByPath(
305315
id: 'AwsSolutions-COG4',
306316
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
307317
},
308-
]
318+
],
309319
);
310320
NagSuppressions.addResourceSuppressionsByPath(
311321
blueprintStack,
@@ -319,7 +329,7 @@ NagSuppressions.addResourceSuppressionsByPath(
319329
id: 'AwsSolutions-COG4',
320330
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
321331
},
322-
]
332+
],
323333
);
324334
NagSuppressions.addResourceSuppressionsByPath(
325335
blueprintStack,
@@ -333,7 +343,7 @@ NagSuppressions.addResourceSuppressionsByPath(
333343
id: 'AwsSolutions-COG4',
334344
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
335345
},
336-
]
346+
],
337347
);
338348
NagSuppressions.addResourceSuppressionsByPath(
339349
blueprintStack,
@@ -347,7 +357,7 @@ NagSuppressions.addResourceSuppressionsByPath(
347357
id: 'AwsSolutions-COG4',
348358
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
349359
},
350-
]
360+
],
351361
);
352362
NagSuppressions.addResourceSuppressionsByPath(
353363
blueprintStack,
@@ -361,7 +371,7 @@ NagSuppressions.addResourceSuppressionsByPath(
361371
id: 'AwsSolutions-COG4',
362372
reason: 'API Gateway OPTIONS method is created implicitly by CDK',
363373
},
364-
]
374+
],
365375
);
366376

367377
// CfnNag suppressions

source/blueprint-infrastructure/.eslintrc.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module.exports = {
1818
tsconfigRootDir: __dirname,
1919
project: ['./tsconfig.json'],
2020
},
21-
plugins: ['@typescript-eslint', 'header'],
21+
plugins: ['@typescript-eslint', 'header', 'import'],
2222
rules: {
2323
'header/header': [2, path.join(__dirname, 'LicenseHeader.txt')],
2424

@@ -35,7 +35,7 @@ module.exports = {
3535
{ selector: 'typeLike', format: ['PascalCase'] },
3636
],
3737
'@typescript-eslint/no-confusing-void-expression': ['error'],
38-
'@typescript-eslint/no-duplicate-imports': ['error'],
38+
'import/no-duplicates': ['error'],
3939
'@typescript-eslint/no-empty-interface': ['warn'],
4040
'@typescript-eslint/no-inferrable-types': ['warn'],
4141
'@typescript-eslint/no-invalid-void-type': ['error'],

source/blueprint-infrastructure/bin/blueprint-infrastructure.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ const blueprintId: string = app.node.tryGetContext('blueprintId');
3232
const blueprintType: BlueprintType = app.node.tryGetContext('blueprintType');
3333

3434
const blueprintInfrastructureSharedConfigJson = app.node.tryGetContext(
35-
'blueprintInfrastructureSharedConfigJson'
35+
'blueprintInfrastructureSharedConfigJson',
3636
);
3737

3838
const repositoryName = app.node.tryGetContext('repositoryName');
@@ -65,7 +65,7 @@ if (githubConnectionArn && githubRepositoryOwner) {
6565
const infraStack = new BlueprintInfrastructureStack(
6666
app,
6767
`BlueprintInfrastructureStack${blueprintId}`,
68-
blueprintInfraStackProps
68+
blueprintInfraStackProps,
6969
);
7070
Aspects.of(infraStack).add(new CfnNagCustomResourceSuppressionAspect());
7171
Aspects.of(infraStack).add(new CfnNagServiceRoleDefaultPolicyResourceSuppressionAspect());

source/blueprint-infrastructure/lambda/codepipeline/blueprint/common.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { DynamoDBDocumentClient, GetCommand } from '@aws-sdk/lib-dynamodb';
1717

1818
export async function getPatternById(
1919
ddbDocClient: DynamoDBDocumentClient,
20-
patternId: string
20+
patternId: string,
2121
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2222
): Promise<Record<string, any> | undefined> {
2323
const params = {

0 commit comments

Comments
 (0)