Skip to content

Commit 9ad383d

Browse files
feat(iot): device certificate age check audit configuration (#33816)
### Issue # (if applicable) None ### Reason for this change AWS IoT now supports for new audit configuration about device certificate age check. https://docs.aws.amazon.com/iot-device-defender/latest/devguide/device-certificate-age-check.html ### Description of changes - Add `deviceCertificateAgeCheck` to `CheckConfiguration` - To enable audit configuraiton - Add `deviceCertificateAgeCheckDuration` to `CheckConfiguration` - To configure threshold duration in days ### Describe any new or updated permissions being added None ### Description of how you validated changes Add both unit and integ tests ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) BREAKING CHANGE: By default, `deviceDertificateAgeCheck` is automatically enabled. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 3c3df15 commit 9ad383d

11 files changed

+214
-36
lines changed

packages/@aws-cdk/aws-iot-alpha/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ new iot.AccountAuditConfiguration(this, 'AuditConfiguration', {
124124
// disabled
125125
caCertificateKeyQualityCheck: false,
126126
conflictingClientIdsCheck: false,
127+
deviceCertificateAgeCheck: false,
127128
deviceCertificateExpiringCheck: false,
128129
deviceCertificateKeyQualityCheck: false,
129130
deviceCertificateSharedCheck: false,
@@ -140,6 +141,21 @@ new iot.AccountAuditConfiguration(this, 'AuditConfiguration', {
140141
});
141142
```
142143

144+
To configure [the device certificate age check](https://docs.aws.amazon.com/iot-device-defender/latest/devguide/device-certificate-age-check.html), you can specify the duration for the check:
145+
146+
```ts
147+
import { Duration } from 'aws-cdk-lib';
148+
149+
new iot.AccountAuditConfiguration(this, 'AuditConfiguration', {
150+
checkConfiguration: {
151+
deviceCertificateAgeCheck: true,
152+
// The default value is 365 days
153+
// Valid values range from 30 days (minimum) to 3652 days (10 years, maximum)
154+
deviceCertificateAgeCheckDuration: Duration.days(365),
155+
},
156+
});
157+
```
158+
143159
### Scheduled Audit
144160

145161
You can create a [scheduled audit](https://docs.aws.amazon.com/iot-device-defender/latest/devguide/AuditCommands.html#device-defender-AuditCommandsManageSchedules) that is run at a specified time interval. Checks must be enabled for your account by creating `AccountAuditConfiguration`.

packages/@aws-cdk/aws-iot-alpha/lib/audit-configuration.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Resource, Stack, IResource } from 'aws-cdk-lib/core';
1+
import { Resource, Stack, IResource, Duration } from 'aws-cdk-lib/core';
22
import { Construct } from 'constructs';
33
import * as iot from 'aws-cdk-lib/aws-iot';
44
import * as iam from 'aws-cdk-lib/aws-iam';
@@ -59,6 +59,25 @@ export interface CheckConfiguration {
5959
*/
6060
readonly conflictingClientIdsCheck?: boolean;
6161

62+
/**
63+
* Checks when a device certificate has been active for a number of days greater than or equal to the number you specify.
64+
*
65+
* @default true
66+
*/
67+
readonly deviceCertificateAgeCheck?: boolean;
68+
69+
/**
70+
* The duration used to check if a device certificate has been active
71+
* for a number of days greater than or equal to the number you specify.
72+
*
73+
* Valid values range from 30 days (minimum) to 3652 days (10 years, maximum).
74+
*
75+
* You cannot specify a value for this check if `deviceCertificateAgeCheck` is set to `false`.
76+
*
77+
* @default - 365 days
78+
*/
79+
readonly deviceCertificateAgeCheckDuration?: Duration;
80+
6281
/**
6382
* Checks if a device certificate is expiring.
6483
*
@@ -201,6 +220,17 @@ export class AccountAuditConfiguration extends Resource implements IAccountAudit
201220
// Enhanced CDK Analytics Telemetry
202221
addConstructMetadata(this, props);
203222

223+
const deviceAgeCheckThreshold = props?.checkConfiguration?.deviceCertificateAgeCheckDuration;
224+
225+
if (deviceAgeCheckThreshold) {
226+
if (props?.checkConfiguration?.deviceCertificateAgeCheck === false) {
227+
throw new Error('You cannot specify a value for `deviceCertificateAgeCheckDuration` if `deviceCertificateAgeCheck` is set to `false`.');
228+
}
229+
if (!deviceAgeCheckThreshold.isUnresolved() && deviceAgeCheckThreshold.toDays() < 30 || deviceAgeCheckThreshold.toDays() > 3652) {
230+
throw new Error(`The device certificate age check threshold must be between 30 and 3652 days. got: ${deviceAgeCheckThreshold.toDays()} days.`);
231+
}
232+
}
233+
204234
this.accountId = Stack.of(this).account;
205235

206236
const auditRole = new iam.Role(this, 'AuditRole', {
@@ -261,6 +291,15 @@ export class AccountAuditConfiguration extends Resource implements IAccountAudit
261291
caCertificateExpiringCheck: this.renderAuditCheckConfiguration(checkConfiguration?.caCertificateExpiringCheck),
262292
caCertificateKeyQualityCheck: this.renderAuditCheckConfiguration(checkConfiguration?.caCertificateKeyQualityCheck),
263293
conflictingClientIdsCheck: this.renderAuditCheckConfiguration(checkConfiguration?.conflictingClientIdsCheck),
294+
deviceCertificateAgeCheck:
295+
checkConfiguration?.deviceCertificateAgeCheck !== false ?
296+
{
297+
enabled: true,
298+
configuration: {
299+
certAgeThresholdInDays: String(checkConfiguration?.deviceCertificateAgeCheckDuration?.toDays() ?? 365),
300+
},
301+
} :
302+
undefined,
264303
deviceCertificateExpiringCheck: this.renderAuditCheckConfiguration(checkConfiguration?.deviceCertificateExpiringCheck),
265304
deviceCertificateKeyQualityCheck: this.renderAuditCheckConfiguration(checkConfiguration?.deviceCertificateKeyQualityCheck),
266305
deviceCertificateSharedCheck: this.renderAuditCheckConfiguration(checkConfiguration?.deviceCertificateSharedCheck),

packages/@aws-cdk/aws-iot-alpha/test/audit-configuration.test.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ test('Default property', () => {
1515
CaCertificateExpiringCheck: { Enabled: true },
1616
CaCertificateKeyQualityCheck: { Enabled: true },
1717
ConflictingClientIdsCheck: { Enabled: true },
18+
DeviceCertificateAgeCheck: {
19+
Enabled: true,
20+
Configuration: {
21+
CertAgeThresholdInDays: '365',
22+
},
23+
},
1824
DeviceCertificateExpiringCheck: { Enabled: true },
1925
DeviceCertificateKeyQualityCheck: { Enabled: true },
2026
DeviceCertificateSharedCheck: { Enabled: true },
@@ -129,6 +135,29 @@ test('configure check configuration', () => {
129135
});
130136
});
131137

138+
test('throw error for configuring duration without enabling deviceCertificateAgeCheck', () => {
139+
const stack = new cdk.Stack();
140+
expect(() => new iot.AccountAuditConfiguration(stack, 'AccountAuditConfiguration', {
141+
checkConfiguration: {
142+
deviceCertificateAgeCheck: false,
143+
deviceCertificateAgeCheckDuration: cdk.Duration.days(1229),
144+
},
145+
})).toThrow('You cannot specify a value for `deviceCertificateAgeCheckDuration` if `deviceCertificateAgeCheck` is set to `false`.');
146+
});
147+
148+
test.each([
149+
cdk.Duration.days(29),
150+
cdk.Duration.days(3653),
151+
])('throw error for invalid duration %s', (duration) => {
152+
const stack = new cdk.Stack();
153+
expect(() => new iot.AccountAuditConfiguration(stack, 'AccountAuditConfiguration', {
154+
checkConfiguration: {
155+
deviceCertificateAgeCheck: true,
156+
deviceCertificateAgeCheckDuration: duration,
157+
},
158+
})).toThrow(`The device certificate age check threshold must be between 30 and 3652 days. got: ${duration.toDays()} days.`);
159+
});
160+
132161
test('import by Account ID', () => {
133162
const stack = new cdk.Stack();
134163

packages/@aws-cdk/aws-iot-alpha/test/integ.audit-configuration.js.snapshot/IotAuditConfigurationTestDefaultTestDeployAssert6A603D00.assets.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-iot-alpha/test/integ.audit-configuration.js.snapshot/IotAuditConfigurationTestStack.assets.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-iot-alpha/test/integ.audit-configuration.js.snapshot/IotAuditConfigurationTestStack.template.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,12 @@
8787
"ConflictingClientIdsCheck": {
8888
"Enabled": true
8989
},
90+
"DeviceCertificateAgeCheck": {
91+
"Configuration": {
92+
"CertAgeThresholdInDays": "1229"
93+
},
94+
"Enabled": true
95+
},
9096
"DeviceCertificateExpiringCheck": {
9197
"Enabled": true
9298
},

packages/@aws-cdk/aws-iot-alpha/test/integ.audit-configuration.js.snapshot/cdk.out

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-iot-alpha/test/integ.audit-configuration.js.snapshot/integ.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/@aws-cdk/aws-iot-alpha/test/integ.audit-configuration.js.snapshot/manifest.json

Lines changed: 56 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)