Skip to content

Commit

Permalink
Merge pull request #11 from aws-samples/release/v1.0.5
Browse files Browse the repository at this point in the history
Release/v1.0.5
  • Loading branch information
ach-mk authored Sep 12, 2024
2 parents 7ecf3c1 + bee836a commit 03fcac3
Show file tree
Hide file tree
Showing 28 changed files with 2,497 additions and 252 deletions.
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,25 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

## [1.0.5] - 2024/09/12

### Added
- You can now use the following queries:
- `cw_logs_scp_resource_perimeter` to list AWS API call `PutSubscriptionFilter` made by principals in the selected account on Amazon CloudWatch Logs destinations not owned by accounts in the same organization as the selected account.
- `dynamodb_scp_resource_perimeter` to list AWS API calls made by principals in the selected account on Amazon DynamoDB tables not owned by accounts in the same organization as the selected account.
- `ecr_scp_resource_perimeter` to list AWS API calls made by principals in the selected account on Amazon ECR repositories not owned by accounts in the same organization as the selected account.
- `events_scp_resource_perimeter` to list AWS API calls made by principals in the selected account on Amazon EventBridge buses not owned by accounts in the same organization as the selected account.
- `kms_scp_resource_perimeter` to list AWS API calls made by principals in the selected account on AWS KMS keys not owned by accounts in the same organization as the selected account.
- `secretsmanager_scp_resource_perimeter` to list AWS API calls made by principals in the selected account on AWS Secrets Manager secrets not owned by accounts in the same organization as the selected account
- `sns_scp_resource_perimeter` to list AWS API calls made by principals in the selected account on Amazon SNS topics not owned by accounts in the same organization as the selected account.
- `sqs_scp_resource_perimeter` to list AWS API calls made by principals in the selected account on Amazon SQS queues not owned by accounts in the same organization as the selected account.
- `sts_scp_resource_perimeter` to list AWS API calls `AssumeRole` made by principals in the selected account on AWS Identity and Access Management (IAM) roles not owned by accounts in the same organization as the selected account.


### Updated
- Previously, organizational unit (OU) boundaries applied only to accounts directly attached to an OU without any nested OUs beneath it. Now, you can set boundaries for accounts attached to OUs that have subsequent nested OUs within their hierarchy.
- Bump dependencies versions.


## [1.0.4] - 2024/07/02

Expand Down
228 changes: 1 addition & 227 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,233 +353,7 @@ The following is a high-level diagram of controls that compose a data perimeter:

## 5.2 Data perimeter helper usage examples

### 5.2.1 Identity perimeter


