From 1b8b5cd18c5ddab4380470af2a670f4ecd2bf2bd Mon Sep 17 00:00:00 2001 From: Prowler Bot Date: Wed, 29 Apr 2026 13:52:53 +0200 Subject: [PATCH] fix(kubernetes): use cluster name as provider_uid in OCSF output (#10932) Co-authored-by: Andoni Alonso <14891798+andoniaf@users.noreply.github.com> Co-authored-by: Pepe Fagoaga --- prowler/CHANGELOG.md | 1 + prowler/lib/outputs/finding.py | 3 ++- tests/lib/outputs/finding_test.py | 36 ++++++++++++++++++++++++++++++- 3 files changed, 38 insertions(+), 2 deletions(-) diff --git a/prowler/CHANGELOG.md b/prowler/CHANGELOG.md index ce5a0f0930..5cd9815b40 100644 --- a/prowler/CHANGELOG.md +++ b/prowler/CHANGELOG.md @@ -7,6 +7,7 @@ All notable changes to the **Prowler SDK** are documented in this file. ### 🐞 Fixed - `KeyError` when generating compliance outputs after the CLI scan [#10919](https://github.com/prowler-cloud/prowler/pull/10919) +- Kubernetes OCSF `provider_uid` now uses the cluster name in in-cluster mode (so `--cluster-name` is correctly reflected in findings) and keeps the kubeconfig context in kubeconfig mode [(#10483)](https://github.com/prowler-cloud/prowler/pull/10483) --- diff --git a/prowler/lib/outputs/finding.py b/prowler/lib/outputs/finding.py index f3cfc08eda..3da2f0d7d3 100644 --- a/prowler/lib/outputs/finding.py +++ b/prowler/lib/outputs/finding.py @@ -245,15 +245,16 @@ class Finding(BaseModel): elif provider.type == "kubernetes": if provider.identity.context == "In-Cluster": output_data["auth_method"] = "in-cluster" + output_data["provider_uid"] = provider.identity.cluster else: output_data["auth_method"] = "kubeconfig" + output_data["provider_uid"] = provider.identity.context output_data["resource_name"] = check_output.resource_name output_data["resource_uid"] = check_output.resource_id output_data["account_name"] = f"context: {provider.identity.context}" output_data["account_uid"] = get_nested_attribute( provider, "identity.cluster" ) - output_data["provider_uid"] = provider.identity.context output_data["region"] = f"namespace: {check_output.namespace}" elif provider.type == "github": diff --git a/tests/lib/outputs/finding_test.py b/tests/lib/outputs/finding_test.py index 00ce2fe1f7..2a57cc40bb 100644 --- a/tests/lib/outputs/finding_test.py +++ b/tests/lib/outputs/finding_test.py @@ -557,7 +557,7 @@ class TestFinding: assert finding_output.resource_tags == {} assert finding_output.partition is None assert finding_output.account_uid == "test_cluster" - assert finding_output.provider_uid == "In-Cluster" + assert finding_output.provider_uid == "test_cluster" assert finding_output.account_name == "context: In-Cluster" assert finding_output.account_email is None assert finding_output.account_organization_uid is None @@ -591,6 +591,40 @@ class TestFinding: assert finding_output.metadata.Notes == "mock_notes" assert finding_output.metadata.Compliance == [] + def test_generate_output_kubernetes_kubeconfig(self): + # Mock provider + provider = MagicMock() + provider.type = "kubernetes" + provider.identity.context = "test-context" + provider.identity.cluster = "test_cluster" + + # Mock check result + check_output = MagicMock() + check_output.resource_name = "test_resource_name" + check_output.resource_id = "test_resource_id" + check_output.namespace = "test_namespace" + check_output.resource_details = "test_resource_details" + check_output.status = Status.PASS + check_output.status_extended = "mock_status_extended" + check_output.muted = False + check_output.check_metadata = mock_check_metadata(provider="kubernetes") + check_output.timestamp = datetime.now() + check_output.resource = {} + check_output.compliance = {} + + # Mock Output Options + output_options = MagicMock() + output_options.unix_timestamp = True + + # Generate the finding + finding_output = Finding.generate_output(provider, check_output, output_options) + + assert isinstance(finding_output, Finding) + assert finding_output.auth_method == "kubeconfig" + assert finding_output.account_uid == "test_cluster" + assert finding_output.provider_uid == "test-context" + assert finding_output.account_name == "context: test-context" + def test_generate_output_github_personal_access_token(self): """Test GitHub output generation with Personal Access Token authentication.""" # Mock provider using Personal Access Token