diff --git a/api/changelog.d/security-hub-connection-status.fixed.md b/api/changelog.d/security-hub-connection-status.fixed.md new file mode 100644 index 0000000000..08ac6edb45 --- /dev/null +++ b/api/changelog.d/security-hub-connection-status.fixed.md @@ -0,0 +1 @@ +AWS Security Hub integrations now persist successful connection checks during finding delivery so their connection status and last checked timestamp stay current diff --git a/api/src/backend/tasks/jobs/integrations.py b/api/src/backend/tasks/jobs/integrations.py index c77ba22b7f..303d28c139 100644 --- a/api/src/backend/tasks/jobs/integrations.py +++ b/api/src/backend/tasks/jobs/integrations.py @@ -1,5 +1,6 @@ import os import time +from datetime import UTC, datetime from glob import glob from api.db_router import READ_REPLICA_ALIAS, MainRouter @@ -214,8 +215,10 @@ def get_security_hub_client_from_integration( for region in set(all_security_hub_regions): regions_status[region] = region in connection.enabled_regions - # Save regions information in the integration configuration + # Persist the successful connection check and regions information with rls_transaction(tenant_id, using=MainRouter.default_db): + integration.connected = True + integration.connection_last_checked_at = datetime.now(tz=UTC) integration.configuration["regions"] = regions_status integration.save() diff --git a/api/src/backend/tasks/tests/test_integrations.py b/api/src/backend/tasks/tests/test_integrations.py index bebb813feb..a95d02fa7f 100644 --- a/api/src/backend/tasks/tests/test_integrations.py +++ b/api/src/backend/tasks/tests/test_integrations.py @@ -1,3 +1,4 @@ +from datetime import UTC, datetime from unittest.mock import MagicMock, patch import pytest @@ -671,6 +672,8 @@ class TestSecurityHubIntegrationUploads: mock_integration = MagicMock() mock_integration.configuration = {"send_only_fails": True} mock_integration.credentials = {} # Empty credentials, use provider + mock_integration.connected = False + mock_integration.connection_last_checked_at = None # Mock tenant_id tenant_id = "550e8400-e29b-41d4-a716-446655440000" # Valid UUID @@ -723,12 +726,22 @@ class TestSecurityHubIntegrationUploads: # Configure the test_connection to return our mock_connection mock_security_hub_class.test_connection = mock_test_connection + checked_at_before = datetime.now(tz=UTC) connected, security_hub = get_security_hub_client_from_integration( mock_integration, tenant_id, mock_findings ) + checked_at_after = datetime.now(tz=UTC) assert connected is True assert security_hub == mock_security_hub + assert mock_integration.connected is True + assert mock_integration.connection_last_checked_at.tzinfo is UTC + assert ( + checked_at_before + <= mock_integration.connection_last_checked_at + <= checked_at_after + ) + mock_integration.save.assert_called_once() # Verify SecurityHub was called once to create the client assert mock_security_hub_class.call_count == 1