-
Notifications
You must be signed in to change notification settings - Fork 3.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(iot-alpha): support for account audit configuration (#31661)
### Issue # (if applicable) Closes #31663. ### Reason for this change Cloudformation supports create an account audit configuration but AWS CDK doesn't support it. ### Description of changes - Define `IAccountAuditConfiguration` - Define `AccountAuditConfiguration` class and `AccountAuditConfigurationProps` I couldn't find documentation regarding the required policies for the role when executing an audit, but when enabling the audit configuration through the management console, it was set to use a "AWSIoTDeviceDefenderAudit" managed policy. This implementation follows that same approach. <img width="624" alt="スクリーンショット 2024-10-05 15 05 10" src="https://github.com/user-attachments/assets/61f9d0bb-2606-4b2d-9c8f-8245f7f47c68"> ### 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) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
- Loading branch information
1 parent
cff1fcd
commit fc19571
Showing
15 changed files
with
1,244 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
{ | ||
"exclude": [ | ||
"no-unused-type:@aws-cdk/aws-iot-alpha.ActionConfig", | ||
"props-physical-name:@aws-cdk/aws-iot-alpha.LoggingProps" | ||
"props-physical-name:@aws-cdk/aws-iot-alpha.LoggingProps", | ||
"props-physical-name:@aws-cdk/aws-iot-alpha.AccountAuditConfigurationProps" | ||
] | ||
} |
287 changes: 287 additions & 0 deletions
287
packages/@aws-cdk/aws-iot-alpha/lib/audit-configuration.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,287 @@ | ||
import { Resource, Stack, IResource } from 'aws-cdk-lib/core'; | ||
import { Construct } from 'constructs'; | ||
import * as iot from 'aws-cdk-lib/aws-iot'; | ||
import * as iam from 'aws-cdk-lib/aws-iam'; | ||
import * as sns from 'aws-cdk-lib/aws-sns'; | ||
|
||
/** | ||
* Represents AWS IoT Audit Configuration | ||
*/ | ||
export interface IAccountAuditConfiguration extends IResource { | ||
/** | ||
* The account ID | ||
* @attribute | ||
*/ | ||
readonly accountId: string; | ||
} | ||
|
||
/** | ||
* The types of audit checks | ||
* | ||
* @see https://docs.aws.amazon.com/iot-device-defender/latest/devguide/device-defender-audit-checks.html | ||
*/ | ||
export interface CheckConfiguration { | ||
/** | ||
* Checks the permissiveness of an authenticated Amazon Cognito identity pool role. | ||
* | ||
* For this check, AWS IoT Device Defender audits all Amazon Cognito identity pools that have been used to connect to the AWS IoT message broker | ||
* during the 31 days before the audit is performed. | ||
* | ||
* @default true | ||
*/ | ||
readonly authenticatedCognitoRoleOverlyPermissiveCheck?: boolean; | ||
|
||
/** | ||
* Checks if a CA certificate is expiring. | ||
* | ||
* This check applies to CA certificates expiring within 30 days or that have expired. | ||
* | ||
* @default true | ||
*/ | ||
readonly caCertificateExpiringCheck?: boolean; | ||
|
||
/** | ||
* Checks the quality of the CA certificate key. | ||
* | ||
* The quality checks if the key is in a valid format, not expired, and if the key meets a minimum required size. | ||
* | ||
* This check applies to CA certificates that are ACTIVE or PENDING_TRANSFER. | ||
* | ||
* @default true | ||
*/ | ||
readonly caCertificateKeyQualityCheck?: boolean; | ||
|
||
/** | ||
* Checks if multiple devices connect using the same client ID. | ||
* | ||
* @default true | ||
*/ | ||
readonly conflictingClientIdsCheck?: boolean; | ||
|
||
/** | ||
* Checks if a device certificate is expiring. | ||
* | ||
* This check applies to device certificates expiring within 30 days or that have expired. | ||
* | ||
* @default true | ||
*/ | ||
readonly deviceCertificateExpiringCheck?: boolean; | ||
|
||
/** | ||
* Checks the quality of the device certificate key. | ||
* | ||
* The quality checks if the key is in a valid format, not expired, signed by a registered certificate authority, | ||
* and if the key meets a minimum required size. | ||
* | ||
* @default true | ||
*/ | ||
readonly deviceCertificateKeyQualityCheck?: boolean; | ||
|
||
/** | ||
* Checks if multiple concurrent connections use the same X.509 certificate to authenticate with AWS IoT. | ||
* | ||
* @default true | ||
*/ | ||
readonly deviceCertificateSharedCheck?: boolean; | ||
|
||
/** | ||
* Checks if device certificates are still active despite being revoked by an intermediate CA. | ||
* | ||
* @default true | ||
*/ | ||
readonly intermediateCaRevokedForActiveDeviceCertificatesCheck?: boolean; | ||
|
||
/** | ||
* Checks the permissiveness of a policy attached to an authenticated Amazon Cognito identity pool role. | ||
* | ||
* @default true | ||
*/ | ||
readonly iotPolicyOverlyPermissiveCheck?: boolean; | ||
|
||
/** | ||
* Checks if an AWS IoT policy is potentially misconfigured. | ||
* | ||
* Misconfigured policies, including overly permissive policies, can cause security incidents like allowing devices access to unintended resources. | ||
* | ||
* This check is a warning for you to make sure that only intended actions are allowed before updating the policy. | ||
* | ||
* @default true | ||
*/ | ||
readonly ioTPolicyPotentialMisConfigurationCheck?: boolean; | ||
|
||
/** | ||
* Checks if a role alias has access to services that haven't been used for the AWS IoT device in the last year. | ||
* | ||
* @default true | ||
*/ | ||
readonly iotRoleAliasAllowsAccessToUnusedServicesCheck?: boolean; | ||
|
||
/** | ||
* Checks if the temporary credentials provided by AWS IoT role aliases are overly permissive. | ||
* | ||
* @default true | ||
*/ | ||
readonly iotRoleAliasOverlyPermissiveCheck?: boolean; | ||
|
||
/** | ||
* Checks if AWS IoT logs are disabled. | ||
* | ||
* @default true | ||
*/ | ||
readonly loggingDisabledCheck?: boolean; | ||
|
||
/** | ||
* Checks if a revoked CA certificate is still active. | ||
* | ||
* @default true | ||
*/ | ||
readonly revokedCaCertificateStillActiveCheck?: boolean; | ||
|
||
/** | ||
* Checks if a revoked device certificate is still active. | ||
* | ||
* @default true | ||
*/ | ||
readonly revokedDeviceCertificateStillActiveCheck?: boolean; | ||
|
||
/** | ||
* Checks if policy attached to an unauthenticated Amazon Cognito identity pool role is too permissive. | ||
* | ||
* @default true | ||
*/ | ||
readonly unauthenticatedCognitoRoleOverlyPermissiveCheck?: boolean; | ||
} | ||
|
||
/** | ||
* Properties for defining AWS IoT Audit Configuration | ||
*/ | ||
export interface AccountAuditConfigurationProps { | ||
/** | ||
* The target SNS topic to which audit notifications are sent. | ||
* | ||
* @default - no notifications are sent | ||
*/ | ||
readonly targetTopic?: sns.ITopic; | ||
|
||
/** | ||
* Specifies which audit checks are enabled and disabled for this account. | ||
* | ||
* @default - all checks are enabled | ||
*/ | ||
readonly checkConfiguration?: CheckConfiguration; | ||
} | ||
|
||
/** | ||
* Defines AWS IoT Audit Configuration | ||
*/ | ||
export class AccountAuditConfiguration extends Resource implements IAccountAuditConfiguration { | ||
/** | ||
* Import an existing AWS IoT Audit Configuration | ||
* | ||
* @param scope The parent creating construct (usually `this`) | ||
* @param id The construct's name | ||
* @param accountId The account ID | ||
*/ | ||
public static fromAccountId(scope: Construct, id: string, accountId: string): IAccountAuditConfiguration { | ||
class Import extends Resource implements IAccountAuditConfiguration { | ||
public readonly accountId = accountId; | ||
} | ||
return new Import(scope, id); | ||
} | ||
|
||
/** | ||
* The account ID | ||
* @attribute | ||
*/ | ||
public readonly accountId: string; | ||
|
||
constructor(scope: Construct, id: string, props?: AccountAuditConfigurationProps) { | ||
super(scope, id); | ||
|
||
this.accountId = Stack.of(this).account; | ||
|
||
const auditRole = new iam.Role(this, 'AuditRole', { | ||
assumedBy: new iam.ServicePrincipal('iot.amazonaws.com'), | ||
managedPolicies: [ | ||
iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSIoTDeviceDefenderAudit'), | ||
], | ||
}); | ||
|
||
new iot.CfnAccountAuditConfiguration(this, 'Resource', { | ||
accountId: this.accountId, | ||
auditCheckConfigurations: this.renderAuditCheckConfigurations(props?.checkConfiguration), | ||
auditNotificationTargetConfigurations: this.renderAuditNotificationTargetConfigurations(props?.targetTopic), | ||
roleArn: auditRole.roleArn, | ||
}); | ||
} | ||
|
||
/** | ||
* Render the audit notification target configurations | ||
*/ | ||
private renderAuditNotificationTargetConfigurations( | ||
targetTopic?: sns.ITopic, | ||
): iot.CfnAccountAuditConfiguration.AuditNotificationTargetConfigurationsProperty | undefined { | ||
if (!targetTopic) { | ||
return undefined; | ||
} | ||
|
||
const notificationRole = new iam.Role(this, 'NotificationRole', { | ||
assumedBy: new iam.ServicePrincipal('iot.amazonaws.com'), | ||
inlinePolicies: { | ||
NotificationPolicy: new iam.PolicyDocument({ | ||
statements: [ | ||
new iam.PolicyStatement({ | ||
actions: ['sns:Publish'], | ||
resources: [targetTopic.topicArn], | ||
}), | ||
], | ||
}), | ||
}, | ||
}); | ||
|
||
return { | ||
sns: { | ||
enabled: true, | ||
targetArn: targetTopic.topicArn, | ||
roleArn: notificationRole.roleArn, | ||
}, | ||
}; | ||
} | ||
|
||
/** | ||
* Render the audit check configurations | ||
*/ | ||
private renderAuditCheckConfigurations(checkConfiguration?: CheckConfiguration): iot.CfnAccountAuditConfiguration.AuditCheckConfigurationsProperty { | ||
return { | ||
authenticatedCognitoRoleOverlyPermissiveCheck: | ||
this.renderAuditCheckConfiguration(checkConfiguration?.authenticatedCognitoRoleOverlyPermissiveCheck), | ||
caCertificateExpiringCheck: this.renderAuditCheckConfiguration(checkConfiguration?.caCertificateExpiringCheck), | ||
caCertificateKeyQualityCheck: this.renderAuditCheckConfiguration(checkConfiguration?.caCertificateKeyQualityCheck), | ||
conflictingClientIdsCheck: this.renderAuditCheckConfiguration(checkConfiguration?.conflictingClientIdsCheck), | ||
deviceCertificateExpiringCheck: this.renderAuditCheckConfiguration(checkConfiguration?.deviceCertificateExpiringCheck), | ||
deviceCertificateKeyQualityCheck: this.renderAuditCheckConfiguration(checkConfiguration?.deviceCertificateKeyQualityCheck), | ||
deviceCertificateSharedCheck: this.renderAuditCheckConfiguration(checkConfiguration?.deviceCertificateSharedCheck), | ||
intermediateCaRevokedForActiveDeviceCertificatesCheck: | ||
this.renderAuditCheckConfiguration(checkConfiguration?.intermediateCaRevokedForActiveDeviceCertificatesCheck), | ||
iotPolicyOverlyPermissiveCheck: this.renderAuditCheckConfiguration(checkConfiguration?.iotPolicyOverlyPermissiveCheck), | ||
ioTPolicyPotentialMisConfigurationCheck: this.renderAuditCheckConfiguration(checkConfiguration?.ioTPolicyPotentialMisConfigurationCheck), | ||
iotRoleAliasAllowsAccessToUnusedServicesCheck: | ||
this.renderAuditCheckConfiguration(checkConfiguration?.iotRoleAliasAllowsAccessToUnusedServicesCheck), | ||
iotRoleAliasOverlyPermissiveCheck: this.renderAuditCheckConfiguration(checkConfiguration?.iotRoleAliasOverlyPermissiveCheck), | ||
loggingDisabledCheck: this.renderAuditCheckConfiguration(checkConfiguration?.loggingDisabledCheck), | ||
revokedCaCertificateStillActiveCheck: this.renderAuditCheckConfiguration(checkConfiguration?.revokedCaCertificateStillActiveCheck), | ||
revokedDeviceCertificateStillActiveCheck: | ||
this.renderAuditCheckConfiguration(checkConfiguration?.revokedDeviceCertificateStillActiveCheck), | ||
unauthenticatedCognitoRoleOverlyPermissiveCheck: | ||
this.renderAuditCheckConfiguration(checkConfiguration?.unauthenticatedCognitoRoleOverlyPermissiveCheck), | ||
}; | ||
} | ||
|
||
/** | ||
* Render the audit check configuration | ||
*/ | ||
private renderAuditCheckConfiguration(check?: boolean): iot.CfnAccountAuditConfiguration.AuditCheckConfigurationProperty | undefined { | ||
return check === false ? undefined : { enabled: true }; | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.