Skip to content

Conversation

@danibarranqueroo
Copy link
Member

@danibarranqueroo danibarranqueroo commented Jan 16, 2026

Context

This PR implements OpenStack provider support in the Prowler SDK/CLI, enabling security assessments for OpenStack cloud environments.

OpenStack is a widely-used open-source cloud computing platform, and this integration allows Prowler to perform security audits on OpenStack deployments, complementing the existing support for other cloud providers

Description

This PR adds comprehensive OpenStack provider integration to Prowler with the following components:

Core Provider Implementation:

  • New OpenStackProvider class with Keystone Identity v3 authentication
  • Environment variable support for credentials:
    • Required: OS_AUTH_URL, OS_USERNAME, OS_PASSWORD, OS_PROJECT_ID, OS_REGION_NAME
    • Optional: OS_IDENTITY_API_VERSION, OS_USER_DOMAIN_NAME, OS_PROJECT_DOMAIN_NAME
  • Smart project ID handling supporting both UUID format and provider-specific formats (e.g., OVH numeric IDs)
  • Static test_connection() method for credential validation without full provider initialization
  • Mutelist support for excluding specific OpenStack resources from checks
  • Integration with Prowler's output formats (JSON, CSV, HTML, etc.)

Services Implemented:

  1. Compute (Nova Service) - Manages virtual machine instances

Security Checks:

  1. compute_instance_security_groups_attached - Ensures compute instances have security groups attached for network protection

Additional Changes:

  • Updated CheckMetadataModel to support OpenStack-specific fields
  • Added OpenStack output rendering in HTML reports
  • Extended CLI parser with OpenStack-specific arguments
  • Added OpenStack compliance framework placeholder structure
  • Fixed compliance loading issue where non-JSON files were being processed

Testing Coverage:

  • 57 comprehensive unit tests including:
    • Provider initialization with various credential combinations
    • Environment variable handling and validation
    • Session configuration for UUID and non-UUID project IDs
    • Connection testing with error scenarios
    • Identity enrichment with graceful failure handling
    • Service initialization and resource listing
    • Check execution with PASS/FAIL scenarios
    • Edge cases (missing attributes, SDK exceptions, empty resources)
  • All tests include environment isolation to prevent interference from local OpenStack configurations

Dependencies:

  • Added openstacksdk package to pyproject.toml for OpenStack API interactions

Steps to review

1. Run Tests:

poetry run pytest tests/providers/openstack/ -v
# Expected: 57 tests passed

2. Verify Provider Initialization:

# Set OpenStack credentials (use your test environment)
export OS_AUTH_URL="https://your-openstack:5000/v3"
export OS_USERNAME="your-username"
export OS_PASSWORD="your-password"
export OS_PROJECT_ID="your-project-id"
export OS_REGION_NAME="RegionOne"

# List available services and checks
poetry run prowler openstack --list-services
poetry run prowler openstack --list-checks

3. Test Credential Validation:

# Should fail with clear error message about missing credentials
unset OS_AUTH_URL
poetry run prowler openstack

# Should succeed with valid credentials
export OS_AUTH_URL="https://your-openstack:5000/v3"
poetry run prowler openstack --check keystone_projects_enabled

4. Execute Security Checks:

# Run all OpenStack checks
poetry run prowler openstack

# Run by service
poetry run prowler openstack --service keystone
poetry run prowler openstack --service compute

# Run specific check
poetry run prowler openstack --check compute_instance_security_groups_attached

5. Verify Code Quality:

  • Check that all new code follows Google Python Style Guide docstrings
  • Verify type hints are present on all public functions
  • Review error handling and logging patterns
  • Confirm test coverage for edge cases

