Skip to content

Commit 369f852

Browse files
fix(aws): lead the partition bootstrap regions with the configured region (#12764)
Co-authored-by: pedrooot <pedromarting3@gmail.com>
1 parent 1e8454a commit 369f852

5 files changed

Lines changed: 303 additions & 13 deletions

File tree

docs/user-guide/providers/aws/regions-and-partitions.mdx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,28 @@ When scanning the China (`aws-cn`), European Sovereign Cloud (`aws-eusc`) or Gov
2121

2222
- Specify the regions to audit within that partition using the `-f/--region` flag.
2323

24+
- Declare the partition with the `PROWLER_AWS_PARTITION` environment variable, set to `aws`, `aws-cn`, `aws-eusc` or `aws-us-gov`.
25+
2426
<Note>
2527
Refer to: https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials for more information about the AWS credential configuration.
2628

2729
</Note>
30+
### Declaring the Partition
31+
32+
`PROWLER_AWS_PARTITION` tells Prowler which partition the scan runs against, without relying on a region being configured:
33+
34+
```bash
35+
export PROWLER_AWS_PARTITION="aws-us-gov"
36+
```
37+
38+
It matters most where nothing else says. Resolving an identity means calling STS before anything is known about the credentials, and with no region configured Prowler would otherwise start from the commercial endpoints. Declaring the partition makes that first call go to the right place, which is the difference between a scan that starts and one that fails on an endpoint the credentials cannot use.
39+
40+
A region configured for the session still wins when it belongs to the declared partition, so a deployment in `us-gov-west-1` is not sent to `us-gov-east-1`. A region belonging to a different partition is ignored, since a partition that has been declared explicitly is the more deliberate statement of the two.
41+
42+
<Note>
43+
Set it wherever the scan runs. For deployments that scan from containers, that means the environment of the containers doing the scanning, not only the one accepting the request.
44+
</Note>
45+
2846
### Scanning Specific Regions
2947

3048
To scan a particular AWS region with Prowler, use:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Bootstrap STS calls now use the session region when `PROWLER_AWS_PARTITION` is set and the region belongs to that partition, instead of always going to the partition's global STS region, which a deployment reached only through its own region's VPC endpoints cannot route to

prowler/providers/aws/aws_provider.py

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -576,8 +576,15 @@ def get_profile_region(
576576
) -> str:
577577
excluded_regions = set(excluded_regions or ())
578578
session_region = session.region_name
579+
env_partition_regions = get_env_partition_regions(session_region)
579580
if session_region and session_region not in excluded_regions:
580-
return session_region
581+
if not env_partition_regions or session_region in env_partition_regions:
582+
return session_region
583+
if env_partition_regions:
584+
for region in env_partition_regions:
585+
if region not in excluded_regions:
586+
return region
587+
return env_partition_regions[0]
581588

582589
for region in AwsProvider.get_bootstrap_region_candidates(session_region):
583590
if region not in excluded_regions:
@@ -673,7 +680,7 @@ def setup_session(
673680
session = Session(**session_arguments)
674681
session._session.set_default_client_config(session_config)
675682
sts_region = (
676-
get_env_partition_bootstrap_region()
683+
get_env_partition_bootstrap_region(session.region_name)
677684
or session.region_name
678685
or AWS_STS_GLOBAL_ENDPOINT_REGION
679686
)
@@ -1420,12 +1427,6 @@ def test_connection(
14201427
Connection(is_connected=True, Error=None))
14211428
"""
14221429
try:
1423-
if aws_region is None:
1424-
aws_region = (
1425-
get_env_partition_bootstrap_region()
1426-
or AWS_STS_GLOBAL_ENDPOINT_REGION
1427-
)
1428-
14291430
session = AwsProvider.setup_session(
14301431
mfa=mfa_enabled,
14311432
profile=profile,
@@ -1434,6 +1435,12 @@ def test_connection(
14341435
aws_session_token=aws_session_token,
14351436
)
14361437

1438+
if aws_region is None:
1439+
aws_region = (
1440+
get_env_partition_bootstrap_region(session.region_name)
1441+
or AWS_STS_GLOBAL_ENDPOINT_REGION
1442+
)
1443+
14371444
if role_arn:
14381445
session_duration = validate_session_duration(session_duration)
14391446
role_session_name = validate_role_session_name(role_session_name)
@@ -1759,11 +1766,18 @@ def get_botocore_partition_regions() -> dict:
17591766
return partition_regions
17601767

17611768

1762-
def get_env_partition_regions() -> Optional[list]:
1769+
def get_env_partition_regions(
1770+
session_region: Optional[str] = None,
1771+
) -> Optional[list]:
17631772
"""
17641773
Get the bootstrap region candidates for the partition set in the
17651774
PROWLER_AWS_PARTITION environment variable.
17661775
1776+
Args:
1777+
session_region (Optional[str]): The region of the AWS session. It leads
1778+
the candidates when it belongs to the partition and is ignored
1779+
otherwise.
1780+
17671781
Returns:
17681782
Optional[list]: The regions of the configured partition, preferred
17691783
bootstrap region first, or None when the environment variable is
@@ -1782,22 +1796,33 @@ def get_env_partition_regions() -> Optional[list]:
17821796
raise AWSInvalidPartitionError(
17831797
message=f"Invalid partition: {raw_partition} set in PROWLER_AWS_PARTITION. Valid partitions: {', '.join(sorted(partition_regions))}"
17841798
)
1799+
1800+
# A deployment reached only through its own region's endpoints has no route
1801+
# to the partition's global STS region, so the session region goes first
1802+
if session_region in regions:
1803+
regions = [session_region] + [r for r in regions if r != session_region]
17851804
return regions
17861805

17871806

1788-
def get_env_partition_bootstrap_region() -> Optional[str]:
1807+
def get_env_partition_bootstrap_region(
1808+
session_region: Optional[str] = None,
1809+
) -> Optional[str]:
17891810
"""
17901811
Get the STS bootstrap region for the partition set in the
17911812
PROWLER_AWS_PARTITION environment variable.
17921813
1814+
Args:
1815+
session_region (Optional[str]): The region of the AWS session, preferred
1816+
when it belongs to the partition.
1817+
17931818
Returns:
17941819
Optional[str]: The preferred bootstrap region of the configured
17951820
partition, or None when the environment variable is not set.
17961821
17971822
Raises:
17981823
AWSInvalidPartitionError: If the value is not a partition known to botocore.
17991824
"""
1800-
regions = get_env_partition_regions()
1825+
regions = get_env_partition_regions(session_region)
18011826
return regions[0] if regions else None
18021827

18031828

@@ -1833,7 +1858,7 @@ def get_aws_region_for_sts(
18331858
if region not in excluded_regions:
18341859
return region
18351860

1836-
env_partition_regions = get_env_partition_regions()
1861+
env_partition_regions = get_env_partition_regions(session_region)
18371862
if env_partition_regions:
18381863
# The configured partition constrains the whole fallback chain: prefer
18391864
# a non-excluded region, but never leave the partition

0 commit comments

Comments
 (0)