Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.prowler.com/llms.txt

Use this file to discover all available pages before exploring further.

This page details the StackIT Cloud provider implementation in Prowler. By default, Prowler audits a single StackIT project per scan. To configure it, provide the project ID and either a service account key file path or inline service account key JSON.

StackIT Provider Classes Architecture

The StackIT provider implementation follows the general Provider structure. This section focuses on the StackIT-specific implementation, highlighting how the generic provider concepts are realized for StackIT in Prowler. For a full overview of the provider pattern, base classes, and extension guidelines, see Provider documentation.

StackitProvider (Main Class)

  • Location: prowler/providers/stackit/stackit_provider.py
  • Base Class: Inherits from Provider (see base class details).
  • Purpose: Central orchestrator for StackIT-specific logic, API authentication, credential validation, and configuration.
  • Key StackIT Responsibilities:
    • Initializes StackIT SDK authentication via a service account key file or inline service account key JSON. The SDK mints and refreshes access tokens internally.
    • Validates the service account credentials and project ID (UUID format validation).
    • Loads and manages configuration, mutelist, and fixer settings.
    • Provides properties and methods for downstream StackIT service classes to access credentials, identity, and configuration data.

Data Models

  • Location: prowler/providers/stackit/models.py
  • Purpose: Define structured data for StackIT identity and output configuration.
  • Key StackIT Models:
    • StackITIdentityInfo: Holds StackIT identity metadata, including project ID and project name (fetched automatically from Resource Manager API).
    • StackITOutputOptions: Customizes default output filenames so StackIT reports include the audited project ID.
    • IaaS resource models such as SecurityGroup and SecurityGroupRule are defined in the IaaS service module.

StackIT Services

  • Location: prowler/providers/stackit/services/
  • Purpose: Implement StackIT service clients and resource collection logic following the generic service pattern.
  • Current Implementation: The IaaSService collects security groups, rules, and network interface usage across supported StackIT regions.

Exception Handling

  • Location: prowler/providers/stackit/exceptions/exceptions.py
  • Purpose: Custom exception classes for StackIT-specific error handling, such as credential validation, API connection, and configuration errors.
  • Key Exception Classes:
    • StackITBaseException: Base exception for all StackIT provider errors.
    • StackITCredentialsError: Raised when credentials are invalid or missing.
    • StackITInvalidProjectIdError: Raised when project ID is invalid or not in UUID format.
    • StackITAPIError: Raised when StackIT API calls fail.

Authentication

Service Account Creation and Key Generation

StackIT uses service account keys for API authentication. Service account keys are RSA key-pair based and provide secure, short-lived access tokens.

Creating a Service Account Key

Method 1: Via StackIT Portal

  1. Navigate to Service Accounts
    • Go to the StackIT Portal
    • Select your project
    • Click on Service Accounts in the left sidebar
  2. Create or Select Service Account
    • If you don’t have a service account, click Create Service Account
    • Provide a name and description
    • Assign necessary permissions:
      • For IaaS security checks: iaas.viewer or project.owner
      • For comprehensive audits: project.owner
  3. Generate Service Account Key
    • Select your service account
    • Navigate to Service Account Keys
    • Click Create key
    • Choose one of the following options:
      • STACKIT-generated key pair (Recommended): Let STACKIT automatically generate an RSA key-pair
      • User-provided key pair: Upload your own RSA 2048 public key
  4. Download and Save the Key
    • Download the generated service account key file (JSON format)
    • Important: Save the key securely - it contains your private key and will only be available once
    • Store the key file in a secure location (e.g., ~/.stackit/sa_key.json)

Method 2: Via StackIT CLI

# Install STACKIT CLI (if not already installed)
# Follow instructions at: https://github.com/stackitcloud/stackit-cli

# Create service account key (STACKIT-generated)
stackit service-account key create --email my-service-account@example.com

# Or create with your own RSA 2048 public key
# First, generate your RSA key pair:
openssl genrsa -out private-key.pem 2048
openssl rsa -in private-key.pem -pubout -out public-key.pem

