Back to Checks
aws

API Gateway custom domain names use a post-quantum TLS security policy

apigateway_domain_name_pqc_tls_enabled
Service: apigatewaySeverity: low
OfficialBuilt-inVerified
Categories:encryption
Resource Type:AwsApiGatewayDomainName

API Gateway custom domain names for REST APIs are assessed for use of a post-quantum (PQ) TLS security policy such as SecurityPolicy_TLS13_1_2_PQ_2025_09. Custom domains with legacy policies such as TLS_1_0 or TLS_1_2 lack hybrid ML-KEM key exchange, leaving captured traffic vulnerable to future quantum decryption.

Risk

Without a PQ-ready TLS policy, traffic to API Gateway custom domains captured today can be decrypted once a cryptographically relevant quantum computer exists (harvest-now, decrypt-later attack). This threatens long-term confidentiality of API payloads, credentials, and bearer tokens.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler aws --checks apigateway_domain_name_pqc_tls_enabled

Recommendation

Migrate every API Gateway custom domain name to an enhanced post-quantum TLS policy such as SecurityPolicy_TLS13_1_2_PQ_2025_09 that enables hybrid ML-KEM key exchange. Note that you must also enable Strict endpoint access mode and that mutual TLS is not supported on enhanced policies. Review allowed policies regularly as AWS publishes new PQ-ready options.

Remediation

CLI

aws apigateway update-domain-name --domain-name <domain_name> --patch-operations op=replace,path=/securityPolicy,value=SecurityPolicy_TLS13_1_2_PQ_2025_09

Terraform

resource "aws_api_gateway_domain_name" "<example_resource_name>" {
  domain_name              = "api.example.com"
  regional_certificate_arn = "<example_certificate_arn>"
  security_policy          = "SecurityPolicy_TLS13_1_2_PQ_2025_09" # FIX: enhanced post-quantum security policy
  endpoint_configuration {
    types = ["REGIONAL"]
  }
}

NativeIaC

Resources:
  <example_resource_name>:
    Type: AWS::ApiGateway::DomainName
    Properties:
      DomainName: api.example.com
      RegionalCertificateArn: <example_certificate_arn>
      SecurityPolicy: SecurityPolicy_TLS13_1_2_PQ_2025_09  # FIX: enhanced post-quantum security policy
      EndpointConfiguration:
        Types:
          - REGIONAL

Other

1In the AWS Console, go to API Gateway > Custom domain names
2Select the custom domain and choose Edit on Domain name configurations
3Set Security policy to SecurityPolicy_TLS13_1_2_PQ_2025_09 (post-quantum) and Endpoint access mode to Strict
4Save the changes

Check Code

from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.apigateway.apigateway_client import (
    apigateway_client,
)

PQC_APIGATEWAY_POLICIES_DEFAULT = [
    "SecurityPolicy_TLS13_1_2_FIPS_PFS_PQ_2025_09",
    "SecurityPolicy_TLS13_1_2_PFS_PQ_2025_09",
    "SecurityPolicy_TLS13_1_2_PQ_2025_09",
]


def _get_allowed_policies(configured_policies: object) -> list[str]:
    if not isinstance(configured_policies, list):
        return PQC_APIGATEWAY_POLICIES_DEFAULT

    return configured_policies


class apigateway_domain_name_pqc_tls_enabled(Check):
    """Verify that every API Gateway custom domain name uses a post-quantum TLS policy.

    A custom domain name PASSES when its ``securityPolicy`` belongs to the
    configured allowlist of enhanced post-quantum policies.
    """

    def execute(self) -> list[Check_Report_AWS]:
        """Execute the API Gateway custom domain post-quantum TLS check.

        Returns:
            A list of reports for API Gateway custom domain names and their
            post-quantum TLS policy compliance status.
        """
        findings = []
        pqc_policies = _get_allowed_policies(
            apigateway_client.audit_config.get("apigateway_pqc_tls_allowed_policies")
        )
        for domain in apigateway_client.domain_names:
            report = Check_Report_AWS(metadata=self.metadata(), resource=domain)
            policy = domain.security_policy or "<none>"
            if domain.security_policy in pqc_policies:
                report.status = "PASS"
                report.status_extended = (
                    f"API Gateway custom domain {domain.name} uses post-quantum "
                    f"TLS policy {policy}."
                )
            else:
                report.status = "FAIL"
                report.status_extended = (
                    f"API Gateway custom domain {domain.name} uses TLS policy "
                    f"{policy}, which is not in the post-quantum allowlist."
                )
            findings.append(report)

        return findings