Skip to content

chore(elbv2): add post-quantum cryptography SSL policies#36297

Merged
mergify[bot] merged 44 commits intoaws:mainfrom
pahud:fix-36283
Mar 19, 2026
Merged

chore(elbv2): add post-quantum cryptography SSL policies#36297
mergify[bot] merged 44 commits intoaws:mainfrom
pahud:fix-36283

Conversation

@pahud
Copy link
Copy Markdown
Contributor

@pahud pahud commented Dec 4, 2025

Issue # (if applicable)

Closes #36283.

Reason for this change

AWS supports post-quantum (PQ) security policies for ALB and NLB using hybrid ML-KEM key exchange. The CDK's SslPolicy enum lacks these policies, and the AWS Console already defaults to PQ policies while CDK still uses ELBSecurityPolicy-2016-08.

Description of changes

  1. Added 11 post-quantum security policy enum values to SslPolicy:

    Standard TLS Policies with PQ:

    • TLS13_13_PQ, TLS13_12_PQ, TLS13_12_RES_PQ, TLS13_12_EXT1_PQ, TLS13_12_EXT2_PQ, TLS13_10_PQ

    FIPS-Compliant Policies with PQ:

    • FIPS_TLS13_13_PQ, FIPS_TLS13_12_PQ, FIPS_TLS13_12_RES_PQ, FIPS_TLS13_12_EXT0_PQ, FIPS_TLS13_12_EXT1_PQ, FIPS_TLS13_12_EXT2_PQ, FIPS_TLS13_10_PQ

    All enum entries include @see links to the AWS ELB SSL policies documentation.

  2. Added feature flag @aws-cdk/aws-elasticloadbalancingv2:usePostQuantumTlsPolicy:

    • Disabled (default): No change to existing behavior
    • Enabled: HTTPS/TLS listeners automatically use SslPolicy.TLS13_12_PQ (ELBSecurityPolicy-TLS13-1-2-PQ-2025-09)
  3. Updated listener implementations:

    • ALB and NLB listeners check the feature flag at construction time
    • Explicit sslPolicy always overrides the feature flag
    • HTTP/TCP listeners are unaffected

Note for new CDK projects: Projects created with cdk init will have the feature flag @aws-cdk/aws-elasticloadbalancingv2:usePostQuantumTlsPolicy enabled by default. This means HTTPS/TLS listeners without an explicit sslPolicy will use ELBSecurityPolicy-TLS13-1-2-PQ-2025-09 instead of the CloudFormation default (ELBSecurityPolicy-2016-08). Existing projects are unaffected unless they explicitly opt in.

Behavior Summary

Feature Flag HTTPS/TLS Listeners (no explicit sslPolicy) Explicit sslPolicy HTTP/TCP Listeners
Disabled (default) CloudFormation default (no explicit policy) Always honored No SSL policy
Enabled ELBSecurityPolicy-TLS13-1-2-PQ-2025-09 Always honored No SSL policy

Description of how you validated changes

  • Unit tests for ALB and NLB listeners covering: flag disabled, flag enabled, explicit override, non-TLS unaffected
  • All policy names verified against AWS documentation

Checklist

- Add 6 new post-quantum hybrid key exchange SSL policies using ML-KEM
* TLS13_13_PQ: TLS 1.3 only with quantum resistance
* TLS13_12_PQ: TLS 1.2 and 1.3 with quantum resistance
* TLS13_12_RES_PQ: Restricted cipher suite with quantum resistance
* TLS13_12_EXT1_PQ: Extended cipher suite 1 with quantum resistance
* TLS13_12_EXT2_PQ: Extended cipher suite 2 with quantum resistance
* TLS13_10_PQ: TLS 1.0 through 1.3 with quantum resistance
- Add 8 new FIPS-compliant post-quantum cryptography SSL policies
* FIPS_TLS13_13_PQ: FIPS TLS 1.3 only with quantum resistance
* FIPS_TLS13_12_PQ: FIPS TLS 1.2 and 1.3 with quantum resistance
* FIPS_TLS13_12_RES_PQ: FIPS restricted cipher suite with quantum resistance
* FIPS_TLS13_12_EXT0_PQ: FIPS extended cipher suite 0 with quantum resistance
* FIPS_TLS13_12_EXT1_PQ: FIPS extended cipher suite 1 with quantum resistance
* FIPS_TLS13_12_EXT2_PQ: FIPS extended cipher suite 2 with quantum resistance
* FIPS_TLS13_11_PQ: FIPS TLS 1.1 through 1.3 with quantum resistance
* FIPS_TLS13_10_PQ: FIPS TLS 1.0 through 1.3 with quantum resistance
- Support AWS recommended post-quantum cryptography policies for enhanced security
@aws-cdk-automation aws-cdk-automation requested a review from a team December 4, 2025 18:11
@github-actions github-actions bot added feature-request A feature should be added or improved. p2 labels Dec 4, 2025
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Dec 4, 2025
Copy link
Copy Markdown
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This review is outdated)

