Rotate the AD FS signing key
Publish a second key, verify corporate sign-in, switch signing and retain a rollback path.
1. Agree the window and scope
The AD FS administrator works with the BusinessProxy administrator. Token-Signing belongs to the whole AD FS issuer: switching it affects other OIDC and SAML applications in the farm. Confirm partner readiness and retain independent administrator access.
- This sequence is qualified for standard AD FS managed certificates on Windows Server 2019, farm behavior 4. Use your CA or HSM procedure for externally managed certificate issuance and import.
- Check server time, HTTPS discovery and JWKS, employee sign-in and access to an allowed application. Signing-key rotation does not require changing client IDs, client secrets, callbacks, groups or user links.
- Prepare and verify server-side rollback before switching. A controlled rehearsal can use a temporary SYSTEM restore task; remove it after successful completion. A check running only on the operator computer does not cover connection loss.
2. Save the initial state
Open an elevated Windows PowerShell on the primary AD FS server. These commands save public certificate thumbprints and the original automatic rollover setting. Retain the checkpoint path and use the same PowerShell session for the following steps. No private-key export is needed.
$before = @(Get-AdfsCertificate -CertificateType 'Token-Signing')
$primary = @($before | Where-Object { $_.IsPrimary })
if ($primary.Count -ne 1) { throw 'Expected one primary signing certificate' }
$OldThumbprint = $primary[0].Certificate.Thumbprint
$OriginalAutoRollover = (Get-AdfsProperties).AutoCertificateRollover
$OldThumbprints = @($before | ForEach-Object { $_.Certificate.Thumbprint })
$Checkpoint = Join-Path $env:USERPROFILE ('adfs-signing-before-' + (Get-Date -Format 'yyyyMMdd-HHmmss') + '.json')
[ordered]@{
primary = $OldThumbprint
thumbprints = $OldThumbprints
auto_rollover = $OriginalAutoRollover
} | ConvertTo-Json | Out-File -FilePath $Checkpoint -Encoding utf8 -NoClobber
$before | Select-Object IsPrimary, @{Name='Thumbprint';Expression={$_.Certificate.Thumbprint}}, @{Name='NotAfter';Expression={$_.Certificate.NotAfter}}3. Generate a secondary certificate
For the standard automatic profile, use the normal Update-AdfsCertificate command. The old certificate must remain primary and the new one must appear as secondary. Stop and reconcile the checkpoint if the state differs.
if (-not $OriginalAutoRollover) { throw 'Use the procedure for your manually managed certificates' }
Update-AdfsCertificate -CertificateType 'Token-Signing'
$after = @(Get-AdfsCertificate -CertificateType 'Token-Signing')
$new = @($after | Where-Object { $_.Certificate.Thumbprint -notin $OldThumbprints })
if ($new.Count -ne 1 -or $new[0].IsPrimary) { throw 'Inspect the certificate state before continuing' }
$NewThumbprint = $new[0].Certificate.Thumbprint- Do not use -Urgent for a planned rehearsal: urgent rollover removes older certificates immediately and removes the overlap period.
4. Verify both public keys
Use your HTTPS issuer. Obtain the JWKS URL from discovery and match published certificates to the saved thumbprints. Run the BusinessProxy connection test and an employee sign-in. All AD FS partners must consume the new public key before switching.
$Issuer = 'https://adfs.example.com/adfs'
$discovery = Invoke-RestMethod ($Issuer + '/.well-known/openid-configuration')
$jwks = Invoke-RestMethod $discovery.jwks_uri
$jwks.keys | ForEach-Object {
$certificate = [Security.Cryptography.X509Certificates.X509Certificate2]::new([Convert]::FromBase64String($_.x5c[0]))
try { [pscustomobject]@{ kid = $_.kid; thumbprint = $certificate.Thumbprint } }
finally { $certificate.Dispose() }
}- The Test action checks discovery/JWKS availability. It does not replace real sign-in, group checks and opening an application.
5. Switch signing in the agreed window
Normal automatic rollover promotes the certificate according to the AD FS policy. Use these commands for an agreed manual switch or controlled rehearsal after checking publication. They temporarily disable automatic rollover; restore its original value after verification or during rollback.
Set-AdfsProperties -AutoCertificateRollover $false
Set-AdfsCertificate -CertificateType 'Token-Signing' -Thumbprint $NewThumbprint -IsPrimary
Get-AdfsCertificate -CertificateType 'Token-Signing' | Select-Object IsPrimary, @{Name='Thumbprint';Expression={$_.Certificate.Thumbprint}}6. Verify new sign-in and permissions
Use a new browser context to verify a new sign-in rather than an existing session. BusinessProxy selects the kid from current JWKS and validates the signature, issuer, audience, nonce and token lifetime.
- An employee in an allowed group signs in as an ordinary member and opens the assigned application. Rotation must not assign an administrator role.
- Check the selected modes: account creation at first sign-in (JIT) and sign-in from an imported directory. The old key remains valid for unexpired tokens during publication overlap.
- After successful verification restore the original setting: Set-AdfsProperties -AutoCertificateRollover $OriginalAutoRollover. Remove a temporary rollback task only after accepting the new primary certificate.
- AD FS key rotation does not revoke existing BusinessProxy sessions. Revoke the relevant sessions or apply employee offboarding through the directory to terminate access.
7. Restore the previous primary on failure
If new sign-in fails, use the saved old certificate thumbprint. Verify real sign-in and the original AutoCertificateRollover value afterwards. Do not automatically delete the new secondary key: issued tokens may still use it. A rehearsal may remove its own test key after completing verification.
Set-AdfsProperties -AutoCertificateRollover $false
Set-AdfsCertificate -CertificateType 'Token-Signing' -Thumbprint $OldThumbprint -IsPrimary
Set-AdfsProperties -AutoCertificateRollover $OriginalAutoRollover8. Retire the old key after overlap
The overlap window depends on token lifetimes, metadata/JWKS refresh by all partners and your organization policy. Confirm the retiring certificate is no longer primary. After removal, a new validation must reject tokens carrying its kid. Retain the verification record and initial checkpoint.
$current = @(Get-AdfsCertificate -CertificateType 'Token-Signing' | Where-Object { $_.IsPrimary })
if ($current.Count -ne 1 -or $current[0].Certificate.Thumbprint -eq $OldThumbprint) {
throw 'Do not remove the primary certificate'
}
# Run only after the agreed overlap period and partner checks.
$RetirementAutoRollover = (Get-AdfsProperties).AutoCertificateRollover
try {
Set-AdfsProperties -AutoCertificateRollover $false
Remove-AdfsCertificate -CertificateType 'Token-Signing' -Thumbprint $OldThumbprint
} finally {
Set-AdfsProperties -AutoCertificateRollover $RetirementAutoRollover
}