# Then create the key with your public key:
stackit service-account key create \
  --email my-service-account@example.com \
  --public-key "$(cat public-key.pem)"

Finding Your Project ID

Your StackIT project ID is a UUID that can be found:
  1. In the StackIT Portal URL when viewing your project: https://portal.stackit.cloud/projects/{PROJECT_ID}/...
  2. In the project settings page
  3. Using the StackIT CLI: stackit project list

Passing the Service Account Key to Prowler

Prowler accepts the service account credentials in two equivalent forms; both go through the same StackIT SDK flow and refresh access tokens internally.

Option 1: Key File Path (key persisted on disk)

export STACKIT_SERVICE_ACCOUNT_KEY_PATH="$HOME/.stackit/sa-key.json"
export STACKIT_PROJECT_ID="12345678-1234-1234-1234-123456789abc"

prowler stackit
Or as CLI flags:
prowler stackit \
  --stackit-service-account-key-path ~/.stackit/sa-key.json \
  --stackit-project-id 12345678-1234-1234-1234-123456789abc

Option 2: Inline Key Content (CI/CD, secret managers)

export STACKIT_SERVICE_ACCOUNT_KEY="$(vault kv get -field=key stackit/sa)"
export STACKIT_PROJECT_ID="12345678-1234-1234-1234-123456789abc"

prowler stackit
Prefer the environment variable over the matching --stackit-service-account-key CLI flag; passing the secret on the command line leaks it through process listings and shell history.

Credential Lookup Order

Prowler resolves credentials in this order:
  1. Command-line arguments:
    • --stackit-service-account-key
    • --stackit-service-account-key-path
    • --stackit-project-id
  2. Environment variables:
    • STACKIT_SERVICE_ACCOUNT_KEY
    • STACKIT_SERVICE_ACCOUNT_KEY_PATH
    • STACKIT_PROJECT_ID
When both the inline key and the key file path are set, the inline content takes precedence.

Configuration

Command-Line Arguments

StackIT-specific command-line arguments:
ArgumentDescriptionRequiredDefault
--stackit-service-account-key-pathPath to a StackIT service account key JSON fileYes*$STACKIT_SERVICE_ACCOUNT_KEY_PATH
--stackit-service-account-keyInline JSON content of a StackIT service account key (preferred env var: STACKIT_SERVICE_ACCOUNT_KEY)Yes*$STACKIT_SERVICE_ACCOUNT_KEY
--stackit-project-idStackIT project ID (UUID format)Yes*$STACKIT_PROJECT_ID
--stackit-regionStackIT region(s) to scanNoAll available regions
* Required unless provided via environment variables.

Input Validation

The StackIT provider performs comprehensive input validation:
  • Service Account Credentials:
    • At least one of service_account_key_path (file path) or service_account_key (inline JSON) must be supplied; both empty raises StackITNonExistentTokenError
    • When both are provided the inline content takes precedence
    • The key file path is logged as-is; the inline content is redacted in the credentials box
  • Project ID:
    • Must not be empty
    • Must be a valid UUID format (e.g., 12345678-1234-1234-1234-123456789abc)
    • Validated using Python’s UUID constructor
Invalid credentials will result in clear error messages before any API calls are made.

Available Services

IaaS (Infrastructure as a Service)

Supported Resources:
  • Security Groups and Rules
  • Servers (Virtual Machines)
  • Network Interfaces (NICs)
Key Features:
  • Automatic discovery of all security groups in the project
  • Security rule parsing with support for unrestricted access detection
  • Network interface analysis to determine whether security groups are in use
  • By default, reports only security groups attached to at least one NIC; --scan-unused-services includes unused security groups too

Available Checks

The StackIT provider currently implements 4 security checks focused on network security:

1. iaas_security_group_ssh_unrestricted

  • Severity: High
  • Description: Detects security groups that allow unrestricted SSH access (port 22) from the internet.
  • Risk: Unrestricted SSH access increases the attack surface and risk of brute-force attacks.
  • Detection Logic:
    • Checks for ingress rules allowing TCP port 22
    • Flags rules with ip_range=None or ip_range="0.0.0.0/0" or ip_range="::/0"
    • Reports security groups attached to NICs by default, or all security groups when --scan-unused-services is enabled

2. iaas_security_group_rdp_unrestricted

  • Severity: High
  • Description: Detects security groups that allow unrestricted RDP access (port 3389) from the internet.
  • Risk: Unrestricted RDP access enables potential unauthorized remote desktop access.
  • Detection Logic:
    • Checks for ingress rules allowing TCP port 3389
    • Flags unrestricted IP ranges (None, 0.0.0.0/0, ::/0)
    • Reports security groups attached to NICs by default, or all security groups when --scan-unused-services is enabled

3. iaas_security_group_database_unrestricted

  • Severity: High
  • Description: Detects security groups that allow unrestricted access to common database ports.
  • Monitored Ports:
    • MySQL: 3306
    • PostgreSQL: 5432
    • MongoDB: 27017
    • Redis: 6379
    • SQL Server: 1433
    • CouchDB: 5984
  • Risk: Unrestricted database access can lead to data breaches and unauthorized data access.

4. iaas_security_group_all_traffic_unrestricted

  • Severity: Critical
  • Description: Detects security groups that allow all traffic from the internet.
  • Detection Logic:
    • Checks for rules with port_range=None (all ports)
    • Checks for rules with port range covering 0-65535 or 1-65535
    • Flags unrestricted IP ranges
    • Critical security misconfiguration requiring immediate remediation

Important Implementation Notes

Self-Referencing Security Group Rules: Security group rules with remoteSecurityGroupId set are automatically filtered out from unrestricted access checks. These rules only allow traffic from instances within the same security group (self-referencing), not from the internet, and are therefore not flagged as security risks. Rule Display Names: All findings include user-friendly rule descriptions when available. If a security group rule has a description field set (the name shown in the StackIT UI), it will be displayed in the finding message along with the rule ID:
  • With description: 'Allow SSH from office' (sgr-abc123)
  • Without description: 'sgr-abc123'
Network Interface (NIC) Usage Filtering: The IaaS service lists project NICs and records the security group IDs attached to them. Checks use that signal to decide whether a security group is in use:
  1. Default behavior: Report security groups attached to at least one NIC.
  2. --scan-unused-services: Report every security group, including unused ones.
  3. FAIL logic: Internet exposure is driven by security group rules that allow unrestricted source ranges, not by the presence of a public IP on the NIC.
Unrestricted IP Ranges: The StackIT API represents “unrestricted” in two ways:
  • ip_range=null: No IP restriction specified (implicit unrestricted)
  • ip_range="0.0.0.0/0" or "::/0": Explicitly configured to allow all IPs
Both are flagged as unrestricted. A null value is more permissive than an explicit range and applies to all protocols/ports if other fields are also null.

Requirements

Python Version

  • Minimum: Python 3.10+
  • Reason: The StackIT SDK requires Python 3.10 or higher

Dependencies

The StackIT provider requires the following Python packages (automatically installed with Prowler):
  • stackit-core (v0.2.0): Core SDK for StackIT API authentication and configuration
  • stackit-iaas (v1.4.0): IaaS service SDK for managing compute resources
  • stackit-resourcemanager (v0.8.0): Resource Manager SDK for fetching project metadata (e.g., project names)
These dependencies are defined in pyproject.toml and installed automatically with:
poetry install
Note: The stackit-resourcemanager package enables automatic retrieval of project names for display in reports. If this package is not available, Prowler will still function normally but project names will be empty in the output.

Region Support

Supported Regions

  • Available Regions: eu01 (Germany South) and eu02 (Austria West)
  • Default: All scans use both eu01 and eu02 regions by default.

Multi-Region Scanning

Prowler supports scanning multiple StackIT regions in a single execution. By default, it will scan all regions defined in the stackit_regions_by_service.json configuration file.

CLI Argument

You can specify which regions to scan using the --stackit-region argument:
# Scan only eu01
prowler stackit --stackit-region eu01