An [identity perimeter](https://aws.amazon.com/blogs/security/establishing-a-data-perimeter-on-aws-allow-only-trusted-identities-to-access-company-data/) is a set of coarse-grained preventative controls that help ensure that only **trusted identities** can access your resources.

If you want to enforce identity perimeter controls on your Amazon S3 buckets, you can start by crafting your bucket policy from the [s3_bucket_policy template](https://github.com/aws-samples/data-perimeter-policy-examples/blob/main/resource_based_policies/s3_bucket_policy.json) provided in the data perimeter policy examples repository:


```jsonc
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EnforceIdentityPerimeter",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::<my-data-bucket>",
"arn:aws:s3:::<my-data-bucket>/*"
],
"Condition": {
"StringNotEqualsIfExists": {
"aws:PrincipalOrgID": "<my-org-id>",
"aws:PrincipalAccount": [
"<load-balancing-account-id>",
"<third-party-account-a>",
"<third-party-account-b>"
]
},
"BoolIfExists": {
"aws:PrincipalIsAWSService": "false"
}
}
}
]
}
```

Replace the values of the `aws:PrincipalOrgID` and `aws:PrincipalAccount` condition keys based on what **trusted identities** mean for your organization and on your knowledge of the intended access patterns you need to support.

To assess the effects of the preceding policy before deployment, review your CloudTrail logs to learn **who** is performing API calls on your Amazon S3 buckets. To complete your analysis, obtain additional information about your environment:
- Are the principals that are performing the API calls part of your AWS organization?
- Are they service roles?
- Are they human roles?

`Data perimeter helper` provides a query that does this heavy lifting for you: [`s3_bucket_policy_identity_perimeter_org_boundary`](./data_perimeter_helper/queries/s3/s3_bucket_policy_identity_perimeter_org_boundary.py).


This query performs the following actions:
- Runs an Athena query to list all API calls made on Amazon S3 buckets that belong to a given AWS account, filtering out:
- API calls made by principals in the same AWS organization.
- API calls made by principals belonging to trusted accounts listed in the `data perimeter helper` [configuration file](./data_perimeter_helper/data_perimeter.yaml) (`identity_perimeter_trusted_account` parameter).
- API calls made by trusted identities listed in the `data perimeter helper` [configuration file](./data_perimeter_helper/data_perimeter.yaml) (`identity_perimeter_trusted_principal` parameter).
- If you have provided multiple AWS account IDs, `data perimeter helper` uses threading to perform concurrent queries to help you accelerate the review across your entire AWS organization.
- Provides query results in the selected format for human analysis, with a separate file generated for each selected AWS account.


### 5.2.2 Network perimeter


The [network perimeter](https://aws.amazon.com/blogs/security/establishing-a-data-perimeter-on-aws-allow-access-to-company-data-only-from-expected-networks/) is a set of coarse-grained controls that help ensure that you data can be accessed only from expected networks.

If you want to enforce network perimeter controls on your Amazon S3 buckets, you can start by crafting your bucket policy from the [s3_bucket_policy template]( https://github.com/aws-samples/data-perimeter-policy-examples/blob/main/resource_based_policies/s3_bucket_policy.json) provided in the data perimeter policy examples repository:


```jsonc
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EnforceNetworkPerimeter",
"Effect": "Deny",
"Principal": "*",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::<my-data-bucket>",
"arn:aws:s3:::<my-data-bucket>/*"
],
"Condition": {
"NotIpAddressIfExists": {
"aws:SourceIp": "<my-corporate-cidr>"
},
"StringNotEqualsIfExists": {
"aws:SourceVpc": "<my-vpc>",
"aws:PrincipalTag/network-perimeter-exception": "true",
"aws:PrincipalAccount": [
"<load-balancing-account-id>",
"<third-party-account-a>",
"<third-party-account-b>"
]
},
"BoolIfExists": {
"aws:PrincipalIsAWSService": "false",
"aws:ViaAWSService": "false"
},
"ArnNotLikeIfExists": {
"aws:PrincipalArn": [
"arn:aws:iam::<my-account-id>:role/aws-service-role/*"
"<principal-arn-with-network-exception>"
]
}
}
}
]
}
```


Replace values of the `aws:SourceIp`, `aws:SourceVpc`, `aws:PrincipalArn` and `aws:PrincipalAccount` condition keys based on what expected networks mean for your organization and on your knowledge of the intended access patterns you need to support. For example, your expected networks might be defined as:
- The VPCs that belong to your application accounts that need access to the bucket.
- The VPCs that belong to your security accounts that need access to the bucket.
- Your corporate public CIDRs.
- Networks of AWS services that use [service principals]( https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-services), [forward access sessions]( https://docs.aws.amazon.com/IAM/latest/UserGuide/access_forward_access_sessions.html), [service roles](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_services.html), or [service-linked roles]( https://docs.aws.amazon.com/IAM/latest/UserGuide/using-service-linked-roles.html) to access your resources.
- Networks of trusted third parties.


To assess the effects of the preceding policy *before* deployment, review your CloudTrail logs to learn from **where** API calls are performed on your Amazon S3 buckets. CloudTrail logs contain the following relevant information:
- Source IP addresses for calls over public service endpoints.
- Source VPC endpoint IDs for calls that traverse VPC endpoints (CloudTrail logs do not record VPC IDs).


To complete your analysis, obtain additional information about your environment:
- The VPC ID a given VPC endpoint belongs to.
- Is the principal a service role?
- By which AWS service can a service role be assumed?

To expedite the review, you might want to filter out API calls that align with your **expected networks** definition (for example, API calls that originate from networks of your approved application and security accounts).

`Data perimeter helper` provides a query that does this heavy lifting for you: [`s3_bucket_policy_network_perimeter_ipv4`](./data_perimeter_helper/queries/s3/s3_bucket_policy_network_perimeter_ipv4.py).

You start by setting your network perimeter definition in the` data perimeter helper` [configuration file](./data_perimeter_helper/data_perimeter.yaml):
```yaml
baseline:
network_perimeter_expected_public_cidr: [
"1.1.1.1/32" # Corporate CIDR
]
network_perimeter_trusted_account: [

]
network_perimeter_trusted_principal: [

]
network_perimeter_expected_vpc: [
"vpc-xxxxxxx", "vpc-yyyyyyy" # security account VPC IDs
]
network_perimeter_expected_vpc_endpoint: [

]
```

Then you run the data perimeter helper query `s3_bucket_policy_network_perimeter_ipv4` on a selected AWS account.


This query performs the following actions:
- Runs an Athena query to get all API calls made on Amazon S3 buckets that belong to the selected AWS account, filtering out the following:
- API calls made from VPCs that belong to the selected account – list of VPC IDs is retrieved from an AWS Config aggregator.
- API calls made through the expected VPC endpoints - retrieved from the data perimeter helper configuration file (`network_perimeter_expected_vpc_endpoint` parameter).
- API calls made from the expected public CIDR ranges - retrieved from the data perimeter helper configuration file (`network_perimeter_expected_public_cidr` parameter).
- API calls made by trusted identities - retrieved from the `data perimeter helper` configuration file (`network_perimeter_trusted_principal` parameter).
- API calls made by AWS service principals already accounted for in the network perimeter policy with the `aws:PrincipalIsAWSService` condition key.
- API calls made by service-linked roles (SLRs) in the same account or inventoried in AWS Config aggregator - already accounted for in the network perimeter policy with the `aws:PrincipalArn` condition key.
- API calls with errors.
- Keeps only API calls performed on the selected AWS account’s buckets because the aim is to update your bucket policies.
- Retrieves configuration information for all IAM roles and VPCs that belong to your organization from an AWS Config aggregator and injects the following fields in the results when relevant:
- Mapping between VPC IDs and VPC endpoint IDs.
- Value of the principal element of an IAM role trust policy.
- A Boolean value to denote if an IAM role is a service role.
- Removes from the processed results:
- API calls made from expected VPC IDs - retrieved from the data perimeter helper configuration file (`network_perimeter_expected_vpc` parameter).
- A subset of API calls made by an AWS service using [forward access sessions](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_forward_access_sessions.html):
- API calls made from an AWS service network by using a service role and where the `sourceipaddress` field in the CloudTrail record is populated with the service's DNS name that does not match the ones specified in the role's trust policy.
- API calls made from an AWS service network by a principal that is neither a service role nor a service-linked role and where the `sourceipaddress` field in the CloudTrail record is populated with the service's DNS name.
- If you have provided multiple AWS account IDs, `data perimeter helper` uses threading to perform concurrent queries to help you accelerate the review across your entire AWS organization.
- Provides query results in the selected format for human analysis, with a separate file generated for each selected AWS account.


### 5.2.3 Resource perimeter

A [resource perimeter](https://aws.amazon.com/blogs/security/establishing-a-data-perimeter-on-aws-allow-only-trusted-resources-from-my-organization/) is a set of coarse-grained preventative controls that help you ensure that only **trusted resources** can be accessed from your organization.

As part of your resource perimeter deployment, you might want to ensure that your identities can only perform `s3:PutObject` API calls on Amazon S3 buckets that your AWS organization owns.

To achieve this objective, you can start by crafting a service control policy using the [resource_perimeter_policy template](https://github.com/aws-samples/data-perimeter-policy-examples/blob/main/service_control_policies/resource_perimeter_policy.json) provided in the data perimeter policy examples repository:

```jsonc
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "EnforceResourcePerimeterAWSResourcesS3",
"Effect": "Deny",
"Action": [
"s3:PutObject"
],
"Resource": "*",
"Condition": {
"StringNotEqualsIfExists": {
"aws:ResourceOrgID": "<my-org-id>"
},
"ForAllValues:StringNotEquals": {
"aws:CalledVia": [
"dataexchange.amazonaws.com",
"servicecatalog.amazonaws.com"
]
}
}
}
]
}
```


To assess the effects of the preceding policy *before* deployment, review you CloudTrail logs to learn to **which** Amazon S3 buckets API calls are performed. CloudTrail logs contain bucket names in the request parameters or the `resources` record field. For each bucket name, you need to know if the bucket belongs to your AWS organization or not.

`Data perimeter helper` provides a query that streamlines this process for you: [`s3_scp_resource_perimeter`](./data_perimeter_helper/queries/s3/s3_scp_resource_perimeter.py).

This query performs the following actions:
- Runs an Athena query to list all Amazon S3 API calls made by the selected account’s principals, filtering out the following:
- API calls that do not support cross-account access (for example, `s3:ListAllMyBuckets`).
- API calls on S3 buckets owned by accounts belonging to the same AWS organization as the selected account.
- API calls made on trusted S3 buckets - retrieved from the `data perimeter helper` configuration file (`resource_perimeter_trusted_bucket` parameter).
- Keeps only API calls performed by the selected AWS account's principal because the aim is to update your service control policies.
- Retrieves the list of Amazon S3 buckets owned by your AWS organization from an AWS Config aggregator and removes calls made to such buckets. This is done as a second clean-up layer in case the CloudTrail `resources` record field is not populated.
- If you have provided multiple AWS account IDs, `data perimeter helper` uses threading to perform concurrent queries to help you accelerate the review across your entire AWS organization.
- Provides query results in the selected format for human analysis, with a separate file generated for each selected AWS account.

See the post [Establishing a data perimeter on AWS: Analyze your account activity to evaluate impact and refine controls](https://aws.amazon.com/blogs/security/establishing-a-data-perimeter-on-aws-analyze-your-account-activity-to-evaluate-impact-and-refine-controls/).

# 6. Data perimeter helper documentation

Expand Down
2 changes: 1 addition & 1 deletion data_perimeter_helper/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
# SPDX-License-Identifier: MIT-0

__version__ = "1.0.3a"
__version__ = "1.0.5"
2 changes: 1 addition & 1 deletion data_perimeter_helper/queries/Query.py
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ def remove_resource_exception(
dataframe = dataframe.drop(
dataframe[
(dataframe[lookup_column] == resource_id_value)
& (dataframe['sourceipaddress'].map(lambda ip: helper.is_ip_in_cidr(ip, cidr)))
& (dataframe['sourceipaddress'].map(lambda ip: helper.is_ip_in_cidr(ip, cidr))) # type: ignore
].index
)
return dataframe
Expand Down
Loading

0 comments on commit 03fcac3

Please sign in to comment.