
Quantum-resistant signing on AWS, Part 1: Build a software supply chain with ML-DSA
Part 1 of an AWS series showing how to build a quantum-resistant software supply chain with ML-DSA: ML-DSA keys in AWS KMS, an ML-DSA root/subordinate CA hierarchy in AWS Private CA, and IAM Roles Anywhere trust anchors for external build agents. It covers signing binaries (EXTERNAL_MU with OpenSSL 3.5), container images as OCI referrers via ORAS, and SBOMs wrapped in in-toto Statements bound to the artifact digest, plus verification, admission control, trust-store distribution, revocation and SCP guardrails. It frames the "forge later" threat and maps CNSA 2.0 (ML-DSA-87 only for NSS) and EU CRA deadlines to actions.
What it is
An AWS Security Blog walkthrough (Part 1 of 2) for building an ML-DSA (FIPS 204) signing pipeline on AWS KMS, AWS Private CA and IAM Roles Anywhere. Part 2 covers SCP/IAM algorithm-policy enforcement. The page's motivating threat is "forge later": signatures recorded today can be forged once a cryptographically relevant quantum computer exists. Its example is ECDSA P-256 firmware on devices that can't be recalled to re-sign.
How it works
- CA hierarchy: the root CA is ML-DSA-87 and the subordinate CA is ML-DSA-65. Private CA generates the CA keys internally, so no KMS key is needed for them.
- Signing key and CSR: the code-signing key lives in KMS. Because the private key can't leave the HSM, you can't build the CSR with OpenSSL. You assemble the TBS structure yourself and sign it with
aws kms sign. There is no CLI-only path. The page points to the Java/Maven samplediy-code-signing-kms-private-ca. - Binaries: KMS caps a RAW message at 4,096 bytes. Make
EXTERNAL_MUthe default: compute the 64-byte mu with OpenSSL 3.5 and send only that to KMS. Use RAW only for fixed-size inputs, such as the 71-character image manifest digest. Both methods yield standard ML-DSA signatures, and the verifier can't tell them apart. - Container images: the signature is stored as an OCI referrer (ORAS, ECR), and the admission controller fetches and verifies it.
- SBOMs: a signed SBOM alone doesn't say which artifact it describes, and a referrer's
subjectfield is set by whoever pushes it, so it isn't a cryptographic binding. The fix is to wrap the SBOM in an in-toto Statement whose subject is the artifact digest, then sign the Statement. The verifier must take the comparison digest from the artifact itself (registry orsha256sum), never from the Statement. - Build agents outside AWS: IAM Roles Anywhere uses an ML-DSA certificate chained to the Private CA. The trust policy is limited to your trust anchor and to a specific certificate subject CN. Agents on AWS use SigV4 (HMAC-SHA256), which the page treats as already quantum-resistant.
flowchart TD
A[Root CA ML-DSA-87] --> B[Subordinate CA ML-DSA-65]
B --> C[Code-signing cert bound to KMS key]
B --> D[Build-agent cert]
D --> E[Roles Anywhere trust anchor]
E --> F[STS creds: kms:Sign on one key]
F --> G[Sign binary / image / SBOM Statement]
C --> H[Verifier: chain + pinned subject + signature]
G --> HPreconditions / Affected
aws_signing_helperv1.8.0 or later (first release with ML-DSA support).- OpenSSL 3.5 or later (needed for verification and mu computation).
- ORAS CLI v1.2 or later, or Notation with a custom plugin.
jq, and Java 11 or later with Maven.- Sbomgen (Linux only) or another CycloneDX tool.
- Regions: Private CA and Roles Anywhere support ML-DSA in commercial, GovCloud (US) and China Regions. KMS supports it in commercial Regions only, so GovCloud and China teams can't use the KMS key path as written.
What to do
- Parameter set: use ML-DSA-87 everywhere if you fall under CNSA 2.0. It permits only ML-DSA-87 for NSS, so the post's ML-DSA-65 examples are not NSS-compliant. Substitute it in all signing keys and certificates.
- Trust store: distribute the root CA certificate to every verifier (a private root is in no default store), and restrict and audit writes to it.
- Verification: run the chain check, then pin the expected signer subject, then verify the signature. A chain check alone accepts every cert the hierarchy issued, including build-agent client certs. Check exit codes or use
set -e. - Referrers: check all referrers of the type and accept if any one verifies, since re-signing produces several. Taking only the first can reject a good image but never accepts an unsigned one.
- Admission control: no off-the-shelf tool verifies this custom ML-DSA referrer type, so you must write the verification as a webhook or a Gatekeeper external data provider.
- Guardrail: an SCP blocks creating new RSA/ECDSA signing keys. It constrains the algorithm family, not the parameter set, so it still permits ML-DSA-44. Part 2 closes that with
kms:KeySpec. - Storage: protect artifacts and signatures with S3 Object Lock, or at minimum Versioning with restricted writes.
- Audit: use an organization CloudTrail trail with Athena. Event History keeps only 90 days.
Caveats
- Revocation: the walkthrough CAs have no CRL or OCSP configured, and the verify commands skip revocation. For production, configure CRL or OCSP (both work with ML-DSA CAs) and add
-crl_check -CRLfile <crl-file>. - Certificate lifetime: the example end-entity cert is valid 365 days, within a subordinate CA valid 1,825 days. For longer verifiability, use multi-year validity (for example 1095 days), RFC 3161 timestamping, or re-signing. AWS has no managed TSA.
- Signature size: ML-DSA-65 signatures are 3,309 bytes against 64 for ECDSA P-256. This is negligible for images but matters on low-bandwidth embedded links.
- Demo shortcuts: the build-agent private key is a plaintext file. In production use a TPM, HSM or PKCS#11. Reusing one subordinate CA for both code signing and workload identity is also a demo shortcut. Use separate CAs in production to limit blast radius.
- TLS: the TLS connection still authenticates AWS endpoints with classical certificates, which the page treats as out of scope.
- Compliance: the regulatory table is not legal advice. The page also claims to be the first end-to-end cloud-provider guide, which is a vendor claim.
- Out of scope: LMS and XMSS, which CNSA 2.0 also approves for software and firmware signing, are not covered.
Organisations named here
- CNSA 2.0
- EU Cyber Resilience Act
- harvest now, forge later
- in-toto
- ML-DSA
- NIST FIPS 204
- OCI referrers
- RFC 3161
- RSA
Technologies named here
- AWS Key Management Service
- AWS Identity and Access Management Roles Anywhere
- AWS SigV4 on-AWS build agents
- IAM Roles Anywhere credential helper v1.8.0 or later
- OpenSSL 3.5 or later
- ORAS CLI v1.2 or later
- jq
- Amazon Inspector SBOM Generator
- diy-code-signing-kms-private-ca sample
- in-toto Statement
- Amazon S3 and Amazon ECR
- AWS CloudTrail and Amazon Athena
- AWS Organizations Service Control Policies
- AWS
- AWS KMS
- AWS IAM Roles Anywhere
- openssl
- SBOM
- ECDSA
- 5G Standalone and Non-Standalone mobile networks
- AWS Private CA
Techniques named here
- Harvest now, forge later
- SBOM swap attack
- Remote CSR construction
Related in Supply Chain


