Back to Checks
aws

Nitro Enclave parent instance is in the running state

ec2_confidential_workload_host_not_running
Service: ec2Severity: medium
OfficialBuilt-inVerified
Categories:resilience
Resource Type:AwsEc2Instance

Nitro Enclave parent instances are evaluated against the EC2 lifecycle: the instance state must not be stopped, shutting-down, or terminated. Enclaves are destroyed when their parent stops, so any consumer depending on enclave availability breaks if the parent moves to a terminal state. Transient states (pending, stopping) are reported as PASS with a note.

Risk

A parent in a terminal state means the enclave no longer exists. Any downstream workload that assumes an active enclave silently loses its availability guarantee and may fall back to a less-protected path outside the trust boundary.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks ec2_confidential_workload_host_not_running

Recommendation

Treat enclave availability as an operational contract: keep parents running (or explicitly retire the downstream dependency), and prefer managed lifecycle patterns (Auto Scaling Groups, lifecycle hooks) that recreate the enclave whenever the parent is replaced.

Remediation

CLI

aws ec2 start-instances --instance-ids <instance-id>

Other

1Investigate why the parent stopped (manual action, ASG scale-in, spot interruption).
2If the outage was intentional, decommission any downstream expectation of enclave availability.
3Otherwise, start the instance and relaunch the enclave through `nitro-cli run-enclave` on boot.
4Wrap enclave workloads in Auto Scaling Groups with lifecycle hooks that recreate enclaves after any instance replacement.

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,
)

_TERMINAL_STATES = frozenset({"stopped", "shutting-down", "terminated"})
_TRANSIENT_STATES = frozenset({"pending", "stopping"})


class ec2_confidential_workload_host_not_running(Check):
    """Ensure Nitro Enclave parent instances are in the running state.

    Enclaves are destroyed when their parent EC2 instance stops or terminates.
    An enclave-enabled instance that has moved to ``stopped``,
    ``shutting-down``, or ``terminated`` therefore signals either an
    unexpected outage or a lifecycle change that any consumer relying on
    enclave availability will fail against. Transient lifecycle states
    (``pending``, ``stopping``) are reported as PASS with a note.

    - PASS: The enclave-enabled instance is running or in a transient state.
    - FAIL: The instance is stopped/shutting-down/terminated.
    """

    def execute(self) -> list[Check_Report_AWS]:
        """Execute the Nitro Enclave parent state check.

        Iterates over every enclave-enabled EC2 instance (including terminal
        states, unlike the shared ``is_enclave_parent`` helper) and reports
        whether the instance is still in a running lifecycle state.

        Returns:
            list[Check_Report_AWS]: One report per enclave-enabled instance.
        """
        findings = []
        for instance in ec2_client.instances:
            if not instance.enclaves_enabled:
                continue

            report = Check_Report_AWS(metadata=self.metadata(), resource=instance)
            if instance.state in _TERMINAL_STATES:
                report.status = "FAIL"
                report.status_extended = (
                    f"Nitro Enclave parent instance {instance.id} is in state "
                    f"'{instance.state}'. Enclaves are destroyed when the parent "
                    f"stops; any expectation of enclave availability is violated. "
                    f"{HOST_TRUST_MODEL_BOILERPLATE}"
                )
            elif instance.state in _TRANSIENT_STATES:
                report.status = "PASS"
                report.status_extended = (
                    f"Nitro Enclave parent instance {instance.id} is in transient "
                    f"state '{instance.state}'; re-evaluate after the lifecycle "
                    f"transition settles. {HOST_TRUST_MODEL_BOILERPLATE}"
                )
            else:
                report.status = "PASS"
                report.status_extended = (
                    f"Nitro Enclave parent instance {instance.id} is in state "
                    f"'{instance.state}'. {HOST_TRUST_MODEL_BOILERPLATE}"
                )
            findings.append(report)
        return findings