@pahud pahud changed the title feat(elbv2): add post-quantum cryptography SSL policies chore(elbv2): add post-quantum cryptography SSL policies Dec 4, 2025
@pahud pahud marked this pull request as ready for review December 4, 2025 18:16
@aws-cdk-automation aws-cdk-automation dismissed their stale review December 4, 2025 18:16

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@aws-cdk-automation aws-cdk-automation added the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Dec 4, 2025
@alexw91
Copy link
Copy Markdown

alexw91 commented Dec 9, 2025

Can you also update RECOMMENDED_TLS to ELBSecurityPolicy-TLS13-1-2-PQ-2025-09? It is purely additive, and I'd love to see the default recommended policy be post-quantum secure as well!

@pahud
Copy link
Copy Markdown
Contributor Author

pahud commented Dec 9, 2025

Can you also update RECOMMENDED_TLS to ELBSecurityPolicy-TLS13-1-2-PQ-2025-09? It is purely additive, and I'd love to see the default recommended policy be post-quantum secure as well!

Sure I will look into this and update this PR.

@pahud
Copy link
Copy Markdown
Contributor Author

pahud commented Dec 10, 2025

Can you also update RECOMMENDED_TLS to ELBSecurityPolicy-TLS13-1-2-PQ-2025-09? It is purely additive, and I'd love to see the default recommended policy be post-quantum secure as well!

AWS recommends implementing the new post-quantum TLS (PQ-TLS) based security policy  ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 or ELBSecurityPolicy-TLS13-1-2-FIPS-PQ-2025-09.
Console – The default security policy is ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09
Other methods (for example, the AWS CLI, AWS CloudFormation, and the AWS CDK) – The default security policy is ELBSecurityPolicy-2016-08.

https://docs.aws.amazon.com/elasticloadbalancing/latest/application/describe-ssl-policies.html

Method Current Default SSL Policy Post-Quantum? Year
AWS Console ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 ✅ Yes 2025
AWS CLI ELBSecurityPolicy-2016-08 ❌ No 2016
CloudFormation ELBSecurityPolicy-2016-08 ❌ No 2016
CDK RECOMMENDED_TLS ELBSecurityPolicy-TLS13-1-2-2021-06 ❌ No 2021
CloudFormation Examples ELBSecurityPolicy-TLS13-1-2-2021-06 ❌ No 2021
AWS Recommendation ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 ✅ Yes 2025

Key Discrepancy: The AWS Console already defaults to post-quantum security, but all programmatic methods (CLI, CloudFormation, CDK) still use older, non-post-quantum policies. This creates an inconsistent experience where Console users get better security by default than infrastructure-as-code users.

I am on board to make CDK default to ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 but changing the RECOMMENDED_TLS would cause breaking change which is subject to resource replacement with disruptions.

We have two options here to move this path forward:

Option 1: Feature Flag

// Add a new feature flag
RECOMMENDED_TLS_PQ = 'ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09'

// Keep existing for backward compatibility
RECOMMENDED_TLS = 'ELBSecurityPolicy-TLS13-1-2-2021-06'

Users opt-in via CDK feature flags:

// cdk.json
{
  "context": {
    "@aws-cdk/aws-elasticloadbalancingv2:usePostQuantumTlsPolicy": true
  }
}
export enum SslPolicy {
  /**
   * The recommended security policy for TLS listeners.
   *
   * When feature flag @aws-cdk/aws-elasticloadbalancingv2:usePostQuantumTlsPolicy is enabled,
   * this uses ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 (post-quantum).
   * Otherwise uses ELBSecurityPolicy-TLS13-1-2-2021-06 (legacy).
   */
  RECOMMENDED_TLS = // dynamically determined based on feature flag
    FeatureFlags.of(this).isEnabled(ELB_USE_POST_QUANTUM_TLS_POLICY)
      ? 'ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09'
      : 'ELBSecurityPolicy-TLS13-1-2-2021-06',
}

Result:

  • Feature flag disabled (default): SslPolicy.RECOMMENDED_TLS = old policy (no BC)
  • Feature flag enabled: SslPolicy.RECOMMENDED_TLS = post-quantum policy

This way existing code using SslPolicy.RECOMMENDED_TLS gets the new behavior only when users explicitly opt-in via the feature flag.

Option 2: New Enum Value

// Add alongside existing
RECOMMENDED_TLS = 'ELBSecurityPolicy-TLS13-1-2-2021-06'        // unchanged
RECOMMENDED_TLS_PQ = 'ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09'  // new
export enum SslPolicy {
  /**
   * The recommended security policy for TLS listeners.
   * This policy includes TLS 1.3, and is backwards compatible with TLS 1.2
   */
  RECOMMENDED_TLS = 'ELBSecurityPolicy-TLS13-1-2-2021-06',  // UNCHANGED

  /**
   * The recommended post-quantum security policy for TLS listeners.
   * AWS recommended policy for post-quantum cryptography.
   */
  RECOMMENDED_TLS_PQ = 'ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09',  // NEW
}

Behavior:

  • No breaking change: Existing code using SslPolicy.RECOMMENDED_TLS continues working exactly as before
  • Opt-in upgrade: Users who want post-quantum security can explicitly use SslPolicy.RECOMMENDED_TLS_PQ
  • Clear intent: The naming makes it obvious which one provides post-quantum protection

Personally, if the console now defaults to TLS_PQ, I don't see any reason CDK should not by introducing a FF. Let me know if there's any other concerns.

@alexw91
Copy link
Copy Markdown

alexw91 commented Dec 10, 2025

I'm in favor of Option 1: Feature Flag. I believe that eventually we will want to set it to true by default for everyone, but this allows customers interested in being early adopters to enable it for themselves early.

- Add integration test for post-quantum cryptography TLS policies on ALB and NLB
- Add feature flag test case with disabled post-quantum TLS policy behavior
- Add snapshot files for post-quantum TLS policy integration test stack
- Update ALB application listener to support post-quantum TLS policies
- Update NLB network listener to support post-quantum TLS policies
- Add post-quantum TLS policy enum values to shared enums
- Add feature flag '@aws-cdk/aws-elasticloadbalancingv2:usePostQuantumTlsPolicy' to cx-api
- Update ALB and NLB listener unit tests to cover post-quantum policy scenarios
- Ensures backward compatibility with feature flag disabled by default
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 10, 2025

⚠️ Experimental Feature: This security report is currently in experimental phase. Results may include false positives and the rules are being actively refined.
Please try merge from main to avoid findings unrelated to the PR.


TestsPassed ✅SkippedFailed
Security Guardian Results48 ran48 passed
TestResult
No test annotations available

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Dec 10, 2025

⚠️ Experimental Feature: This security report is currently in experimental phase. Results may include false positives and the rules are being actively refined.
Please try merge from main to avoid findings unrelated to the PR.


TestsPassed ✅SkippedFailed
Security Guardian Results with resolved templates48 ran48 passed
TestResult
No test annotations available

@alexw91
Copy link
Copy Markdown

alexw91 commented Dec 11, 2025

I think the new Post Quantum SslPolicy.RECOMMENDED_TLS policy should be ELBSecurityPolicy-TLS13-1-2-PQ-2025-09 not ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09. The -Res in the name stands for "Restricted", and removes AES-CBC algorithms from the ELB Security Policy.

AWS customers who are currently using the classical version of SslPolicy.RECOMMENDED_TLS (aka ELBSecurityPolicy-TLS13-1-2-2021-06) and have TLS clients negotiating TLS 1.2 with AES-CBC would see their clients break. I think this would most likely be around ~1% of clients.

I know that the AWS Console defaults to ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09 (without AES-CBC), but I think CDK users have additional backwards compatibility requirements with previous CDK versions that users clicking buttons in the AWS console don't have.

I'd feel much more confident in making the new Post Quantum CDK SslPolicy.RECOMMENDED_TLS policy be ELBSecurityPolicy-TLS13-1-2-PQ-2025-09, since it is (nearly) 100% backwards compatible with the previous CDK recommended default. It does remove support for the SHA1 signature algorithm, but SHA1 usage is much smaller than AES-CBC usage.

*/
export function getRecommendedTlsPolicy(scope: Construct): string {
if (FeatureFlags.of(scope).isEnabled(cxapi.ELB_USE_POST_QUANTUM_TLS_POLICY)) {
return SslPolicy.TLS13_12_RES_PQ;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you should add a new RECOMMENDED_TLS_PQ enum to SslPolicy, and then change this line to be return SslPolicy.RECOMMENDED_TLS_PQ

- Add new `RECOMMENDED_TLS_PQ` enum value for post-quantum TLS policy
- Set policy to `ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09` with ML-KEM hybrid key exchange
- Update `getRecommendedTlsPolicy()` to return `RECOMMENDED_TLS_PQ` instead of `TLS13_12_RES_PQ`
- Add comprehensive JSDoc comments explaining post-quantum cryptography support
- Provides AWS-recommended security policy for quantum-resistant TLS connections
@github-actions github-actions bot added the effort/small Small work item – less than a day of effort label Dec 12, 2025
- Update SSL policy name from `ELBSecurityPolicy-TLS13-1-2-Res-PQ-2025-09` to `ELBSecurityPolicy-TLS13-1-2-PQ-2025-09`
- Update ALB listener snapshot with corrected policy name
- Update NLB listener snapshot with corrected policy name
- Update enums.ts to reflect the correct policy identifier
- Add test cases for ALB and NLB listeners with corrected policy
- Update feature flag configuration in cx-api
- Fixes incorrect policy naming that was using "Res" prefix which should not be present in the post-quantum TLS policy identifier
- Remove `getRecommendedTlsPolicy()` helper function and inline feature flag logic directly in listeners
- Update ApplicationListener to calculate SSL policy based on feature flag before calling super()
- Update NetworkListener to calculate SSL policy based on feature flag before calling super()
- Remove test file for feature flag disabled scenario (test-feature-flag-disabled.ts)
- Simplify SSL policy determination by checking `ELB_USE_POST_QUANTUM_TLS_POLICY` feature flag at listener construction time
- This change consolidates TLS policy selection logic and removes unnecessary abstraction layer
@aws-cdk-automation aws-cdk-automation removed the pr/needs-maintainer-review This PR needs a review from a Core Team Member label Mar 5, 2026
Rename RECOMMENDED_TLS_PQ enum to TLS13_12_PQ to follow the same
naming convention as other PQ entries (TLS13_13_PQ, TLS13_12_RES_PQ,
etc.) per reviewer feedback. No opinion baked into the enum name -
the feature flag handles the 'recommended' semantics.
@aws-cdk-automation
Copy link
Copy Markdown
Collaborator

➡️ PR build request submitted to test-main-pipeline ⬅️

A maintainer must now check the pipeline and add the pr-linter/cli-integ-tested label once the pipeline succeeds.

@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 18, 2026

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 18, 2026

Merge Queue Status

  • Entered queue2026-03-18 17:03 UTC · Rule: default-squash
  • 🚫 Left the queue2026-03-18 17:50 UTC · at ee2f6b2ee3b7534fe85373deaa8b920bef85ab21

This pull request spent 47 minutes 52 seconds in the queue, with no time running CI.

Reason

The pull request can't be updated

For security reasons, Mergify can't update this pull request. Try updating locally.
GitHub response: refusing to allow a GitHub App to create or update workflow .github/workflows/security-report.yml without workflows permission

Hint

You should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again.
If you think this was a flaky issue, you can requeue the pull request, without updating it, by posting a @mergifyio queue comment.

@gasolima
Copy link
Copy Markdown
Contributor

@Mergifyio refresh

@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 18, 2026

refresh

✅ Pull request refreshed

@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 18, 2026

Merge Queue Status

  • Entered queue2026-03-18 22:36 UTC · Rule: default-squash
  • 🚫 Left the queue2026-03-18 22:36 UTC · at ee2f6b2ee3b7534fe85373deaa8b920bef85ab21

This pull request spent 3 seconds in the queue, with no time running CI.

Reason

The pull request can't be updated

For security reasons, Mergify can't update this pull request. Try updating locally.
GitHub response: refusing to allow a GitHub App to create or update workflow .github/workflows/pr-linter.yml without workflows permission

Hint

You should update or rebase your pull request manually. If you do, this pull request will automatically be requeued once the queue conditions match again.
If you think this was a flaky issue, you can requeue the pull request, without updating it, by posting a @mergifyio queue comment.

@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 19, 2026

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 19, 2026

Merge Queue Status

  • Entered queue2026-03-19 11:35 UTC · Rule: default-squash
  • Checks started · in-place · dashboard
  • 🟠 Running checks
  • ⏳ Merge · ETA: 2026-03-19 18:10 UTC 🚀
Required conditions to merge
Required conditions to stay in the queue
  • -closed [📌 queue requirement]
  • -conflict [📌 queue requirement]
  • -draft [📌 queue requirement]
  • any of [📌 queue -> configuration change requirements]:
    • -mergify-configuration-changed
    • check-success = Configuration changed
  • any of [📌 queue requirement]:
    • check-neutral = Mergify Merge Protections
    • check-skipped = Mergify Merge Protections
    • check-success = Mergify Merge Protections
  • any of [🔀 queue conditions]:
    • all of [📌 queue conditions of queue default-squash]:
      • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
      • #approved-reviews-by>=1
      • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
      • #changes-requested-reviews-by=0
      • -approved-reviews-by~=author
      • -closed
      • -label~=(blocked|do-not-merge|no-squash|priority-pr)
      • -merged
      • -title~=(WIP|wip)
      • base!=release
      • check-success=build
      • check-success=validate-pr
      • any of:
        • -label~=pr/needs-integration-tests-deployment
        • check-success=Deploy integration test snapshots (requires pr/needs-integration-tests-deployment label)
      • any of [🛡 GitHub branch protection]:
        • check-success = validate-pr
        • check-neutral = validate-pr
        • check-skipped = validate-pr
      • any of [🛡 GitHub branch protection]:
        • check-success = build
        • check-neutral = build
        • check-skipped = build
    • all of [📌 queue conditions of queue default-merge]:
      • label~=no-squash
      • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
      • #approved-reviews-by>=1
      • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
      • #changes-requested-reviews-by=0
      • -approved-reviews-by~=author
      • -closed
      • -label~=(blocked|do-not-merge)
      • -merged
      • -title~=(WIP|wip)
      • check-success=build
      • check-success=validate-pr
      • any of:
        • -label~=pr/needs-integration-tests-deployment
        • check-success=Deploy integration test snapshots (requires pr/needs-integration-tests-deployment label)
      • any of [🛡 GitHub branch protection]:
        • check-success = validate-pr
        • check-neutral = validate-pr
        • check-skipped = validate-pr
      • any of [🛡 GitHub branch protection]:
        • check-success = build
        • check-neutral = build
        • check-skipped = build
    • all of [📌 queue conditions of queue priority-squash]:
      • label~=priority-pr
      • #approved-reviews-by >= 1 [🛡 GitHub branch protection]
      • #approved-reviews-by>=1
      • #changes-requested-reviews-by = 0 [🛡 GitHub branch protection]
      • #changes-requested-reviews-by=0
      • -approved-reviews-by~=author
      • -closed
      • -label~=(blocked|do-not-merge|no-squash)
      • -merged
      • -title~=(WIP|wip)
      • base!=release
      • check-success=build
      • check-success=validate-pr
      • any of:
        • -label~=pr/needs-integration-tests-deployment
        • check-success=Deploy integration test snapshots (requires pr/needs-integration-tests-deployment label)
      • any of [🛡 GitHub branch protection]:
        • check-success = validate-pr
        • check-neutral = validate-pr
        • check-skipped = validate-pr
      • any of [🛡 GitHub branch protection]:
        • check-success = build
        • check-neutral = build
        • check-skipped = build

@mergify
Copy link
Copy Markdown
Contributor

mergify bot commented Mar 19, 2026

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot merged commit f18a4e2 into aws:main Mar 19, 2026
16 of 18 checks passed
@github-actions
Copy link
Copy Markdown
Contributor

Comments on closed issues and PRs are hard for our team to see.
If you need help, please open a new issue that references this one.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

contribution/core This is a PR that came from AWS. effort/small Small work item – less than a day of effort feature-request A feature should be added or improved. p2 pr/needs-further-review PR requires additional review from our team specialists due to the scope or complexity of changes.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(aws-elasticloadbalancingv2): Please add post-quantum security policies

6 participants