6. Review Key Files:

  • prowler/providers/openstack/openstack_provider.py - Provider implementation
  • prowler/providers/openstack/models.py - Session and identity models
  • prowler/providers/openstack/services/*/ - Service implementations
  • tests/providers/openstack/* - Test coverage

Checklist

Community Checklist
  • This feature/issue is listed in here or roadmap.prowler.com
  • Is it assigned to me, if not, request it via the issue/feature in here or Prowler Community Slack

SDK/CLI

  • Are there new checks included in this PR? Yes / No
    • If so, do we need to update permissions for the provider? Please review this carefully.

UI

  • All issue/task requirements work as expected on the UI
  • Screenshots/Video of the functionality flow (if applicable) - Mobile (X < 640px)
  • Screenshots/Video of the functionality flow (if applicable) - Table (640px > X < 1024px)
  • Screenshots/Video of the functionality flow (if applicable) - Desktop (X > 1024px)
  • Ensure new entries are added to CHANGELOG.md, if applicable.

API

  • All issue/task requirements work as expected on the API
  • Endpoint response output (if applicable)
  • EXPLAIN ANALYZE output for new/modified queries or indexes (if applicable)
  • Performance test results (if applicable)
  • Any other relevant evidence of the implementation (if applicable)
  • Verify if API specs need to be regenerated.
  • Check if version updates are required (e.g., specs, Poetry, etc.).
  • Ensure new entries are added to CHANGELOG.md, if applicable.

License

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@danibarranqueroo danibarranqueroo requested review from a team as code owners January 16, 2026 12:21
@github-actions github-actions bot added output/html Issues/PRs related with the HTML output format compliance Issues/PRs related with the Compliance Frameworks metadata-review labels Jan 16, 2026
@danibarranqueroo danibarranqueroo added no-merge Please, DO NOT MERGE this PR. and removed output/html Issues/PRs related with the HTML output format compliance Issues/PRs related with the Compliance Frameworks metadata-review labels Jan 16, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Jan 16, 2026

Conflict Markers Resolved

All conflict markers have been successfully resolved in this pull request.

@github-actions github-actions bot added output/html Issues/PRs related with the HTML output format compliance Issues/PRs related with the Compliance Frameworks metadata-review labels Jan 16, 2026
@danibarranqueroo danibarranqueroo requested a review from a team as a code owner January 19, 2026 13:38
@github-actions
Copy link
Contributor

github-actions bot commented Jan 19, 2026

✅ All necessary CHANGELOG.md files have been updated.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 19, 2026

🔒 Container Security Scan

Image: prowler:7625571
Last scan: 2026-01-22 12:59:49 UTC

📊 Vulnerability Summary

Severity Count
🔴 Critical 3
Total 3

3 package(s) affected

⚠️ Action Required

Critical severity vulnerabilities detected. These should be addressed before merging:

  • Review the detailed scan results
  • Update affected packages to patched versions
  • Consider using a different base image if updates are unavailable

📋 Resources:

@github-actions
Copy link
Contributor

github-actions bot commented Jan 19, 2026

🔒 Container Security Scan

Image: prowler-api:0917a85
Last scan: 2026-01-19 13:47:31 UTC

📊 Vulnerability Summary

Severity Count
🔴 Critical 11
Total 11

10 package(s) affected

⚠️ Action Required

Critical severity vulnerabilities detected. These should be addressed before merging:

  • Review the detailed scan results
  • Update affected packages to patched versions
  • Consider using a different base image if updates are unavailable

📋 Resources:

@codecov
Copy link

codecov bot commented Jan 19, 2026

Codecov Report

❌ Patch coverage is 85.88235% with 48 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.56%. Comparing base (963ece9) to head (896af57).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #9811      +/-   ##
==========================================
- Coverage   92.85%   84.56%   -8.29%     
==========================================
  Files         137     1517    +1380     
  Lines        3387    47655   +44268     
==========================================
+ Hits         3145    40300   +37155     
- Misses        242     7355    +7113     
Flag Coverage Δ
prowler-py3.10-aws 90.54% <ø> (?)
prowler-py3.10-azure 89.78% <ø> (?)
prowler-py3.10-config 84.50% <85.88%> (?)
prowler-py3.10-gcp 90.11% <ø> (-2.75%) ⬇️
prowler-py3.10-github 89.36% <ø> (?)
prowler-py3.10-iac 89.02% <ø> (?)
prowler-py3.10-kubernetes 89.74% <ø> (?)
prowler-py3.10-lib 84.53% <85.84%> (?)
prowler-py3.10-m365 89.29% <ø> (?)
prowler-py3.10-mongodbatlas 88.92% <ø> (?)
prowler-py3.10-nhn 89.31% <ø> (?)
prowler-py3.10-openstack 86.79% <93.97%> (?)
prowler-py3.10-oraclecloud 86.73% <ø> (?)
prowler-py3.11-aws 90.60% <ø> (?)
prowler-py3.11-azure 89.82% <ø> (?)
prowler-py3.11-config 84.53% <85.88%> (?)
prowler-py3.11-gcp 90.14% <ø> (-2.71%) ⬇️
prowler-py3.11-github 89.39% <ø> (?)
prowler-py3.11-iac 89.05% <ø> (?)
prowler-py3.11-kubernetes 89.77% <ø> (?)
prowler-py3.11-lib 84.55% <85.84%> (?)
prowler-py3.11-m365 89.32% <ø> (?)
prowler-py3.11-mongodbatlas 88.95% <ø> (?)
prowler-py3.11-nhn 89.34% <ø> (?)
prowler-py3.11-openstack 86.82% <93.97%> (?)
prowler-py3.11-oraclecloud 86.76% <ø> (?)
prowler-py3.12-aws 90.58% <ø> (?)
prowler-py3.12-azure 89.80% <ø> (?)
prowler-py3.12-config 84.50% <85.88%> (?)
prowler-py3.12-gcp 90.12% <ø> (-2.74%) ⬇️
prowler-py3.12-github 89.37% <ø> (?)
prowler-py3.12-iac 89.01% <ø> (?)
prowler-py3.12-kubernetes 89.75% <ø> (?)
prowler-py3.12-lib 84.52% <85.84%> (?)
prowler-py3.12-m365 89.29% <ø> (?)
prowler-py3.12-mongodbatlas 88.91% <ø> (?)
prowler-py3.12-nhn 89.32% <ø> (?)
prowler-py3.12-openstack 86.78% <93.97%> (?)
prowler-py3.12-oraclecloud 86.73% <ø> (?)
prowler-py3.9-aws 90.55% <ø> (?)
prowler-py3.9-azure 89.78% <ø> (?)
prowler-py3.9-config 84.49% <85.88%> (?)
prowler-py3.9-gcp 90.10% <ø> (-2.75%) ⬇️
prowler-py3.9-github 89.36% <ø> (?)
prowler-py3.9-iac 89.00% <ø> (?)
prowler-py3.9-kubernetes 89.73% <ø> (?)
prowler-py3.9-lib 84.51% <85.84%> (?)
prowler-py3.9-m365 89.27% <ø> (?)
prowler-py3.9-mongodbatlas 88.90% <ø> (?)
prowler-py3.9-nhn 89.30% <ø> (?)
prowler-py3.9-openstack 86.77% <93.97%> (?)
prowler-py3.9-oraclecloud 86.72% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

Components Coverage Δ
prowler 84.56% <85.88%> (-8.29%) ⬇️
api ∅ <ø> (∅)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment on lines +9 to +13
def is_finding_muted(
self,
finding: CheckReportOpenStack,
project_id: str,
) -> bool:

Check warning

Code scanning / CodeQL

Signature mismatch in overriding method Warning

This method requires 3 positional arguments, whereas overridden
Mutelist.is_finding_muted
requires 1.

Copilot Autofix

AI 7 days ago

In general, this problem is fixed by ensuring that the overriding method in the subclass has a compatible signature with the base class method. The usual pattern is: match the base method’s parameters (names, order, and defaults) and then adapt them internally as needed without changing the method’s external contract.

Here, we must align OpenStackMutelist.is_finding_muted with Mutelist.is_finding_muted. CodeQL says the overridden method requires 1 positional argument (in addition to self), whereas the subclass currently defines two (finding and project_id). The most conservative, non-breaking fix (for callers) is to shrink the public signature to match the base class: accept only finding (besides self) and then obtain project_id from the finding object itself. Since CheckReportOpenStack is specific to OpenStack, it is reasonable that it carries a project identifier (typically something like finding.project_id, finding.account_id, or similar). To avoid assumptions about other files, we should access a likely attribute defensively, but we cannot edit other files, so the best we can do is use an attribute name that’s already evidently part of CheckReportOpenStack’s semantics. The file name and context strongly imply that project_id is available as finding.project_id.

Concretely, in prowler/providers/openstack/lib/mutelist/mutelist.py, change the method signature from:

def is_finding_muted(
    self,
    finding: CheckReportOpenStack,
    project_id: str,
) -> bool:

to:

def is_finding_muted(
    self,
    finding: CheckReportOpenStack,
) -> bool:
    project_id = finding.project_id

and then use project_id exactly as before in the calls to self.is_muted. The rest of the method body remains the same. This ensures that the override is compatible with the base class method: callers pass only the finding object as per the base-class contract, while the OpenStack-specific logic still has access to the project identifier.

Suggested changeset 1
prowler/providers/openstack/lib/mutelist/mutelist.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/prowler/providers/openstack/lib/mutelist/mutelist.py b/prowler/providers/openstack/lib/mutelist/mutelist.py
--- a/prowler/providers/openstack/lib/mutelist/mutelist.py
+++ b/prowler/providers/openstack/lib/mutelist/mutelist.py
@@ -9,9 +9,9 @@
     def is_finding_muted(
         self,
         finding: CheckReportOpenStack,
-        project_id: str,
     ) -> bool:
         """Return True when the finding should be muted for the audited project."""
+        project_id = finding.project_id
         # Try matching with both resource_id and resource_name for better UX
         # Users can specify either the UUID or the friendly name in the mutelist
         muted_by_id = self.is_muted(
EOF
@@ -9,9 +9,9 @@
def is_finding_muted(
self,
finding: CheckReportOpenStack,
project_id: str,
) -> bool:
"""Return True when the finding should be muted for the audited project."""
project_id = finding.project_id
# Try matching with both resource_id and resource_name for better UX
# Users can specify either the UUID or the friendly name in the mutelist
muted_by_id = self.is_muted(
Copilot is powered by AI and may make mistakes. Always verify output.
from pathlib import Path
from typing import Optional

import openstack

Check notice

Code scanning / CodeQL

Module is imported with 'import' and 'import from' Note

Module 'openstack' is imported with both 'import' and 'import from'.
Module 'prowler.providers.openstack' is imported with both 'import' and 'import from'.
Module 'prowler.compliance.openstack' is imported with both 'import' and 'import from'.

Copilot Autofix

AI 7 days ago

In general, to fix this pattern you avoid importing the same module both with import module and from module import something. Instead, keep one style and, if needed, create aliases like something = module.something after a single import module.

For this file, the minimal, safest change is to remove the unused broad import import openstack on line 5 and rely solely on from openstack.connection import Connection as OpenStackConnection, which is already present and clearly used via the OpenStackConnection type annotation. Since we are not allowed to modify code beyond the shown snippet and we see no direct uses of the openstack package object here, the best assumption to preserve functionality is that import openstack is unnecessary in this file. No additional methods or imports are required to support this; we only delete that one import line in prowler/providers/openstack/openstack_provider.py.

Suggested changeset 1
prowler/providers/openstack/openstack_provider.py

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/prowler/providers/openstack/openstack_provider.py b/prowler/providers/openstack/openstack_provider.py
--- a/prowler/providers/openstack/openstack_provider.py
+++ b/prowler/providers/openstack/openstack_provider.py
@@ -2,7 +2,6 @@
 from pathlib import Path
 from typing import Optional
 
-import openstack
 import openstack.config
 from colorama import Fore, Style
 from openstack import exceptions as openstack_exceptions
EOF
@@ -2,7 +2,6 @@
from pathlib import Path
from typing import Optional

import openstack
import openstack.config
from colorama import Fore, Style
from openstack import exceptions as openstack_exceptions
Copilot is powered by AI and may make mistakes. Always verify output.
@danibarranqueroo danibarranqueroo requested a review from a team as a code owner January 22, 2026 12:50
@github-actions github-actions bot added the github_actions Pull requests that update GitHub Actions code label Jan 22, 2026
@danibarranqueroo danibarranqueroo added provider/openstack and removed no-merge Please, DO NOT MERGE this PR. labels Jan 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

compliance Issues/PRs related with the Compliance Frameworks github_actions Pull requests that update GitHub Actions code metadata-review output/html Issues/PRs related with the HTML output format provider/openstack

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants