Beyond PSK: PKI for Fortinet SD-WAN IPsec, Part 3 — Enrollment, Automation, and the Cutover

Where we are

Two posts of groundwork land here. Part 1 made the case for a dedicated external CA with an EST front-end over FortiManager-as-CA, and walked the protocol-level reality of what authmethod signature actually changes versus psk. Part 2 built that CA — root, issuing tier, a role/template scoped to IPsec end entities, an EST endpoint, revocation infrastructure placed where the chicken-and-egg overlay problem can’t reach it — and pushed the trust framework onto the FortiGates via a classic CLI template.

What’s still missing is the only part that actually moves anything: getting a FortiGate that’s never spoken to this PKI from zero to a working certificate, keeping it that way without a human in the loop, and then — the payoff — flipping phase1 from a shared secret to a signature across the estate.

That’s this post, in three movements: solve the bootstrap problem properly, build the monitoring that catches renewal failure before it becomes an outage, and execute the cutover.

Movement 1 — solving the bootstrap problem on purpose

Every post in this series has flagged the same seam: EST’s mutual-TLS re-enrollment is elegant precisely because the device authenticates with a certificate it already holds — which means the first certificate has to come from somewhere else. That somewhere-else is where automation quietly reverts to manual process if you don’t design it as carefully as everything downstream of it.

The wrong shape for this credential is obvious in hindsight but common in practice: one shared est-http-username/est-http-password pair, baked into a device template, valid indefinitely, used by every device in the estate. Look closely at that sentence. Shared. Indefinitely. Every device. That’s a SCEP challenge password — the exact legacy pattern Part 1 spent a section explaining EST exists to retire — wearing an EST costume.

The right shape has three properties, and you can build all three with primitives you already have:

Scoped. A bootstrap credential should be valid for enrolling devices in a specific batch — a site rollout, a hardware refresh, a quarter’s worth of new spokes — not for the estate in perpetuity. In Vault terms, that’s a tightly-scoped token or AppRole tied to a specific issuance role with a deliberately narrow allowed_domains pattern; in AD CS terms, it’s a one-time enrollment agent credential issued per batch, not a standing service account.

Short-lived. Set its expiry to comfortably outlast the rollout window and not one day more. A bootstrap credential that’s still valid six months after the batch it was created for finished enrolling is not a convenience you might need later — it’s an unrevoked standing credential you forgot about, which is precisely the failure mode that makes audits exist.

Single-use where the tooling allows it. If your EST front-end (or the gateway in front of it) can mark a bootstrap credential consumed on first successful enrollment, use that. It turns “did this credential leak” from a question you have to investigate into a non-event — a leaked, already-consumed credential authenticates nothing.

Wire it into zero-touch provisioning, not around it. This is the part that makes the design actually operational rather than just safer-on-paper. FortiManager already has a natural moment to hand a device its bootstrap credential: first contact, when a factory-fresh or re-imaged FortiGate calls home over FGFM and FMG applies its device-level template. That template — generated per batch, or per device, from your provisioning pipeline — carries the scoped, short-lived bootstrap credential alongside the trust-anchor and EST-client config from Part 2’s classic CLI template. The device’s very first action with that config is to call out to the EST endpoint, authenticate with the one-time credential, and receive its actual operating identity. From that moment forward, it never needs the bootstrap credential again — re-enrollment uses the certificate it just received.

That sequencing — bootstrap credential delivered with the EST-client config, consumed immediately, never needed again — is what closes the seam. The device goes from “has nothing” to “self-sufficient, mutual-TLS, auto-renewing” in one operation, and the one shared-secret-shaped moment in the entire lifecycle exists for minutes, not months.

Movement 2 — monitoring renewal before it becomes an outage

A 90-day leaf lifetime (the number Part 2 picked, deliberately short) means every device in the estate is renewing roughly monthly. That’s a lot of renewal events — which sounds like more to monitor, and is actually the opposite: it’s enough volume that “renewal is broken” becomes a statistical signal long before it becomes an emergency.

Track three things, and alert on trend, not just threshold:

  • Days-to-expiry distribution across the fleet. If this looks like a smooth, continuously-replenishing curve — devices renewing in a rolling spread because they enrolled at different times — that’s healthy. If you see a cliff, a cohort of devices all approaching expiry within days of each other, that’s not a future problem to schedule around; it’s a present sign that those devices enrolled in a batch and have been silently failing to renew ever since. The cliff is the alert. Don’t wait for it to arrive.
  • Renewal success/failure rate, per device and in aggregate. A device that fails one renewal attempt and succeeds on retry is unremarkable — transient network blip, EST endpoint mid-restart, whatever. A device that’s failed its last three is telling you something specific is wrong with it, and a fleet-wide uptick in failure rate is telling you something is wrong with the PKI side — capacity, a cert on the EST endpoint itself approaching its own expiry, a CRL publish job that silently stopped.
  • EST endpoint and issuing-CA health, independent of device-side signals. Request latency, error rate, the EST front-end’s own TLS certificate’s days-to-expiry (yes, really — it has one too, and “the thing that issues certificates let its own certificate expire” is a more common failure than it should be), and CRL publish recency. A device-side renewal failure that correlates with a CA-side latency spike isn’t forty separate problems; it’s one problem wearing forty masks.

Wire these into whatever you already use for fleet observability — there’s nothing exotic about the data sources (FortiGate’s own diagnose vpn certificate local list and the EST endpoint’s logs are both perfectly serviceable starting points), the value is entirely in looking at the trend lines on purpose, on a schedule, before the cliff arrives.

Movement 3 — the cutover, diffed against the FMG-as-CA path

Here’s where this series and Jinja Orchestrator Part 3 converge — because at the IPsec phase1 layer, the cutover is the same migration. That post already showed you the rendered diff in full:

# before — psk
set authmethod psk
set peertype any
set psksecret S3cr3t!

# after — certificate
set authmethod signature
set certificate "Edge"
set peertype any

…and the Jinja conditional that drives it, gated on a single project-wide cert_auth flag. None of that changes here. No SD-WAN config changes. No BGP config changes. No routing changes. That property — the cert/PSK choice is invisible to everything else in the overlay’s shape — is exactly as true with an external CA as it is with FMG-as-CA, and it’s the single best piece of news in this whole series: the riskiest-looking part of the migration (rewriting how tunnels authenticate) is, by design, the part that disturbs the least.

What’s genuinely different is everything upstream of that flag flip — and naming the deltas explicitly is more useful than re-deriving a migration that’s already documented:

FMG-as-CA path (Jinja Orchestrator Pt. 3)External CA + EST path (this series)
Trust anchorOne FMG-generated CA certFull chain — root and issuing CA — from Part 2
Cert deliveryPushed by FMG over FGFMPulled by the device via EST, after a scoped bootstrap
RenewalFMG-scheduled or on-demand pushDevice-initiated, mutual-TLS, continuous
RevocationCRL only, FMG-publishedCRL + OCSP, placed for underlay reachability
peertype/user peer filter objectReferences the FMG CAReferences your issuing CA, with subject filters matching the naming convention Part 2 set deliberately
Cert object namingEdge/Hub convention (FMG defaults)Whatever your CA’s subject/SAN policy drives — decide once, apply estate-wide
What FMG actually doesMints and pushes certificatesPushes configuration that points at the PKI (Part 2’s classic CLI template)

Every row in that table is a decision this series made on purpose, in the two posts before this one. None of it is news by the time you reach the flag flip — which is exactly the point. The architecture work front-loads the hard decisions so the mechanical cutover is, genuinely, mechanical.

Sequencing still matters, identically to the FMG-as-CA path. Don’t flip cert_auth until every device in the affected project has successfully enrolled and is holding a valid certificate that chains through the trust anchors you pushed. Verify with diagnose vpn certificate local list and a chain-validation check before the template install that changes phase1 — not after, when the symptom is tunnels that won’t come up and the cause is a cert that was never there. Render offline, diff against the prior render, install via FMG with Install Preview — the same three controls Part 3 of the Jinja series named as the boundary between intent and production, because they’re the right controls regardless of which CA signed the certs on either side of the diff.

Phased rollout has the same shape, and the same trap. If you’re cutting over a large estate in waves rather than in one maintenance window, the Orchestrator’s cert_auth flag is still project-wide — it doesn’t switch per device. The clean approach is still two parallel project files, each driven by its own inventory subset, with spokes moving from one to the other on cutover. Trying to interleave PSK and cert auth within a single project is, as that post put it, more pain than it’s worth — and that judgment doesn’t change just because a different CA signed the certificates on the cert side of the line.

Gotchas

Don’t flip the flag on faith. “The enrollment job said it completed” is not the same statement as “every device in this project is holding a valid certificate that chains to the trust anchors on every other device in this project.” Verify the second statement, explicitly, before the phase1 template install — it’s the difference between a non-event cutover and a 2 a.m. bridge call.

The bootstrap credential’s blast radius is bounded by how disciplined you were in Movement 1. A scoped, short-lived, single-use bootstrap credential that leaks authenticates nothing useful to an attacker. A shared, long-lived one that leaks is a standing compromise of your enrollment process — which, transitively, is a standing compromise of your trust model. This is the one place in the entire series where skipping a step doesn’t degrade gracefully; it silently reintroduces the exact problem the migration exists to solve.

Watch the cliff, not the average. A fleet-wide “average days to renewal: 45 days” can be hiding a cohort that’s three days from a synchronized expiry event. Aggregate statistics are comforting and frequently wrong about the thing that’s about to bite you. Distribution shape is where the actual signal lives.

The out-of-band recovery path is not optional, and it doesn’t get easier with a better PKI. Jinja Orchestrator Part 3 named this for the FMG-as-CA path — a device whose cert has expired can’t reach the thing that would renew it, because the path to that thing is the thing the cert authenticates — and nothing about a more sophisticated CA changes the shape of that trap. If anything, a 90-day lifetime means you’ll exercise this recovery path’s necessity-checking more often (because more devices are mid-renewal at any given moment) even as good monitoring makes you exercise the recovery path itself less. Build it. Test it. Don’t let “we have great monitoring now” talk you out of the parallel management path that monitoring is there to make unnecessary, not to replace.

Closing the series

Three posts ago, the question was “how do I get my SD-WAN estate off PSK.” That’s a one-line answer — authmethod signature — and if that had been the actual hard part, this would have been a much shorter series, and arguably an unnecessary one, because Jinja Orchestrator Part 3 already showed you that one line in full, rendered, diffed, and gotcha’d.

The actual hard part — the part that determines whether what you end up with is a genuine improvement or a more elaborate way of having the same problems — was always the question hiding underneath: who is your CA, and how do certificates get onto devices without a human in the loop forever? That’s a PKI question. It doesn’t get easier because a FortiGate is involved, and it doesn’t go away because you picked a vendor feature that promises to make it go away. It gets answered, properly, by separating root from issuing, by choosing a protocol (EST) that was designed to eliminate the shared-secret problem rather than relocate it, by placing revocation infrastructure where the system’s own chicken-and-egg dependency can’t reach it, by treating certificate lifetime as a feature of automation rather than a cost to be minimized — and by being honest, in the one place it’s tempting not to be, about the one bootstrap moment where a human still has to start the chain.

Get that foundation right, and the FortiGate-specific part — the part every migration writeup focuses on, the part that looks the scariest from the outside — turns out to be the easiest, most mechanical, least eventful step in the whole project. That’s not an accident, and it’s not a coincidence that it’s also exactly what good architecture is supposed to do: make the risky-looking thing boring, by doing the actual hard thinking somewhere else, first, on purpose.

If your estate is small enough, single-tenant enough, and FMG-centric enough that none of the three posts’ worth of PKI architecture feels like it earns its keep — that’s a legitimate place to land, and Jinja Orchestrator Part 3 is the shorter, complete path to the same authmethod signature destination. This series was for the estate that’s going to outgrow that path — or already has — and wants the foundation under its feet to be the kind that’s still standing in ten years, not the kind that’s due for a rebuild the day the next audit finding arrives.