diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index 55f0190393..8a1504d398 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -27,6 +27,7 @@ All notable changes to the **Prowler SDK** are documented in this file. ### 🐞 Fixed +- OCI mutelist support: pass `tenancy_id` to `is_finding_muted` and update `oraclecloud_mutelist_example.yaml` to use `Accounts` key [(#10565)](https://github.com/prowler-cloud/prowler/issues/10565) - `return` statements in `finally` blocks replaced across IAM, Organizations, GCP provider, and custom checks metadata to stop silently swallowing exceptions [(#10102)](https://github.com/prowler-cloud/prowler/pull/10102) - `JiraConnection` now includes issue types per project fetched during `test_connection`, fixing `JiraInvalidIssueTypeError` on non-English Jira instances [(#10534)](https://github.com/prowler-cloud/prowler/pull/10534) - `--list-checks` and `--list-checks-json` now include `threat-detection` category checks in their output [(#10578)](https://github.com/prowler-cloud/prowler/pull/10578) diff --git a/prowler/config/oraclecloud_mutelist_example.yaml b/prowler/config/oraclecloud_mutelist_example.yaml index 3e40310ea8..2f56167b6a 100644 --- a/prowler/config/oraclecloud_mutelist_example.yaml +++ b/prowler/config/oraclecloud_mutelist_example.yaml @@ -1,12 +1,12 @@ -### Tenancy, Check and/or Region can be * to apply for all the cases. -### Tenancy == OCI Tenancy OCID and Region == OCI Region +### Account, Check and/or Region can be * to apply for all the cases. +### Account == OCI Tenancy OCID and Region == OCI Region ### Resources and tags are lists that can have either Regex or Keywords. ### Tags is an optional list that matches on tuples of 'key=value' and are "ANDed" together. ### Use an alternation Regex to match one of multiple tags with "ORed" logic. -### For each check you can except Tenancies, Regions, Resources and/or Tags. +### For each check you can except Accounts, Regions, Resources and/or Tags. ########################### MUTELIST EXAMPLE ########################### Mutelist: - Tenancies: + Accounts: "ocid1.tenancy.oc1..aaaaaaaexample": Checks: "iam_user_mfa_enabled": diff --git a/prowler/lib/check/check.py b/prowler/lib/check/check.py index 0041d4fde2..8e365acedc 100644 --- a/prowler/lib/check/check.py +++ b/prowler/lib/check/check.py @@ -718,6 +718,10 @@ def execute( is_finding_muted_args["team_id"] = ( team.id if team else global_provider.identity.user_id ) + elif global_provider.type == "oraclecloud": + is_finding_muted_args["tenancy_id"] = ( + global_provider.identity.tenancy_id + ) for finding in check_findings: if global_provider.type == "cloudflare": is_finding_muted_args["account_id"] = finding.account_id diff --git a/prowler/providers/oraclecloud/oraclecloud_provider.py b/prowler/providers/oraclecloud/oraclecloud_provider.py index 1fbb10483a..c5abaf3929 100644 --- a/prowler/providers/oraclecloud/oraclecloud_provider.py +++ b/prowler/providers/oraclecloud/oraclecloud_provider.py @@ -351,7 +351,6 @@ class OraclecloudProvider(Provider): try: config = oci.config.from_file(oci_config_file, profile) - oci.config.validate_config(config) # Check if using security token authentication if ( @@ -374,6 +373,9 @@ class OraclecloudProvider(Provider): token=token, private_key=private_key ) else: + # Only validate full config for API key auth + # (session auth doesn't require 'user' field) + oci.config.validate_config(config) logger.info( f"Using profile '{profile}' with API key authentication" ) diff --git a/tests/lib/check/check_test.py b/tests/lib/check/check_test.py index b6332deb25..84708b96b1 100644 --- a/tests/lib/check/check_test.py +++ b/tests/lib/check/check_test.py @@ -1090,6 +1090,37 @@ class TestCheck: assert not errors, "\n\n".join(errors) + def test_execute_oraclecloud_mutelist_passes_tenancy_id(self): + """Test that execute() passes tenancy_id to is_finding_muted for OCI provider.""" + tenancy_id = "ocid1.tenancy.oc1..aaaaaaaexample" + + finding = Mock() + finding.status = "PASS" + finding.muted = False + + check = Mock() + check.CheckID = "oci_test_check" + check.execute = Mock(return_value=[finding]) + + provider = mock.MagicMock() + provider.type = "oraclecloud" + provider.identity.tenancy_id = tenancy_id + provider.mutelist.mutelist = {"Accounts": {tenancy_id: {}}} + provider.mutelist.is_finding_muted = Mock(return_value=True) + + findings = execute( + check=check, + global_provider=provider, + custom_checks_metadata=None, + output_options=None, + ) + + provider.mutelist.is_finding_muted.assert_called_once_with( + tenancy_id=tenancy_id, + finding=finding, + ) + assert findings[0].muted is True + def test_execute_check_exception_only_logs(self, caplog): caplog.set_level(ERROR)