# Scan both eu01 and eu02
prowler stackit --stackit-region eu01 eu02

Implementation Details

  • Regional Clients: Prowler generates a separate API client for each audited region.
  • Service Iteration: Each service (e.g., IaaS) iterates through the regional clients to fetch and audit resources.
  • Identity Tracking: The audited_regions are stored in the identity model for reporting.

Future Enhancements

As StackIT adds more regions, they can be easily added to Prowler by updating the prowler/providers/stackit/stackit_regions_by_service.json file without requiring code changes.

Command Examples

Scan Specific Regions

Scan only the eu01 region:
export STACKIT_SERVICE_ACCOUNT_KEY_PATH="$HOME/.stackit/sa-key.json"

prowler stackit \
  --stackit-project-id "your-project-id" \
  --stackit-region eu01
Scan multiple regions:
export STACKIT_SERVICE_ACCOUNT_KEY_PATH="$HOME/.stackit/sa-key.json"

prowler stackit \
  --stackit-project-id "your-project-id" \
  --stackit-region eu01 eu02

Scan Specific Checks

Run only SSH unrestricted check:
export STACKIT_SERVICE_ACCOUNT_KEY_PATH="$HOME/.stackit/sa-key.json"

prowler stackit \
  --stackit-project-id "your-project-id" \
  --checks iaas_security_group_ssh_unrestricted

Scan All Security Group Checks

export STACKIT_SERVICE_ACCOUNT_KEY_PATH="$HOME/.stackit/sa-key.json"

prowler stackit \
  --stackit-project-id "your-project-id" \
  --services iaas

Output Formats

Generate JSON output:
export STACKIT_SERVICE_ACCOUNT_KEY_PATH="$HOME/.stackit/sa-key.json"

prowler stackit \
  --stackit-project-id "your-project-id" \
  --output-formats json
Generate HTML report:
export STACKIT_SERVICE_ACCOUNT_KEY_PATH="$HOME/.stackit/sa-key.json"

prowler stackit \
  --stackit-project-id "your-project-id" \
  --output-formats html

Known Limitations

Current Limitations

  1. Single Project Scope: Only one project can be scanned at a time
  2. Service Coverage: Only the IaaS service is currently implemented
  3. Check Coverage: Limited to security group network security checks (4 checks total)
  4. No Compliance Frameworks: Compliance framework mappings are not yet implemented

Planned Enhancements

  • Multi-project scanning capability
  • Additional IaaS checks (volume encryption, server public IP exposure, backup status)
  • Compliance framework mappings (CIS, custom StackIT best practices)
  • StackIT CLI remediation examples in metadata

Troubleshooting

Authentication Errors

Error: StackIT service account key was rejected Solutions:
  1. Re-issue the service account key in the StackIT Portal
  2. Verify the service account key file or inline JSON content is complete
  3. Check that the service account has the necessary permissions (iaas.viewer or project.owner)
  4. Ensure the service account key is provided through STACKIT_SERVICE_ACCOUNT_KEY_PATH, STACKIT_SERVICE_ACCOUNT_KEY, or the matching CLI arguments
Error: StackIT credentials not found or are invalid Solutions:
  1. Ensure the project ID and one service account credential source are provided
  2. Check that credentials are set via environment variables or command-line arguments
  3. Verify there are no extra spaces or newlines in the credentials
Error: Invalid StackIT project ID format Solutions:
  1. Verify the project ID is a valid UUID format: 12345678-1234-1234-1234-123456789abc
  2. Copy the project ID directly from the StackIT Portal
  3. Ensure there are no extra spaces or quotes around the UUID

API Connection Errors

Error: Failed to connect to StackIT API Solutions:
  1. Check your internet connection
  2. Verify the StackIT API endpoint is accessible from your network
  3. Check if there are any firewall rules blocking HTTPS connections
  4. Review the full error message for specific API error codes
Error: HTTP 403 Forbidden Solutions:
  1. Verify the service account has the correct permissions
  2. Ensure the project ID is correct and you have access to it
  3. Check that the service account is enabled (not disabled or expired)
  4. Verify the service account key has not been revoked
