Skip to content

Commit

Permalink
docs: added security docs and escape hatches (#99)
Browse files Browse the repository at this point in the history
  • Loading branch information
rehanvdm authored Dec 13, 2024
1 parent 8b6e1a4 commit a3a99b5
Show file tree
Hide file tree
Showing 6 changed files with 326 additions and 13 deletions.
26 changes: 14 additions & 12 deletions docs/astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,11 @@ export default defineConfig({
{
label: 'Security',
items: [
// { label: 'Overview', slug: 'introduction'},
{ label: 'Service Control Policies', slug: 'components/security/service-deny-list'}, // Mention the service deny list
// { label: 'Permission Boundary', slug: 'introduction'},
// { label: 'SecurityHub', slug: 'introduction'},
// { label: 'Control Tower Controls', slug: 'introduction'},
{ label: 'SecurityHub', slug: 'components/security/security-hub'},
{ label: 'Control Tower Controls', slug: 'components/security/control-tower-controls'},
{ label: 'Service Deny Lists', slug: 'components/security/service-deny-list'}, // Change to SCPs when we support them externally and make the deny list a subheading
{ label: 'IAM Permission Boundary', slug: 'components/security/iam-permission-boundary'},

// { label: 'AWS Config', slug: 'introduction'},
// { label: 'AWS Guard Duty', slug: 'introduction'},
// { label: 'AWS Macie', slug: 'introduction'},
Expand Down Expand Up @@ -108,22 +108,24 @@ export default defineConfig({
}
],
},
{
label: 'Integration',
items: [
{ label: 'Exported SSM Parameters', slug: 'reference/integration/exported-ssm-parameters'},
{ label: 'CDK Client', slug: 'reference/integration/cdk-client'},
]
},
{
label: 'Reference',
items: [
// TODO: Complete docs
{ label: 'API', slug: 'reference/api'},
{ label: 'Defaults', slug: 'reference/defaults'},
{
label: 'Integration',
items: [
{ label: 'Exported SSM Parameters', slug: 'reference/integration/exported-ssm-parameters'},
{ label: 'CDK Client', slug: 'reference/integration/cdk-client'},
]
},
{ label: 'Scripts & commands', slug: 'reference/scripts-commands' },
{ label: 'Extending and Escape Hatches', slug: 'reference/extending-and-escape-hatches'},
{ label: 'Lake Formation TBAC strategy', slug: 'reference/lake-formation-tbac-recommended-strategy' },
{ label: 'Network Address', slug: 'reference/network-address'},

// { label: 'Roadmap', slug: 'introduction'},
// { label: 'Escape Hatches', slug: 'introduction'}, // How to extend and modify/add components
]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: Control Tower Controls
description: Control Tower Controls
---
import DualCode from '../../../../components/DualCode.astro';

The Data Landing Zone supports specifying Control Tower Controls using the `controlTowerControls` property. This property
applies controls to the entire organization and all accounts within it.

The example below demonstrates how to use DLZ defaults and add the `SH_SECRETS_MANAGER_3` control:

<DualCode>
<Fragment slot="ts">
```ts
import {App} from 'aws-cdk-lib';
import { DataLandingZone } from 'aws-data-landing-zone';

const app = new App();
const dlz = new DataLandingZone(app, {
organization: {
root: {
...
controls: [
...Defaults.rootControls(),
DlzControlTowerStandardControls.SH_SECRETS_MANAGER_3,
],
},
ous: ...
},
...
});
```
</Fragment>
<Fragment slot="python">
```python
import aws_cdk as cdk
import aws_data_landing_zone as dlz

app = cdk.App()
dlz.DataLandingZone(app,
organization=dlz.DLzOrganization(
root=dlz.RootOptions(
...
controls=[
*dlz.Defaults.root_controls(),
dlz.DlzControlTowerStandardControls.SH_SECRETS_MANAGER_3
]
),
...
)
```
</Fragment>
</DualCode>

## Defaults

The `Defaults.rootControls` function returns a list of commonly used Control Tower Controls based on best practices
and data management. You can find a detailed list of these controls in the code
[here](https://github.com/DataChefHQ/aws-data-landing-zone/blob/dfe6f6d7ea991aa37976fae41b9ab38c81a2748a/src/defaults.ts#L143).

## API References
- [DlzControlTowerEnabledControl](/reference/api/#dlzcontroltowerenabledcontrol)
- [DlzControlTowerControlFormat](/reference/api/#dlzcontroltowercontrolformat)
- [IDlzControlTowerControl](/reference/api/#idlzcontroltowercontrol)
- [DlzControlTowerStandardControls](/reference/api/#dlzcontroltowerstandardcontrols)
- [DlzControlTowerSpecializedControls](/reference/api/#dlzcontroltowerspecializedcontrols)
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
title: IAM Permission Boundary
description: IAM Permission Boundary
---
import DualCode from '../../../../components/DualCode.astro';

A permissions boundary uses a managed IAM policy to define the maximum permissions an
identity-based policy can grant to an IAM entity. This ensures that the entity can perform only actions permitted
by both its identity-based policies and the permissions boundary, effectively preventing unauthorized permission
escalation.

The Data Landing Zone enables specifying an IAM policy to be used as a permissions boundary for all IAM users and
roles. The DLZ creates a managed policy named `IamPolicyPermissionBoundaryPolicy` and enforces its attachment to all IAM
users and roles through a
[Service Control Policy](https://github.com/DataChefHQ/aws-data-landing-zone/blob/cd54815aa4c2bdc7f1ba2d91b18df914280553fb/src/constructs/organization-policies/service-control-policy.ts#L38).

The example below demonstrates a permissions boundary that allows listing S3 bucket contents (`s3:ListBucket`) and
downloading objects (`s3:GetObject`) across all S3 resources in the account. Note that the entity must also have matching
permissions in its identity-based policy to perform these actions. This policy is for demonstration purposes only, as
it has limited scope and usability.

<DualCode>
<Fragment slot="ts">
```ts
import {App} from 'aws-cdk-lib';
import { DataLandingZone } from 'aws-data-landing-zone';

const app = new App();
const dlz = new DataLandingZone(app, {
iamPolicyPermissionBoundary: {
policyStatement: {
effect: iam.Effect.ALLOW,
actions: [
's3:ListBucket',
's3:GetObject',
],
resources: ['*'],
},
},
...
});
```
</Fragment>
<Fragment slot="python">
```python
import aws_cdk as cdk
import aws_data_landing_zone as dlz

app = cdk.App()
dlz.DataLandingZone(app,
iam_policy_permission_boundary={
"policy_statement": {
"effect": iam.Effect.ALLOW,
"actions: [
's3:ListBucket',
's3:GetObject',
],
"resources": ["*"],
},
},
...
)
```
</Fragment>
</DualCode>


## API References
- [iamPolicyPermissionBoundary](/reference/api/#aws-data-landing-zone.DataLandingZoneProps.property.iamPolicyPermissionBoundary)

123 changes: 123 additions & 0 deletions docs/src/content/docs/components/security/security-hub.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
---
title: Security Hub
description: Security Hub
---
import DualCode from '../../../../components/DualCode.astro';

The Data Landing Zone integrates with Security Hub, utilizing the setup provided by Control Tower to enable Security Hub
in all regions of all accounts. Security Hub should be accessed through the Audit Account in the Security OU.

Security Hub notifications are delivered via Amazon SNS, with support for the following methods:
- **Email**: Each email address must confirm the notification opt-in the first time it is deployed.
- **Slack**: Notifications are sent to a designated Slack channel. The Slack workspace must be linked to the Management
Account. For setup details, see the SOP [AWS Chatbot and Slack Integration](sop-account-setup#aws-chatbot-and-slack-integration).

:::note
Email notifications are unstructured JSON and may appear messy. Slack notifications are well-formatted and easy to read.
:::

Below is an example of creating filters for findings based on their severity and workflow status. Notifications for
medium, high, and critical severity findings marked as "new" are sent to the `security-hub-high` Slack channel. A
separate filter for resolved and suppressed findings sends notifications to the `security-hub-resolved` Slack channel.

Using separate Slack channels helps manage the volume of notifications. Users interested in new findings can focus on
the `security-hub-high` channel, while others tracking resolved findings can monitor the `security-hub-resolved` channel.
This allows users to mute or unsubscribe from the channel they are not interested in.

<DualCode>
<Fragment slot="ts">
```ts
import {App} from 'aws-cdk-lib';
import { DataLandingZone } from 'aws-data-landing-zone';

const app = new App();
const dlz = new DataLandingZone(app, {
securityHubNotifications: [
{
id: 'notify-high',
severity: [
SecurityHubNotificationSeverity.MEDIUM,
SecurityHubNotificationSeverity.HIGH,
SecurityHubNotificationSeverity.CRITICAL,
],
workflowStatus: [
SecurityHubNotificationSWorkflowStatus.NEW,
],
notification: {
// emails: ['[email protected]'],
slack: {
slackChannelConfigurationName: 'security-hub-high',
slackWorkspaceId: 'YourWorkspaceId',
slackChannelId: 'YourChannelId',
},
},
},
{
id: 'notify-resolved',
workflowStatus: [
SecurityHubNotificationSWorkflowStatus.RESOLVED,
SecurityHubNotificationSWorkflowStatus.SUPPRESSED,
],
notification: {
// emails: ['[email protected]'],
slack: {
slackChannelConfigurationName: 'security-hub-resolved',
slackWorkspaceId: 'YourWorkspaceId',
slackChannelId: 'YourChannelId',
},
},
},
],
...
});
```
</Fragment>
<Fragment slot="python">
```python
import aws_cdk as cdk
import aws_data_landing_zone as dlz

app = cdk.App()
dlz.DataLandingZone(app,
security_hub_notifications=[
{
"id": "notify-high",
"severity": [
SecurityHubNotificationSeverity.MEDIUM,
SecurityHubNotificationSeverity.HIGH,
SecurityHubNotificationSeverity.CRITICAL,
],
"workflow_status": [SecurityHubNotificationSWorkflowStatus.NEW],
"notification": {
"slack": {
"slack_channel_configuration_name": "security-hub-high",
"slack_workspace_id": "YourWordspaceID",
"slack_channel_id": "YourChannelID",
},
},
},
{
"id": "notify-resolved",
"workflow_status": [
SecurityHubNotificationSWorkflowStatus.RESOLVED,
SecurityHubNotificationSWorkflowStatus.SUPPRESSED,
],
"notification": {
"slack": {
"slack_channel_configuration_name": "security-hub-resolved",
"slack_workspace_id": "YourWordspaceID",
"slack_channel_id": "YourChannelID",
},
},
},
],
...
)
```
</Fragment>
</DualCode>


## API References
- [SecurityHubNotification](/reference/api/#aws-data-landing-zone.SecurityHubNotification)

4 changes: 3 additions & 1 deletion docs/src/content/docs/reference/defaults.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,6 @@ and another for the DLZ-managed resources.
- [Defaults.vpcClassB3Private3Public](/components/networking/vpcs#defaults): Creates a VPC with three public and three
private subnets in the `eu-west-1` region.
- [Defaults.denyServiceList](/components/security/service-deny-list#defaults): Creates a list of services that should
be denied by default.
be denied by default.
- [Defaults.rootControls](/components/security/control-tower-controls#defaults): Specifies a list of commonly used
Control Tower Controls based on best practices and data management.
50 changes: 50 additions & 0 deletions docs/src/content/docs/reference/extending-and-escape-hatches.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
title: Extending and Escape Hatches
description: Extending and Escape Hatches
---
import DualCode from "../../../components/DualCode.astro";

The Data Landing Zone provides the flexibility to customize and extend stacks and their constructs. This section explains
how to extend the Data Landing Zone and use escape hatches to modify default behavior.

## Extending the Data Landing Zone

All stacks are accessible through the DLZ construct, enabling the addition or removal of constructs from these stacks.

Below is an example showing how to add an SNS topic to the management stack:

<DualCode>
<Fragment slot="ts">
```ts
import {App} from 'aws-cdk-lib';
import { DataLandingZone } from 'aws-data-landing-zone';

const app = new App();
const dlz = new DataLandingZone(app, { ... });

const topic = new sns.Topic(dlz.managementStack, "new-topic", {
displayName: "new-topic",
topicName: "new-topic",
});
```
</Fragment>
<Fragment slot="python">
```python
import aws_cdk as cdk
from aws_data_landing_zone import DataLandingZone
from aws_cdk import aws_sns as sns

app = cdk.App()
dlz = DataLandingZone(app, ... )

topic = sns.Topic(dlz.management_stack, "new-topic",
display_name="new-topic",
topic_name="new-topic")
```
</Fragment>
</DualCode>

## Escape Hatches

Constructs can be accessed and customized using common CDK [escape hatches](https://docs.aws.amazon.com/cdk/v2/guide/cfn_layer.html).
These include Aspects, using the `node` property, and the `addOverride` method.

0 comments on commit a3a99b5

Please sign in to comment.