rotate_cert_windows.py¶
Transactional Windows Blueprint certificate rotation with full rollback,
extracted from deploy-windows.ps1 so the rollback contract is testable. Windows
only.
Part of the auth-and-certs command reference.
Purpose¶
Performs an all-or-nothing rotation of the Blueprint certificate: it registers
the new certificate on the Blueprint app, smoke-tests token acquisition, and
either commits (removing the old certificate) or rolls everything back. Other
machines' certificates on the Blueprint are kept in both directions. It is a
module invoked by deploy-windows.ps1, not a
standalone CLI entry point. See
Windows Platform APIs → Two thumbprints, two purposes
and Token flows.
Requirements¶
- Windows, driven by
deploy-windows.ps1. - The wrapper must, before generating the new certificate, capture the old certificate's public DER — for a non-exportable TPM key this is the only chance to grab the old public material for rollback.
- The wrapper supplies: the old DER, the new certificate's SHA-1 thumbprint,
x5t#S256, and public DER (fromgenerate_windows_cert.py), plus callables for the GraphPATCH, the smoke test, deletion of the old certificate, and a Graph token provider, together with the.envpath, MSAL cache path, and Blueprint object ID.
Usage¶
Invoked through the deploy wrapper rather than run directly:
Options¶
Not a CLI. The rotation is driven by the parameters the wrapper passes to the
rotate function.
Effects¶
The rotation runs as an ordered transaction:
- Read the original
x5t#S256and SHA-1 thumbprints from.env. - Acquire a Graph token.
- Swap the new certificate DER into the Blueprint's
keyCredentials, through the wrapper's callable: read the list, drop only the entries whose key material matches the old or new certificate, add the new one, andPATCH. If the read fails, nothing is sent. - Rewrite the
BLUEPRINT_CERT_*lines in.envto the new thumbprints (the single source of truth for the next run). - Run the smoke test (acquire a fresh Agent User token end to end).
- On the outcome:
- Smoke passes → delete the old certificate from
Cert:\CurrentUser\Myby its SHA-1 thumbprint. The old certificate is removed only after the new one is proven to work. - Smoke fails → roll back in order: swap the old DER back onto the
Blueprint, restore the original thumbprints in
.env, and delete the MSAL cache so the next call does not present a token signed by the now-invalid new key.
Exit behavior¶
Outcomes surface as typed errors that the wrapper maps to process exit codes:
- Success — returns without error; the new certificate is live and the old one removed.
RotationFailed— the initial read orPATCHfailed; no rollback was attempted and the old certificate is still in the local store.RotationRolledBack— thePATCHsucceeded but the smoke test failed; the original certificate and.envthumbprints were restored, and the MSAL cache was deleted (not restored) so a fresh cache is built on the next token acquisition.ManualInterventionRequired— the smoke test failed and then the rollback (its read or itsPATCH) failed too;.envand the MSAL cache are deliberately left untouched for manual triage, since the old DER is the only public material matching a working private key.
Security¶
Private keys never leave the certificate store; only public DER is exchanged.
Invalidating the MSAL cache on rollback prevents a stale-signed token from
looping on 401 after the new key is removed.
Common failures¶
- Rollback after smoke failure — expected and safe; the previous certificate is restored automatically.
ManualInterventionRequired— re-PATCHthe old DER manually; do not touch.env/MSAL until the Blueprint is consistent again.
Related commands¶
generate_windows_cert.py— produces the new certificate material this rotation consumes.deploy-windows.ps1— the wrapper that drives this module.setup-windows.ps1— first-time Windows provisioning.