feat(aws): add check to ensure Codebuild Github projects are only use allowed Github orgs (#7595)

Co-authored-by: Sergio Garcia <hello@mistercloudsec.com>
This commit is contained in:
Andoni Alonso
2025-06-17 18:17:18 +02:00
committed by GitHub
parent 3986bf3f42
commit dfd5c9aee7
9 changed files with 749 additions and 4 deletions
+1
View File
@@ -31,6 +31,7 @@ The following list includes all the AWS checks with configurable variables that
| `cloudtrail_threat_detection_privilege_escalation` | `threat_detection_privilege_escalation_minutes` | Integer |
| `cloudwatch_log_group_no_secrets_in_logs` | `secrets_ignore_patterns` | List of Strings |
| `cloudwatch_log_group_retention_policy_specific_days_enabled` | `log_group_retention_days` | Integer |
| `codebuild_github_allowed_organizations` | `github_allowed_organizations` | List of Strings |
| `codebuild_project_no_secrets_in_variables` | `excluded_sensitive_environment_variables` | List of Strings |
| `codebuild_project_no_secrets_in_variables` | `secrets_ignore_patterns` | List of Strings |
| `config_recorder_all_regions_enabled` | `mute_non_default_regions` | Boolean |
+1
View File
@@ -29,6 +29,7 @@ All notable changes to the **Prowler SDK** are documented in this file.
- Avoid bypassing IAM check using wildcards [(#7708)](https://github.com/prowler-cloud/prowler/pull/7708)
- New method to authenticate in AppInsights in check `app_function_application_insights_enabled` [(#7763)](https://github.com/prowler-cloud/prowler/pull/7763)
- ISO 27001 2022 for M365 provider. [(#7985)](https://github.com/prowler-cloud/prowler/pull/7985)
- `codebuild_project_uses_allowed_github_organizations` check for AWS provider [(#7595)](https://github.com/prowler-cloud/prowler/pull/7595)
- IaC provider [(#7852)](https://github.com/prowler-cloud/prowler/pull/7852)
---
+5
View File
@@ -417,6 +417,11 @@ aws:
{"name": "TwilioKeyDetector"},
]
# AWS CodeBuild Configuration
# aws.codebuild_project_uses_allowed_github_organizations
codebuild_github_allowed_organizations:
[
]
# Azure Configuration
azure:
@@ -0,0 +1,30 @@
{
"Provider": "aws",
"CheckID": "codebuild_project_uses_allowed_github_organizations",
"CheckTitle": "Ensure AWS CodeBuild projects using GitHub connect only to allowed organizations",
"CheckType": [],
"ServiceName": "codebuild",
"SubServiceName": "",
"ResourceIdTemplate": "arn:aws:codebuild:region:account-id:project:project-name",
"Severity": "high",
"ResourceType": "AwsCodeBuildProject",
"Description": "Check for CodeBuild projects using GitHub repositories from untrusted organizations that could lead to backdoored IAM roles",
"Risk": "Attackers can use GitHub Actions in untrusted repositories to backdoor IAM roles used by CodeBuild projects, gaining persistent access to AWS accounts.",
"RelatedUrl": "https://medium.com/@adan.alvarez/gaining-long-term-aws-access-with-codebuild-and-github-873324638784",
"Remediation": {
"Code": {
"NativeIaC": "",
"Terraform": "",
"CLI": "",
"Other": ""
},
"Recommendation": {
"Text": "Only use GitHub repositories from trusted organizations with CodeBuild projects. Configure the allowed GitHub organizations in your Prowler configuration.",
"Url": "https://docs.aws.amazon.com/codebuild/latest/userguide/auth-and-access-control-iam-identity-based-access-control.html"
}
},
"Categories": [],
"DependsOn": [],
"RelatedTo": [],
"Notes": ""
}
@@ -0,0 +1,57 @@
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.codebuild.codebuild_client import codebuild_client
from prowler.providers.aws.services.iam.iam_client import iam_client
from prowler.providers.aws.services.iam.lib.policy import (
has_codebuild_trusted_principal,
is_codebuild_using_allowed_github_org,
)
class codebuild_project_uses_allowed_github_organizations(Check):
def execute(self):
findings = []
allowed_organizations = codebuild_client.audit_config.get(
"codebuild_github_allowed_organizations", []
)
for project in codebuild_client.projects.values():
if project.source and project.source.type in (
"GITHUB",
"GITHUB_ENTERPRISE",
):
project_github_repo_url = project.source.location
project_role = next(
(
role
for role in iam_client.roles
if role.arn == project.service_role_arn
),
None,
)
project_iam_trust_policy = (
project_role.assume_role_policy if project_role else None
)
if not project_iam_trust_policy or not has_codebuild_trusted_principal(
project_iam_trust_policy
):
continue
report = Check_Report_AWS(metadata=self.metadata(), resource=project)
report.status = "PASS"
is_allowed, org_name = is_codebuild_using_allowed_github_org(
project_iam_trust_policy,
project_github_repo_url,
allowed_organizations,
)
if org_name is not None:
if is_allowed:
report.status_extended = f"CodeBuild project {project.name} uses GitHub organization '{org_name}', which is in the allowed organizations."
else:
report.status = "FAIL"
report.status_extended = f"CodeBuild project {project.name} uses GitHub organization '{org_name}', which is not in the allowed organizations."
findings.append(report)
return findings
@@ -120,6 +120,7 @@ class Codebuild(AWSService):
stream_name=cloudwatch_logs.get("streamName", ""),
)
project.tags = project_info.get("tags", [])
project.service_role_arn = project_info.get("serviceRole", "")
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
@@ -216,10 +217,11 @@ class Project(BaseModel):
buildspec: Optional[str] = None
source: Optional[Source] = None
secondary_sources: Optional[list[Source]] = []
environment_variables: Optional[List[EnvironmentVariable]] = []
s3_logs: Optional[s3Logs] = None
cloudwatch_logs: Optional[CloudWatchLogs] = None
tags: Optional[list] = []
service_role_arn: Optional[str] = None
environment_variables: Optional[List[EnvironmentVariable]]
s3_logs: Optional[s3Logs]
cloudwatch_logs: Optional[CloudWatchLogs]
tags: Optional[list]
class ExportConfig(BaseModel):
@@ -1,5 +1,6 @@
import re
from ipaddress import ip_address, ip_network
from typing import Optional, Tuple
from py_iam_expand.actions import InvalidActionHandling, expand_actions
@@ -738,3 +739,75 @@ def is_valid_aws_service(service):
if service in read_aws_regions_file()["services"]:
return True
return False
def is_codebuild_using_allowed_github_org(
trust_policy: dict, github_repo_url: str, allowed_organizations: list
) -> Tuple[bool, Optional[str]]:
"""
Checks if the trust policy allows codebuild.amazonaws.com as a trusted principal and if the GitHub organization
in the repo URL is in the allowed organizations list.
Returns (is_allowed: bool, org_name: str or None)
"""
try:
if not trust_policy or not github_repo_url:
return False, None
if not has_codebuild_trusted_principal(trust_policy):
return False, None
# Extract org name from GitHub repo URL
org_name = (
github_repo_url.split("/")[3]
if len(github_repo_url.split("/")) > 3
else None
)
if not org_name:
raise ValueError(f"Malformed GitHub repo URL: {github_repo_url}")
if org_name in allowed_organizations:
return True, org_name
return False, org_name
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
return False, None
def has_codebuild_trusted_principal(trust_policy: dict) -> bool:
"""
Returns True if the trust policy allows codebuild.amazonaws.com as a trusted principal, otherwise False.
"""
if not trust_policy:
return False
statements = trust_policy.get("Statement", [])
if not isinstance(statements, list):
statements = [statements]
return any(
s.get("Effect") == "Allow"
and "Principal" in s
and (
(
isinstance(s["Principal"], dict)
and (
(
isinstance(s["Principal"].get("Service"), str)
and s["Principal"].get("Service") == "codebuild.amazonaws.com"
)
or (
isinstance(s["Principal"].get("Service"), list)
and "codebuild.amazonaws.com" in s["Principal"].get("Service")
)
)
)
or (
isinstance(s["Principal"], str)
and s["Principal"] == "codebuild.amazonaws.com"
)
or (
isinstance(s["Principal"], list)
and "codebuild.amazonaws.com" in s["Principal"]
)
)
for s in statements
)
@@ -0,0 +1,393 @@
from unittest.mock import patch
from boto3 import client
from moto import mock_aws
from tests.providers.aws.utils import AWS_REGION_EU_WEST_1, set_mocked_aws_provider
AWS_ACCOUNT_NUMBER = "123456789012"
class Test_codebuild_project_uses_allowed_github_organizations:
@mock_aws
def test_no_projects(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
new=Codebuild(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
{"codebuild_github_allowed_organizations": ["allowed-org"]},
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
codebuild_project_uses_allowed_github_organizations,
)
check = codebuild_project_uses_allowed_github_organizations()
result = check.execute()
assert len(result) == 0
@mock_aws
def test_project_github_allowed_organization(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
codebuild_client = client("codebuild", region_name=AWS_REGION_EU_WEST_1)
iam_client = client("iam", region_name=AWS_REGION_EU_WEST_1)
project_name = "test-project-github-allowed"
role_name = "codebuild-test-role"
role_arn = iam_client.create_role(
RoleName=role_name,
AssumeRolePolicyDocument="""{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "codebuild.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}""",
)["Role"]["Arn"]
project_arn = codebuild_client.create_project(
name=project_name,
source={
"type": "GITHUB",
"location": "https://github.com/allowed-org/repo",
},
artifacts={"type": "NO_ARTIFACTS"},
environment={
"type": "LINUX_CONTAINER",
"image": "aws/codebuild/standard:4.0",
"computeType": "BUILD_GENERAL1_SMALL",
"environmentVariables": [],
},
serviceRole=role_arn,
tags=[{"key": "Name", "value": "test"}],
)["project"]["arn"]
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
from prowler.providers.aws.services.iam.iam_service import IAM
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
new=Codebuild(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.iam_client",
new=IAM(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
{"codebuild_github_allowed_organizations": ["allowed-org"]},
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
codebuild_project_uses_allowed_github_organizations,
)
check = codebuild_project_uses_allowed_github_organizations()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert result[0].resource_id == project_name
assert result[0].resource_arn == project_arn
assert "which is in the allowed organizations" in result[0].status_extended
assert result[0].region == AWS_REGION_EU_WEST_1
@mock_aws
def test_project_github_not_allowed_organization(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
codebuild_client = client("codebuild", region_name=AWS_REGION_EU_WEST_1)
iam_client = client("iam", region_name=AWS_REGION_EU_WEST_1)
project_name = "test-project-github-not-allowed"
role_name = "codebuild-test-role"
role_arn = iam_client.create_role(
RoleName=role_name,
AssumeRolePolicyDocument="""{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "codebuild.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}""",
)["Role"]["Arn"]
project_arn = codebuild_client.create_project(
name=project_name,
source={
"type": "GITHUB",
"location": "https://github.com/not-allowed-org/repo",
},
artifacts={"type": "NO_ARTIFACTS"},
environment={
"type": "LINUX_CONTAINER",
"image": "aws/codebuild/standard:4.0",
"computeType": "BUILD_GENERAL1_SMALL",
"environmentVariables": [],
},
serviceRole=role_arn,
tags=[{"key": "Name", "value": "test"}],
)["project"]["arn"]
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
from prowler.providers.aws.services.iam.iam_service import IAM
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
new=Codebuild(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.iam_client",
new=IAM(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
{"codebuild_github_allowed_organizations": ["allowed-org"]},
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
codebuild_project_uses_allowed_github_organizations,
)
check = codebuild_project_uses_allowed_github_organizations()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert result[0].resource_id == project_name
assert result[0].resource_arn == project_arn
assert (
"which is not in the allowed organizations" in result[0].status_extended
)
assert result[0].region == AWS_REGION_EU_WEST_1
@mock_aws
def test_project_github_no_codebuild_trusted_principal(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
from prowler.providers.aws.services.iam.iam_service import IAM
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
new=Codebuild(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.iam_client",
new=IAM(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
{"codebuild_github_allowed_organizations": ["allowed-org"]},
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
codebuild_project_uses_allowed_github_organizations,
)
check = codebuild_project_uses_allowed_github_organizations()
result = check.execute()
assert len(result) == 0
@mock_aws
def test_project_github_enterprise_allowed_organization(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
codebuild_client = client("codebuild", region_name=AWS_REGION_EU_WEST_1)
iam_client = client("iam", region_name=AWS_REGION_EU_WEST_1)
project_name = "test-project-github-enterprise-allowed"
role_name = "codebuild-test-role"
role_arn = iam_client.create_role(
RoleName=role_name,
AssumeRolePolicyDocument="""{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "codebuild.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}""",
)["Role"]["Arn"]
project_arn = codebuild_client.create_project(
name=project_name,
source={
"type": "GITHUB_ENTERPRISE",
"location": "https://github.enterprise.com/allowed-org/repo",
},
artifacts={"type": "NO_ARTIFACTS"},
environment={
"type": "LINUX_CONTAINER",
"image": "aws/codebuild/standard:4.0",
"computeType": "BUILD_GENERAL1_SMALL",
"environmentVariables": [],
},
serviceRole=role_arn,
tags=[{"key": "Name", "value": "test"}],
)["project"]["arn"]
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
from prowler.providers.aws.services.iam.iam_service import IAM
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
new=Codebuild(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.iam_client",
new=IAM(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
{"codebuild_github_allowed_organizations": ["allowed-org"]},
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
codebuild_project_uses_allowed_github_organizations,
)
check = codebuild_project_uses_allowed_github_organizations()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert result[0].resource_id == project_name
assert result[0].resource_arn == project_arn
assert "which is in the allowed organizations" in result[0].status_extended
assert result[0].region == AWS_REGION_EU_WEST_1
@mock_aws
def test_project_github_enterprise_not_allowed_organization(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
codebuild_client = client("codebuild", region_name=AWS_REGION_EU_WEST_1)
iam_client = client("iam", region_name=AWS_REGION_EU_WEST_1)
project_name = "test-project-github-enterprise-not-allowed"
role_name = "codebuild-test-role"
role_arn = iam_client.create_role(
RoleName=role_name,
AssumeRolePolicyDocument="""{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "codebuild.amazonaws.com"},
"Action": "sts:AssumeRole"
}
]
}""",
)["Role"]["Arn"]
project_arn = codebuild_client.create_project(
name=project_name,
source={
"type": "GITHUB_ENTERPRISE",
"location": "https://github.enterprise.com/not-allowed-org/repo",
},
artifacts={"type": "NO_ARTIFACTS"},
environment={
"type": "LINUX_CONTAINER",
"image": "aws/codebuild/standard:4.0",
"computeType": "BUILD_GENERAL1_SMALL",
"environmentVariables": [],
},
serviceRole=role_arn,
tags=[{"key": "Name", "value": "test"}],
)["project"]["arn"]
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
from prowler.providers.aws.services.iam.iam_service import IAM
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
new=Codebuild(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.iam_client",
new=IAM(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
{"codebuild_github_allowed_organizations": ["allowed-org"]},
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
codebuild_project_uses_allowed_github_organizations,
)
check = codebuild_project_uses_allowed_github_organizations()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert result[0].resource_id == project_name
assert result[0].resource_arn == project_arn
assert (
"which is not in the allowed organizations" in result[0].status_extended
)
assert result[0].region == AWS_REGION_EU_WEST_1
@mock_aws
def test_project_github_enterprise_no_codebuild_trusted_principal(self):
aws_provider = set_mocked_aws_provider([AWS_REGION_EU_WEST_1])
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
from prowler.providers.aws.services.iam.iam_service import IAM
with (
patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=aws_provider,
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client",
new=Codebuild(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.iam_client",
new=IAM(aws_provider),
),
patch(
"prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations.codebuild_client.audit_config",
{"codebuild_github_allowed_organizations": ["allowed-org"]},
),
):
from prowler.providers.aws.services.codebuild.codebuild_project_uses_allowed_github_organizations.codebuild_project_uses_allowed_github_organizations import (
codebuild_project_uses_allowed_github_organizations,
)
check = codebuild_project_uses_allowed_github_organizations()
result = check.execute()
assert len(result) == 0
@@ -5,6 +5,8 @@ from prowler.providers.aws.services.iam.lib.policy import (
check_admin_access,
check_full_service_access,
get_effective_actions,
has_codebuild_trusted_principal,
is_codebuild_using_allowed_github_org,
is_condition_block_restrictive,
is_condition_block_restrictive_organization,
is_condition_block_restrictive_sns_endpoint,
@@ -2268,3 +2270,184 @@ class Test_Policy:
],
}
assert check_admin_access(policy)
def test_is_codebuild_using_allowed_github_org_allows():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "codebuild.amazonaws.com"},
"Action": "sts:AssumeRole",
}
],
}
github_repo_url = "https://github.com/allowed-org/repo"
allowed_organizations = ["allowed-org"]
is_allowed, org_name = is_codebuild_using_allowed_github_org(
trust_policy, github_repo_url, allowed_organizations
)
assert is_allowed is True
assert org_name == "allowed-org"
def test_is_codebuild_using_allowed_github_org_denies():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "codebuild.amazonaws.com"},
"Action": "sts:AssumeRole",
}
],
}
github_repo_url = "https://github.com/not-allowed-org/repo"
allowed_organizations = ["allowed-org"]
is_allowed, org_name = is_codebuild_using_allowed_github_org(
trust_policy, github_repo_url, allowed_organizations
)
assert is_allowed is False
assert org_name == "not-allowed-org"
def test_is_codebuild_using_allowed_github_org_no_codebuild_principal():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole",
}
],
}
github_repo_url = "https://github.com/allowed-org/repo"
allowed_organizations = ["allowed-org"]
is_allowed, org_name = is_codebuild_using_allowed_github_org(
trust_policy, github_repo_url, allowed_organizations
)
assert is_allowed is False
assert org_name is None
def test_is_codebuild_using_allowed_github_org_invalid_url():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "codebuild.amazonaws.com"},
"Action": "sts:AssumeRole",
}
],
}
github_repo_url = "https://github.com//test" # Malformed, no org
allowed_organizations = ["allowed-org"]
is_allowed, org_name = is_codebuild_using_allowed_github_org(
trust_policy, github_repo_url, allowed_organizations
)
assert is_allowed is False
assert org_name is None
def test_has_codebuild_trusted_principal_true():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "codebuild.amazonaws.com"},
"Action": "sts:AssumeRole",
}
],
}
assert has_codebuild_trusted_principal(trust_policy) is True
def test_has_codebuild_trusted_principal_false():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {"Service": "lambda.amazonaws.com"},
"Action": "sts:AssumeRole",
}
],
}
assert has_codebuild_trusted_principal(trust_policy) is False
def test_has_codebuild_trusted_principal_empty():
trust_policy = {}
assert has_codebuild_trusted_principal(trust_policy) is False
def test_is_codebuild_using_allowed_github_org_principal_string():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "codebuild.amazonaws.com",
"Action": "sts:AssumeRole",
}
],
}
github_repo_url = "https://github.com/allowed-org/repo"
allowed_organizations = ["allowed-org"]
is_allowed, org_name = is_codebuild_using_allowed_github_org(
trust_policy, github_repo_url, allowed_organizations
)
assert is_allowed is True
assert org_name == "allowed-org"
def test_is_codebuild_using_allowed_github_org_principal_list():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": ["codebuild.amazonaws.com", "lambda.amazonaws.com"],
"Action": "sts:AssumeRole",
}
],
}
github_repo_url = "https://github.com/allowed-org/repo"
allowed_organizations = ["allowed-org"]
is_allowed, org_name = is_codebuild_using_allowed_github_org(
trust_policy, github_repo_url, allowed_organizations
)
assert is_allowed is True
assert org_name == "allowed-org"
def test_has_codebuild_trusted_principal_string():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "codebuild.amazonaws.com",
"Action": "sts:AssumeRole",
}
],
}
assert has_codebuild_trusted_principal(trust_policy) is True
def test_has_codebuild_trusted_principal_list():
trust_policy = {
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": ["codebuild.amazonaws.com", "lambda.amazonaws.com"],
"Action": "sts:AssumeRole",
}
],
}
assert has_codebuild_trusted_principal(trust_policy) is True