◇ OpenCyber Academy
Technologist · Chapter 22 · English

Chapter 22 — Quantum and post-quantum security: automation

Open, free learning for anyone who wants to protect people and technology. No account is required to read this text or its worked answers.

Chapter 22 — Quantum and post-quantum security: automation

Lesson map

Lesson 22 published. Map, example, EX043.

flowchart TD
  N0["Learning outcomes"]
  N1["22.1 Inventory and audits in pipelines"]
  N2["22.2 Policy-driven selection"]
  N3["22.3 Practical activity — Lab A"]
  N4["22.4 Regression gates"]
  N5["22.5 Certificate automation"]
  N6["22.7 Automation risks"]
  N7["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7
  N7 --> EX["Worked example"]
  EX --> Q["Exercise EX043"]

Logical drawing

flowchart LR
  N0["Learning outcomes"]
  N1["22.1 Inventory and audits in pipelines"]
  N2["22.2 Policy-driven selection"]
  N3["22.3 Practical activity — Lab A"]
  N4["22.4 Regression gates"]
  N5["22.5 Certificate automation"]
  N6["22.7 Automation risks"]
  N7["Synthesis"]
  N0 --> N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> N7 --> Q["EX043"]
[Learning outcomes]
    |
    v
[22.1 Inventory and audits in pipelines]
    |
    v
[22.2 Policy-driven selection]
    |
    v
[22.3 Practical activity — Lab A]
    |
    v
[22.4 Regression gates]
    |
    v
[22.5 Certificate automation]
    |
    v
[22.7 Automation risks]
    |
    v
[Synthesis]
    |
    v
[Worked example] --> [Exercise EX043]

Learning outcomes

You will (1) automate inventory, configuration audits and negotiation checks in CI/CD; (2) implement policy-driven algorithm selection; (3) prevent regressions with gates; and (4) automate certificate issuance with algorithm awareness.

22.1 Inventory and audits in pipelines

Pipelines already build images and deploy configuration; add steps that extract library versions from images, compare TLS profiles with the approved profile, and update the CBOM. A pull request that changes an ingress profile should show its cryptographic diff, just as it shows a code diff.

KLS's pipeline prints the cryptographic diff as a comment on the pull request: groups added or removed, preference order changes and library versions in the new image. Reviewers approve it the same way as code.

22.2 Policy-driven selection

Applications that sign or encrypt data should look up algorithms from configuration and record identifiers with data, so that migration is a policy change.

KLS's manifest-signing service stores an algorithm identifier with every signature, and the verifier reads which identifiers are acceptable from configuration. When ML-DSA becomes available in the signing library, switching is a policy edit followed by a canary, and old manifests still verify until the classical identifier is retired.

A manifest signed before identifiers were added is checked against a dated list of legacy signatures, not by assuming ECDSA; anything outside that list fails verification and goes to the logistics team for re-signing.

22.3 Practical activity — Lab A

# Lab A (ch 22): crypto-agility through a policy-driven registry instead of hard-coded algorithms.
import hashlib, hmac
REGISTRY = {"hmac-sha256": lambda k, m: hmac.new(k, m, hashlib.sha256).digest(),
            "hmac-sha3-256": lambda k, m: hmac.new(k, m, hashlib.sha3_256).digest()}
POLICY = {"tag-algorithm": "hmac-sha256", "accept": ["hmac-sha256", "hmac-sha3-256"]}
def protect(key, msg):
    alg = POLICY["tag-algorithm"]; return alg, REGISTRY[alg](key, msg)
def check(key, msg, alg, tag):
    if alg not in POLICY["accept"]: return False            # algorithm identifier is authenticated by policy
    return hmac.compare_digest(REGISTRY[alg](key, msg), tag)
k, m = b"k" * 32, b"shipment manifest 42"
a1, t1 = protect(k, m)
POLICY["tag-algorithm"] = "hmac-sha3-256"                   # migration = one policy change
a2, t2 = protect(k, m)
print("old tag still verifies during transition:", check(k, m, a1, t1))
print("new tag verifies:", check(k, m, a2, t2), "| algorithms:", a1, "->", a2)
POLICY["accept"] = ["hmac-sha3-256"]                        # retire the old algorithm
print("old tag after retirement:", check(k, m, a1, t1))

Expected output:

old tag still verifies during transition: True
new tag verifies: True | algorithms: hmac-sha256 -> hmac-sha3-256
old tag after retirement: False

The lab models the three phases of an algorithm migration. In transition, the policy produces new tags with HMAC-SHA3-256 while the accept list still contains HMAC-SHA256, so the old tag verifies and nothing breaks. After retirement, the old identifier is removed from the accept list, and the same valid old tag now fails. The algorithm identifier travels with the tag, but the verifier never trusts it on its own: it must also be on the policy's accept list, which is what stops an attacker relabelling a tag to choose a weaker algorithm. The same structure carries over to signatures when ML-DSA replaces ECDSA.

22.4 Regression gates

Gates fail a deployment if: a tier-1 listener's profile lacks the hybrid group or does not prefer it; a base image's TLS library is older than the approved minimum; a new dependency introduces a hard-coded classical algorithm where policy requires agility. Every gate needs an exception path with an owner and expiry.

KLS's exceptions are YAML entries in the gate's repository: listener, reason, owner and expiry date. The gate reads them, passes the listed listener with a warning, and fails again automatically when the expiry passes. That keeps exceptions visible and stops them from becoming silent permanent bypasses.

22.5 Certificate automation

ACME (RFC 8555) and internal issuance APIs automate certificate renewal. Make the requested key and signature algorithms explicit parameters, so that switching internal leaves to ML-DSA is a change of template, not of scripts. Test renewal of a post-quantum certificate in staging before relying on it.

KLS's internal issuance template already names ecdsa-p256 as an explicit parameter; the ML-DSA pilot uses the same template with ml-dsa-44. The staging test checks that renewal produces a valid chain and that every relying party accepts it before the template changes in production.

22.6 Worked example

KLS adds a CI job, crypto-gate, that parses rendered Kubernetes manifests, extracts ingress TLS groups, and fails if a tier-1 ingress lacks X25519MLKEM768 first. In its first week it blocks two releases that copied an old annotation; both are fixed in minutes rather than discovered weeks later by monitoring.

Both blocked releases had copied an annotation from an old service template. The fix was to correct the template as well as the two services, so the gate stopped the pattern at its source. The gate runs in under a minute and has a documented exception path.

22.7 Automation risks

Automation multiplies mistakes as efficiently as it multiplies fixes. Protect pipeline configuration with review, sign pipeline definitions where tooling allows, and stage changes to central profiles through the same canary process as code. A wrong profile pushed automatically to every ingress is a large outage; the same profile pushed to one canary ingress is a small, informative one.

KLS learned this in staging: a profile change merged without the canary stage removed X25519 from every staging ingress at once, breaking the Java test client across all services. Now profile changes reach one canary ingress first, and the pipeline definitions are reviewed by two people.

22.8 Common errors and limits

Each error turns automation against the team. A gate with no exception path gets disabled the first time it blocks an urgent release; KLS's exception file exists so that never happens. Issuance scripts with an algorithm hard-coded in a string would have to be rewritten for ML-DSA instead of changing a template. And a profile pushed to every ingress at once turns a small mistake into a platform-wide outage, as the staging incident showed.

Exercises

Synthesis

Automation embeds inventory, audits, policy-driven selection and regression gates in the delivery pipeline, with exception paths and staged rollout of central changes.

Continue studying — chapter 22 of 30

← Chapter 21 (draft) · Course chapter index · Chapter 23 (draft) →