Back to Checks
aws

Confidential-workload host enforces IMDSv2

ec2_confidential_workload_host_imdsv2_not_enforced
Service: ec2Severity: high
OfficialBuilt-inVerified
Categories:identity-accessec2-imdsv1
Resource Type:AwsEc2Instance

Instances hosting Nitro Enclave workloads (EnclaveOptions.Enabled=true) are evaluated for IMDSv2 enforcement on the metadata service (HttpTokens=required). This check assesses the host environment; it does not audit the enclave itself.

Risk

IMDSv1 exposes temporary IAM credentials to SSRF and workload-compromise paths on the host, undermining the confidentiality of the identity the enclave workload depends on.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks ec2_confidential_workload_host_imdsv2_not_enforced

Recommendation

Apply defense in depth on identity surfaces: require IMDSv2 on every confidential-workload host so credentials cannot be lifted from the metadata service via SSRF or a compromised workload on the host.

Remediation

CLI

aws ec2 modify-instance-metadata-options --instance-id <instance-id> --http-tokens required --http-endpoint enabled

Terraform

resource "aws_instance" "example_resource" {
  enclave_options { enabled = true }
  metadata_options {
    http_tokens = "required"  # critical: enforce IMDSv2
    http_endpoint = "enabled"
  }
}

NativeIaC

Resources:
  example_resource:
    Type: AWS::EC2::Instance
    Properties:
      EnclaveOptions: { Enabled: true }
      MetadataOptions:
        HttpTokens: required  # critical: enforce IMDSv2

Other

1Open the EC2 console.
2Select the confidential-workload host and choose Actions > Instance settings > Modify instance metadata options.
3Set IMDS to Enabled and IMDSv2 to Required.
4Save.

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.ec2.ec2_client import ec2_client
from prowler.providers.aws.services.ec2.lib.enclave import (
    HOST_TRUST_MODEL_BOILERPLATE,
    is_enclave_parent,
)


class ec2_confidential_workload_host_imdsv2_not_enforced(Check):
    """Ensure confidential-workload host instances enforce IMDSv2.

    The confidential-workload host (an EC2 instance with
    ``EnclaveOptions.Enabled=true``) inherits and passes its IAM identity to
    every Nitro Enclave it operates. When the host still accepts IMDSv1, SSRF
    and other workload-compromise paths on the host expose the temporary
    credentials the enclave workload depends on. This check assesses the host
    environment; it does not audit the enclave itself.

    - PASS: The host has ``HttpTokens=required`` (IMDSv2 enforced).
    - FAIL: The host still allows IMDSv1 (``HttpTokens=optional``).
    """

    def execute(self) -> list[Check_Report_AWS]:
        """Execute the confidential-workload host IMDSv2 enforcement check.

        Iterates confidential-workload hosts (instances with enclaves enabled)
        and reports whether each one enforces IMDSv2 on the metadata service.

        Returns:
            list[Check_Report_AWS]: One report per confidential-workload host.
        """
        findings = []
        for instance in ec2_client.instances:
            if not is_enclave_parent(instance):
                continue
            report = Check_Report_AWS(metadata=self.metadata(), resource=instance)
            if instance.http_tokens == "required":
                report.status = "PASS"
                report.status_extended = (
                    f"Confidential-workload host {instance.id} enforces "
                    f"IMDSv2. {HOST_TRUST_MODEL_BOILERPLATE}"
                )
            else:
                report.status = "FAIL"
                report.status_extended = (
                    f"Confidential-workload host {instance.id} does not "
                    f"enforce IMDSv2 (HttpTokens={instance.http_tokens}). "
                    f"{HOST_TRUST_MODEL_BOILERPLATE}"
                )
            findings.append(report)
        return findings