Migration

Shadow ADCS: The Coexistence Pattern That Makes CA Migrations Boring

The riskiest moment of any CA migration is the one where issuance stops. The shadow-issuance pattern removes that moment entirely. For every real cert the old CA issues, the new CA issues an identical shadow. You run them in parallel for weeks, prove parity, then cut over. This is how it works - and why it is the only CA migration pattern worth running in production.

R
Ravi Shankar
Principal PKI Engineer
2026-10-07
11 min read

The Problem With Every Other Migration Pattern

CA migrations fail in one of three ways:

  1. Big-bang cutover. Stand up the new CA, flip DNS, retire the old one. Works for toy environments. Guarantees an outage in production, because something is pinned to the old root, trust-stores aren't updated everywhere, or an enrollment client doesn't recover from a connection drop.

  2. Hard cutover with new root. New CA, new root. Push the new root to every trust store. Reissue every cert as it comes up for renewal. Keep the old CA validating until the last old cert expires. This works for small estates with controlled relying parties - web servers, APIs. It breaks for device fleets, MDMs, and anything that validates the issuer by subject.

  3. Partial coexistence. Both CAs issuing new certs during the migration window. "The team will pick which CA to use for each cert." Everyone's eyes glaze over and nobody picks correctly. Six months later, you have certificates issued from both CAs in production, with no clear plan to retire either one.

The shadow-issuance pattern is the fourth option. Both CAs run; only one is authoritative. The second one proves it is ready to be authoritative, in production, under load, against the real request stream. When you cut over, you have evidence - not hope.

What Shadow Issuance Actually Does

For every real enrollment request that lands at ADCS (or wherever your legacy CA lives), two things happen:

  1. The request is served by the legacy CA, exactly as it would be today. The client gets its cert. Production is unchanged.

  2. The same request is replayed - after the fact, asynchronously - against the new CA. The new CA issues a shadow cert. The shadow cert is never returned to the client. It is dropped into a database table with the real cert alongside it, so a human can diff the two.

That's it. The pattern is almost embarrassingly simple. The value is entirely in what you can do with the diff.

What the Diff Catches

A clean shadow-issuance diff proves the new CA would have issued exactly the same cert the old CA did. A dirty diff tells you which template, which EKU, which SAN rule, which validity policy did not transfer correctly.

Common diffs the pattern catches:

Subject rewrite differences. ADCS templates can have server-side scripts that modify the subject before issuance. Converting those scripts to CEL expressions in the TigerTrust profile is where most "we lost something" bugs live. The shadow diff shows: ADCS issued CN=device-prod-us-east-01.corp.example.com, new CA issued CN=device-prod-us-east-01. Fix the CEL expression; the next shadow issuance matches.

EKU drift. A template was edited in 2019 to add Server Authentication EKU to a client-cert template, and the edit lives only in the template definition. The importer picks up the current state; the shadow diff proves the current state matches real issuance. If someone has a copy of the template with the old EKU set and that is what you imported, the diff catches it.

Validity clamping. The template says 2 years. The CA policy caps at 13 months. ADCS issues 13-month certs; the new CA, with a different policy, issues 2-year certs. Shadow diff flags this before it hits a certificate transparency log.

Key size policy. The template permits RSA-2048 and ECC P-256. The old CA has only ever issued RSA-2048. The new CA, with the same template, starts issuing P-256 (because the client's CSR was P-256 and the new CA actually honoured the template). This may or may not be a problem - but it is a change, and you want to notice it before the first client fails validation.

Autoenroll differences. The ADCS template has autoenrollment on. The new CA profile has it off (because autoenrollment via GPO doesn't apply to the new CA - clients enroll via ACME/EST). Shadow issuance shouldn't trigger from autoenroll alone, but the diff makes the state explicit.

How Long You Run It

The honest answer is: until the diff is boring.

For a template that issues continuously (an auto-enrolled machine template on domain controllers), the first dozen shadow issuances tell you a lot. If they match, run for another dozen. If they still match, you have proven parity for the current configuration.

For a template that issues rarely (quarterly code-signing, annual root subordinate), you can wait a year to see one real issuance. The pragmatic answer: either simulate the issuance with a representative CSR against the new CA and manually diff, or accept that you have less confidence in parity for low-volume templates and plan the cutover with extra scrutiny there.

Typical production shadow runs are 4-8 weeks. That is enough to see every weekly / monthly cycle fire, enough to catch the "we deploy a new region every three weeks and it has its own enrollment pattern" edge case, and short enough that the migration doesn't lose organisational momentum.

What Changes During Shadow Issuance

Nothing on the client side. The whole point.

Nothing on the ADCS side either - ADCS doesn't know shadow issuance exists. The intercept is on the enrollment path (SCEP, NDES, auto-enroll, REST wrapper) or on the audit stream from ADCS. The shadow issuance happens out of band.

On the TigerTrust side: a worker (shadow-adcs) processes a queue of shadow-issuance requests. It issues against the configured profile, records the result, and the console shows the diff table.

When the Diff Is Clean

Clean diff for 4-8 weeks, across every template that has issued at least a dozen times - this is the signal to move to Phase 3 (dual-trust) in the migration. You have evidence that the new CA would have issued the exact same certificates ADCS issued, for every live template in your fleet. You can present this to your change-advisory board. You can present it to your auditor.

When you flip the SCEP profile in Phase 5 (promote), the first real certificate the new CA issues is one it has already issued, as a shadow, dozens of times before.

What Shadow Issuance Doesn't Solve

Three honest caveats:

It doesn't catch client-side pinning. If a client is pinning the issuer DN or the subject key identifier of the old CA, shadow issuance doesn't help - the client is validating something that didn't come from the enrollment flow at all. You find these by walking the trust-store policies of every MDM and every network appliance. The CA rotation wizard's per-appliance trust push surfaces drift.

It doesn't catch low-volume templates. Covered above. The mitigation is manual CSR replay against the new CA plus extra scrutiny on the cutover for those templates.

It doesn't retire templates for you. The ADCS Migration importer surfaces templates that haven't issued in 90 days, and shadow issuance never fires for them because the enrollment stream never fires for them. You still have to decide: keep, retire, or ignore. The pattern just makes the decision data-informed.

Where This Sits in the Full Migration

Shadow issuance is Phase 3 of the ADCS migration pattern:

  1. Discover + inventory
  2. Import templates
  3. Shadow issuance (this post)
  4. Dual-trust push
  5. Promote (cutover)
  6. Retire

Phases 1-2 are prep. Phase 3 is where you prove the new CA is ready. Phase 4 is where the new CA becomes operational (trust pushed, but still shadow-issuing). Phase 5 is the cutover moment - which is boring, because Phase 3 did the hard work. Phase 6 is the long tail of waiting for old certs to expire.

The migration pattern inverts the usual CA-migration risk profile. Instead of a dramatic cutover moment followed by weeks of firefighting, you get weeks of parallel-run followed by a cutover that is a change-window formality.

Related Reading

TOPICS

ADCS migration
shadow issuance
parallel run
CA migration
coexistence pattern
Microsoft ADCS
TigerTrust

SHARE THIS ARTICLE

Ready to Transform Your Certificate Management?

See how TigerTrust can help you automate certificate lifecycle management at scale.