Back to Checks
oraclecloud

Instance principal authentication is configured for OCI instances, OCI Cloud Databases, and OCI Functions

identity_instance_principal_used
Service: identitySeverity: medium
OfficialBuilt-inVerified
Categories:identity-access
Resource Type:DynamicResourceGroup

OCI dynamic groups configured for instance principal access to workloads like Compute instances, Functions, and Autonomous Databases. The evaluation looks for matching rules that target these resources (e.g., instance, fnfunc, autonomousdatabase) to confirm workload identity usage.

Risk

Using user credentials or long-lived keys instead of instance principals exposes secrets and weakens least privilege and accountability. Stolen keys from code or pipelines enable unauthorized API calls, data exfiltration, and privilege abuse, impacting confidentiality and integrity of OCI resources.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler oraclecloud --checks identity_instance_principal_used

Recommendation

Adopt workload identities with instance principals and granular dynamic groups. Apply least privilege policies to those groups, avoid long-lived user keys, and remove embedded credentials from code and CI/CD. Monitor access patterns and favor short-lived, auditable tokens as part of a zero trust approach.

Remediation

CLI

oci iam dynamic-group create --compartment-id <example_resource_id> --name <example_resource_name> --matching-rule "ALL {resource.type = 'instance'}"

Terraform

resource "oci_identity_dynamic_group" "dg" {
  compartment_id = "<example_resource_id>"
  name           = "<example_resource_name>"
  description    = "Enable instance principals"
  matching_rule  = "ALL {resource.type = 'instance'}" # Critical: creates a Dynamic Group for instances to enable instance principal auth
}

Other

1In the OCI Console, go to Identity & Security > Dynamic Groups
2Click Create Dynamic Group
3Enter Name: <example_resource_name>
4Set Matching Rule to: ALL {resource.type = 'instance'}
5Click Create

Check Code

"""Check Ensure Instance Principal authentication is used for OCI instances, OCI Cloud Databases and OCI Functions to access OCI resources."""

from prowler.lib.check.models import Check, Check_Report_OCI
from prowler.providers.oraclecloud.services.identity.identity_client import (
    identity_client,
)


class identity_instance_principal_used(Check):
    """Check Ensure Instance Principal authentication is used for OCI instances, OCI Cloud Databases and OCI Functions to access OCI resources."""

    def execute(self) -> Check_Report_OCI:
        """Execute the identity_instance_principal_used check."""
        findings = []

        # Resources to check for in matching rules
        oci_resources = [
            "fnfunc",
            "instance",
            "autonomousdatabase",
            "resource.compartment.id",
        ]

        # Track which dynamic groups have valid instance principal configurations
        valid_dynamic_groups = []
        invalid_dynamic_groups = []

        for dynamic_group in identity_client.dynamic_groups:
            matching_rule_upper = dynamic_group.matching_rule.upper()

            # Check if any of the OCI resources are in the matching rule
            if any(
                oci_resource.upper() in matching_rule_upper
                for oci_resource in oci_resources
            ):
                valid_dynamic_groups.append(dynamic_group)
            else:
                invalid_dynamic_groups.append(dynamic_group)

        # Determine the region - use the first dynamic group's region if available, otherwise first audited region
        region = "global"
        if identity_client.dynamic_groups:
            region = identity_client.dynamic_groups[0].region
        elif identity_client.audited_regions:
            first_region = identity_client.audited_regions[0]
            region = (
                first_region.key if hasattr(first_region, "key") else str(first_region)
            )

        # Create a report for the tenancy
        report = Check_Report_OCI(
            metadata=self.metadata(),
            resource={},
            region=region,
            resource_name="Instance Principal Configuration",
            resource_id=identity_client.audited_tenancy,
            compartment_id=identity_client.audited_tenancy,
        )

        # If there are valid dynamic groups for instance principals, PASS
        if valid_dynamic_groups:
            report.status = "PASS"
            report.status_extended = f"Dynamic Groups are configured for instance principal authentication. Found {len(valid_dynamic_groups)} dynamic group(s) with proper matching rules."
        else:
            report.status = "FAIL"
            report.status_extended = "No Dynamic Groups found with matching rules for instance principals (instances, functions, or databases)."

        findings.append(report)

        return findings