Error: HTTP 404 Not Found Solutions:
  1. Verify the project ID exists and is correct
  2. Check that the IaaS service is enabled in your project
  3. Ensure you’re using the correct region (eu01)

Empty Results

Issue: No security groups or findings reported Solutions:
  1. Verify that security groups exist in your project
  2. Check that the IaaS service is properly configured
  3. Ensure the service account has iaas.viewer permission
  4. Check Prowler logs for any API errors (use --log-level DEBUG)

Debug Mode

Enable debug logging for detailed troubleshooting:
export STACKIT_SERVICE_ACCOUNT_KEY_PATH="$HOME/.stackit/sa-key.json"

prowler stackit \
  --stackit-project-id "your-project-id" \
  --log-level DEBUG
This will show:
  • API authentication details (with inline service account keys redacted)
  • Resource discovery progress
  • Security rule parsing details
  • Any API errors or warnings

Specific Patterns in StackIT Services

The generic service pattern is described in service page. You can find all the currently implemented services in the following locations: The best reference to understand how to implement a new service is following the service implementation documentation and taking other StackIT services as reference.

StackIT Service Common Patterns

  • Services communicate with StackIT using the StackIT Python SDK, you can find the documentation here.
  • Service constructors receive a StackitProvider instance and use it to access credentials, identity, and configuration.
  • The provider builds StackIT SDK Configuration objects from the service account key path or inline key content.
  • Resource containers must be initialized in the constructor, typically as lists or dictionaries.
  • Do not manipulate os.environ for credentials inside services. Use the provider session and SDK configuration helpers.
  • All StackIT resources are represented as Pydantic BaseModel classes, providing type safety and structured access to resource attributes.
  • StackIT SDK calls are wrapped in try/except blocks, with specific handling for API errors, always logging errors.
  • Centralized Error Handling: Use provider.handle_api_error(exception) for consistent authentication error detection across all services.
  • SDK Warning Suppression: StackIT SDK prints deprecation warnings to stderr - use the suppress_stderr() context manager during SDK initialization and API calls.
  • Unrestricted Access Detection: In StackIT API, None values mean “allow all” (more permissive than explicit 0.0.0.0/0).
    • protocol=None → All protocols allowed
    • ip_range=None → All source IPs allowed (unrestricted!)
    • port_range=None → All ports allowed
    • remote_security_group_id set → Only allows traffic from the same security group (not unrestricted!)

IaaS Service Specific Patterns

Security Group Discovery:
# List all security groups
security_groups = client.list_security_groups(
    project_id=self.project_id,
    region=region,
)

# List network interfaces to determine security group usage
nics = client.list_project_nics(
    project_id=self.project_id,
    region=region,
)

# Checks report in-use security groups by default. Use --scan-unused-services
# to include security groups that are not attached to any NIC.
Centralized Authentication Error Handling:
def _handle_api_call(self, api_function, *args, **kwargs):
    """Wrapper for API calls with centralized error handling."""
    try:
        with suppress_stderr():  # Suppress SDK warnings
            return api_function(*args, **kwargs)
    except Exception as e:
        # Use centralized error handler from provider
        self.provider.handle_api_error(e)  # Detects 401 and raises StackITInvalidTokenError
Unrestricted Access Detection:
def is_unrestricted(rule):
    """Check if a rule allows unrestricted access."""
    # Filter out self-referencing rules
    if rule.remote_security_group_id is not None:
        return False
    # Check for unrestricted IP ranges
    return rule.ip_range is None or rule.ip_range in ["0.0.0.0/0", "::/0"]

def is_tcp(rule):
    """Check if a rule applies to TCP protocol."""
    # None means all protocols (including TCP)
    return rule.protocol is None or rule.protocol.lower() in ["tcp", "all"]

def includes_port(rule, port):
    """Check if a rule includes a specific port."""
    # None means all ports
    if rule.port_range is None:
        return True
    return rule.port_range.min <= port <= rule.port_range.max

Specific Patterns in StackIT Checks

The StackIT checks pattern is described in checks page. You can find all the currently implemented checks: The best reference to understand how to implement a new check is following the check creation documentation and taking other similar StackIT checks as reference.

Check Report Class

The CheckReportStackIT class models a single finding for a StackIT resource in a check report. It is defined in prowler/lib/check/models.py and inherits from the generic Check_Report base class.

Purpose

CheckReportStackIT extends the base report structure with StackIT-specific fields, enabling detailed tracking of the resource, project, and location associated with each finding.

Constructor and Attribute Population

When you instantiate CheckReportStackIT, you must provide the check metadata and a resource object. The class will attempt to automatically populate its StackIT-specific attributes from the resource, using the following logic:
  • resource_id:
    • Uses resource.id if present.
    • Otherwise, uses resource.resource_id if present.
    • Defaults to an empty string if none are available.
  • resource_name:
    • Uses resource.name if present.
    • Defaults to an empty string if not available.
  • project_id:
    • Uses resource.project_id if present.
    • Defaults to an empty string if not available (should be set in check logic).
  • location:
    • Uses resource.region if present.
    • Otherwise, uses resource.location if present.
    • Defaults to an empty string if not available.
If the resource object does not contain the required attributes, you must set them manually in the check logic. Other attributes are inherited from the Check_Report class, from which you always have to set the status and status_extended attributes in the check logic.

Example Usage

from prowler.lib.check.models import CheckReportStackIT

report = CheckReportStackIT(
    metadata=self.metadata(),
    resource=security_group
)
report.status = "FAIL"
report.status_extended = f"Security group {security_group.name} allows unrestricted SSH access from the internet."
report.resource_id = security_group.id
report.resource_name = security_group.name
report.project_id = security_group.project_id
report.location = security_group.region

Common Check Pattern

from prowler.lib.check.models import Check, CheckReportStackIT
from prowler.providers.stackit.services.iaas.iaas_client import iaas_client

class iaas_security_group_ssh_unrestricted(Check):
    """Check if IaaS security groups allow unrestricted SSH access."""

    def execute(self):
        findings = []

        for security_group in iaas_client.security_groups:
            if not (iaas_client.scan_unused_services or security_group.in_use):
                continue

            report = CheckReportStackIT(
                metadata=self.metadata(),
                resource=security_group
            )
            report.status = "PASS"
            report.status_extended = f"Security group {security_group.name} does not allow unrestricted SSH access."

            # Check each rule
            for rule in security_group.rules:
                if (rule.is_ingress() and
                    rule.is_tcp() and
                    rule.includes_port(22) and
                    rule.is_unrestricted()):
                    report.status = "FAIL"
                    report.status_extended = f"Security group {security_group.name} allows unrestricted SSH access from the internet."
                    break

            findings.append(report)

        return findings

Resources

Official StackIT Documentation

Python SDK

Prowler Resources

Contributing

If you’d like to contribute to the StackIT provider:
  1. Add New Checks: Follow the check creation guide and use existing StackIT checks as templates
  2. Enhance Services: Implement additional IaaS resource discovery or add new services
  3. Improve Documentation: Add metadata enhancements, CLI remediation examples, or Terraform code samples
  4. Report Issues: Submit bug reports or feature requests on GitHub

Quick Start for Contributors

  1. Install dependencies: poetry install (includes stackit-core and stackit-iaas)
  2. Set credentials: Export STACKIT_SERVICE_ACCOUNT_KEY_PATH and STACKIT_PROJECT_ID
  3. Run checks: prowler stackit
  4. View code: Start in prowler/providers/stackit/
  5. Add checks: Create new check directories under services/iaas/
  6. Run tests: poetry run pytest tests/providers/stackit/ -v

Code Quality Standards

The StackIT provider should follow the same quality expectations as the rest of the Prowler SDK:
  • Keep service and check logic covered by unit tests.
  • Redact inline service account keys from generated output.
  • Keep documentation aligned with the implemented services and checks.
  • Follow existing provider, service, and check patterns before adding StackIT-specific abstractions.