Certificate Authority
FluxDeploy issues certificates for the services it deploys. Some of those certificates are validated by other machines - a Connected Cache node's HTTPS certificate is checked by every Windows client that tries to use the cache - so they must chain to a root those machines already trust.
Rather than configuring an issuer per feature, FluxDeploy has one organization certificate authority, configured once at Settings > Security > Certificates > How they are issued. Every feature that needs a certificate uses it.
Not the same as the server's own HTTPS certificate. The certificate FluxDeploy's web UI serves is configured separately - see HTTPS & Certificates. The organization CA issues certificates to the things FluxDeploy deploys.
What uses it
| Feature | What is issued | Where it goes |
|---|---|---|
| Connected Cache | A server-authentication certificate per cache node, signed from the node's own CSR | The relay's cache container, serving HTTPS on 443 |
Modes
FluxDeploy's own certificate authority (self-signed)
FluxDeploy generates an RSA-4096 root the first time it needs one, stores it encrypted, and signs everything from it. No PKI required.
The trade-off is one manual step you must complete yourself:
Devices ignore the certificate until they trust the root. Until a device trusts it, Windows refuses the connection and falls back to the internet - quietly, with no error. FluxDeploy cannot install the root for you: it stops managing a machine once Windows is running.
- On Settings > Security > Certificates > How they are issued, click Download root certificate (.crt). (The root is generated at this point if it does not exist yet.)
- Distribute it to every device that has to trust it:
- Intune - Devices → Configuration → Trusted certificate profile, upload the
.crt, target the device groups. - Group Policy - Computer Configuration → Windows Settings → Security Settings → Public Key Policies → Trusted Root Certification Authorities → import the
.crt.
- Intune - Devices → Configuration → Trusted certificate profile, upload the
- Confirm on a client with
certlm.msc(Trusted Root Certification Authorities → Certificates → FluxDeploy CA).
Your organization's ACME server (recommended)
Certificates obtained automatically from an ACME server (RFC 8555), aimed at internal CAs - step-ca, EJBCA, Keyfactor, Venafi, HashiCorp Vault PKI - not public ones.
This is the mode that costs you the least. The other two each ask for something: the self-signed root has to be distributed to every client before the cache is usable, and the subordinate ceremony means asking your PKI team to hand a signing authority to a deployment tool. ACME asks for neither - FluxDeploy never holds a signing key at all. It is a client of your CA, like anything else on the network, and an ACME account is a much smaller ask than a subordinate CA.
Select My organization's ACME server and fill in the panel that appears:
| Field | What to enter |
|---|---|
| ACME directory URL | The directory endpoint your CA publishes, as https://. For step-ca this is https://ca.example.com/acme/acme/directory. |
| Certificate names for this server | DNS names for this server's own HTTPS certificate, comma separated. Not IP addresses - ACME names are DNS names, and an IP typed here is rejected at entry rather than failing later as an unexplained validation error. |
| Contact email | Where your CA sends expiry and account notices. Optional for most internal CAs. |
| Certificate authority root (PEM) | The root FluxDeploy should trust when connecting to your CA. An internal ACME endpoint is normally served by a certificate from the internal root, which this server has no reason to trust yet - so this is effectively required unless your CA is publicly trusted. |
| External account binding | Key ID and HMAC key, only if your CA requires it. Most internal CAs do not; the directory advertises externalAccountRequired when it does, and registration fails with that message. The HMAC key is stored encrypted and never shown again - leave the box blank to keep the stored one. |
Then click Test connection. It saves the settings, registers an account with your CA, and reports the result. The registered account URL appears underneath once it succeeds. Do this before relying on the mode: until an account exists, every certificate request fails.
Enabling ACME covers both of the things FluxDeploy needs certificates for:
- Connected Cache nodes. Each node's CSR is ordered from your CA and the issued certificate handed back to the node. Because your root is already deployed across the estate, clients trust the cache immediately - nothing to distribute.
- This server's own HTTPS certificate, for the names you listed. FluxDeploy stages the new certificate and cuts over only once every live relay has acknowledged the new thumbprint - relays pin this server's certificate, so an unannounced swap would cut them off. Leave the names field pointing at this server's real DNS name; see HTTPS & Certificates for the rotation detail.
Two constraints are worth knowing before you choose this mode:
- Validation needs port 80 reachable. ACME's
http-01challenge works by the CA connecting to the thing being named on port 80. FluxDeploy ships with no HTTP port bound (Https.HttpPortis0) and opens the port only for the moments an order is in flight, closing it again afterwards. For a cache node the node's own port 80 is borrowed the same way, since the cache software owns 80 and 443 on that host. Your CA must be able to reach the name or address being validated - a CA that cannot is the most common failure, and Test connection says so plainly. - ACME issues end-entity certificates only. What comes back is your CA's profile decision, not the requester's: every ACME implementation issues a leaf by default, so this mode cannot produce a signing CA for FluxDeploy to sign from. That is not a limitation here - in this mode nothing is signed locally. If you specifically want FluxDeploy to hold a signing CA, use the subordinate ceremony above.
The last failure is kept on the tab, with its timestamp. Issuance and renewal both run in the background, so without it the only record of a rejected order would be the server log.
Certificate rotation
Below the ACME server panel, Certificate rotation shows where this server's own HTTPS certificate is in the publish → acknowledge → cut over handshake, and gives you the controls for the cases where the automatic path needs a hand.
| What it shows | Meaning |
|---|---|
| In use now | The SHA-256 thumbprint this server is serving, who issued it and when it expires. |
| Staged, not yet served | A certificate that has been obtained and is waiting for the cutover, with its issue and expiry times. Usually empty - that is the resting state between renewals. |
| Relay acknowledgement | How many live relay sites have pre-authorized the staged thumbprint, and the names of any that have not. A site that has not been heard from in seven days is not counted; it cannot acknowledge anything and waiting on it forever would eventually expire the certificate for everyone. |
Why there is a wait at all. Relays pin this server's certificate by thumbprint. Swapping it without warning makes every relay's TLS handshake fail, and a relay that cannot validate Core stops syncing until someone edits
CoreCertThumbprintin itsrelay.jsonby hand. So FluxDeploy publishes the new thumbprint first, waits for every live relay to echo it back, and only then serves it.
Three controls:
- Request a certificate now. Places an order with your CA immediately. The result is staged, not served - the cutover is still the separate decision below. Disabled while something is already staged; discard that first. Use it after fixing a configuration problem, rather than waiting for the next renewal to try again.
- Activate staged certificate now. Brings the cutover forward. If every live relay has acknowledged, this is simply "do it now instead of on the next pass". If some have not, activating strands them - the confirmation names exactly which sites, and each one stops syncing the moment this server serves the new certificate, until its
relay.jsonis updated by hand. If those relays are just switched off, wait: FluxDeploy cuts over on its own as soon as they answer, and forces it anyway shortly before the current certificate expires. - Discard staged certificate. Throws the staged certificate away and stops relays being told to expect it. Nothing in service changes and the next renewal orders a fresh one. Use it when a certificate was issued for the wrong names.
If a cutover was forced and relays were left behind
A forced cutover - automatic, shortly before the old certificate expires, or an administrator pressing Activate staged certificate now over unacknowledged sites - leaves every relay that had not acknowledged pinning a certificate this server no longer serves. Those relays cannot reach this server at all: no heartbeat, no sync, no cache-node certificate renewal. A relay deliberately does not adopt a certificate it was never told about, so nothing heals this on its own. FluxDeploy does four things instead:
- It holds the new certificate in service for as long as it safely can while any of those relays is still silent, rather than renewing again on schedule - so the thumbprint you are copying into their
relay.jsonfiles does not change under you. The hold ends only at the last moment a renewal and the healthy relays' acknowledgement still fit before expiry; the audit log recordsCORE_CERT_RENEWAL_HELDwhen it begins. - It names them on the Sites page: a red banner lists the stranded sites, the one thumbprint to pin and the exact edit, and each site's Health cell reads not pinning Core's certificate. A site drops off the list on its first heartbeat after you fix it.
- It records
CORE_CERT_CUTOVER_FORCEDin the audit log with the site names and the thumbprint. - It sends the TLS certificate rotated with relays left behind notification (System category) with the same list and the same instruction.
To recover a relay: on that relay, edit relay.json and set Relay.CoreCertThumbprint to the thumbprint shown in the banner. The relay has already written the thumbprint it saw during its failed handshake as ProposedCoreCertThumbprint - confirm the two match before copying, then restart the FluxDeploy relay service. If a cache node's certificate renewal failed while the relay was stranded, the Connected Cache status message says so explicitly ("Core is presenting a certificate this relay has not pinned") rather than blaming port 80 on the relay; it renews on its own once the relay is back.
Resetting the ACME account
The ACME account panel shows the account URL your CA issued and offers Reset ACME account, which forgets the account key and the account URL so the next certificate request registers a new account. Certificates already issued are unaffected.
Reset it when:
- you are pointing FluxDeploy at a different certificate authority;
- your CA has re-issued your external account binding credentials (you will need to enter the new key ID and HMAC key as well);
- certificate requests fail with "the stored ACME account key could not be read". That means the stored key was encrypted by a different machine - the usual cause is a settings backup restored onto a rebuilt server. A settings backup deliberately does not carry ACME key material for exactly this reason, so it should only be seen on a server restored from an older backup file; resetting is the fix.
Subordinate to your enterprise PKI
For organisations that already run a CA (AD Certificate Services, or any PKI whose root is deployed to clients). FluxDeploy holds a CA signed by yours, so everything it issues chains to a root your devices already trust - nothing has to be distributed.
This is a one-time ceremony that covers every certificate FluxDeploy will ever issue, not one per site:
- Select Subordinate to my enterprise PKI and click Save.
- Click Generate CA request. FluxDeploy creates an RSA-4096 key pair - the private key never leaves the Core server - and a PKCS#10 request for
CN=FluxDeploy Issuing CA. - Click Download request (.csr) and sign it with your CA using a subordinate certification authority template. The template must allow the certificate to issue certificates (Basic Constraints
CA=true); a plain server-authentication template will be rejected. - Click Import CA certificate: pick the issued
.crt/.pemor paste the PEM. If your CA is not a root, paste the intermediates and root into the Issuer chain box so FluxDeploy can hand out a complete chain. - The tab then shows the CA's subject, issuer, expiry and SHA-256 thumbprint, and reports Ready.
FluxDeploy validates the import: the certificate must be a CA certificate, and its public key must match the pending request. Signing the wrong request is the usual cause of a key mismatch - regenerate and sign the new one.
If your PKI team generates the CA for you
Some PKI teams will not sign a request whose key they did not create; they mint the subordinate CA themselves and hand it over as a .pfx/.p12. Use Already have a subordinate CA? on the same tab instead of generating a request:
- Upload the
.pfx/.p12and enter its password. (If they gave you separate files, expand Have separate certificate and key files instead? and paste the certificate and private key as PEM.) - Paste the intermediates and root into Issuer chain if their CA is not a root.
- Click Import certificate authority.
The same validation applies, plus two checks that matter for a CA you did not generate:
- It must actually be able to sign. FluxDeploy mints a throwaway certificate with the key before accepting it. A CA that imports cleanly and then fails on the first cache node is worse than no CA at all.
- The key must be exportable. FluxDeploy stores it encrypted so it survives a restart. A key held in an HSM, or marked non-exportable when the
.pfxwas created, is rejected with that reason - ask for an exportable copy.
Whichever route you take, the private key is encrypted at rest and never leaves the Core server.
Which names a certificate can be issued for
A cache node builds its own request on the relay and sends it to Core to be signed, so the names in it arrive from a branch-office machine. FluxDeploy does not take them on trust. Core builds the certificate's names from what it already knows about the requesting site:
- The site's addresses - the address on the site record, its LAN address and any address the relay has reported - are always allowed.
- A DNS name is allowed when it resolves, from Core, to one of those addresses. That is the case the feature exists for: a client reaching the cache by a name that points at the relay.
- A name that points somewhere else is refused, by name, and the request fails immediately rather than leaving the node waiting: another site's host or address, a wildcard, and request entries that are not a server name at all (a URI or an email address).
- A name that does not resolve from Core is left out of the certificate, and the rest of the request proceeds. A bare host name that only resolves inside the branch office is the usual reason; nothing can be steered to a name that resolves nowhere, so there is no need to fail the request - but if clients do reach the cache by that name, give it a DNS record that points at the relay.
- A node whose own name does not resolve asks for nothing. It is then issued for the site's addresses rather than refused, which is the usual case on a workgroup relay.
The refusal is shown on the relay's Connected Cache panel and recorded in the audit log, and the issuance records which names were granted. If a legitimate name is being refused, either correct its DNS record so it points at the relay, or set the site's address on Settings > Relays and let the relay send one heartbeat, then retry. Nothing about the request can widen this - the names are Core's decision, so one relay's API key cannot obtain a certificate for a domain controller or a wildcard.
Until the CA is ready
A CA in subordinate mode with nothing imported yet cannot sign. Features fall back to a manual signing ceremony rather than issuing nothing - for Connected Cache that means each node's request waits on the Certificates tab for you to sign and upload it. Nothing is silently issued from the wrong issuer.
Changing the mode
Each mode keeps its CA in its own slot, so switching modes never signs from a CA of the wrong provenance, and switching back does not require a fresh ceremony. Selecting Subordinate before the ceremony is complete reports Not set up rather than quietly falling back to the self-signed root. Selecting ACME before the ACME panel is filled in and saved is refused outright, with the reason - a mode pointing at a CA nobody configured would fail on every certificate with nothing to explain why.
Certificates already issued stay valid - they were signed by the old CA and continue to chain to it until they expire (cache-node certificates are valid for one year) or the service re-requests one.
Cache-node certificates renew themselves about a month before that year is up, signed by whichever CA is configured at renewal time - so switching modes migrates nodes onto the new CA as they come up for renewal, without a redeploy. Reports → Certificates shows every node's expiry, which CA signed it, and whether a renewal is failing.
When ACME certificates renew
With an ACME CA, the CA can have an opinion about when each certificate should be renewed, and FluxDeploy asks for it (RFC 9773, ACME Renewal Information). This applies to this server's own HTTPS certificate and to every cache node's certificate the ACME CA issued.
- CA implements ARI (Let's Encrypt, Google Trust Services, ZeroSSL, and newer internal CAs): the CA answers with a suggested window, and FluxDeploy renews at a fixed point inside it - not at the start, so a CA moving a million certificates forward does not get a million orders at once. The point is never later than the moment that still leaves time for the order itself and, for this server's own certificate, for every relay to acknowledge the new thumbprint before the cutover (a window that runs right up to expiry, as short-lived profiles do, is cut back to the part that does). A certificate too short for even that renews at the start of the window, and the renewal's audit entry says so; after a forced cutover the next renewal is also pulled to the start. The CA is asked again whenever it says to (usually every few hours), so if it brings the window forward - a key-compromise incident, a mis-issuance, its own maintenance - FluxDeploy renews early instead of finding out when the certificate is revoked underneath it. Each renewal order also tells the CA which certificate it replaces, so the CA stops suggesting a window for the old one.
- CA does not implement ARI (step-ca today, and any CA that does not list
renewalInfoin its directory): nothing changes. This server's certificate renews two thirds of the way through its lifetime, and a cache node's certificate renews at the configured days-before-expiry (or the same two-thirds point when its lifetime is shorter than that setting). - CA implements ARI but cannot be reached, or answers with something unusable: the local rule above is the fallback, and the CA is asked again six hours later. A window the CA already gave stays in force meanwhile.
The CA's window is only ever consulted for a certificate it issued and that has not yet expired. A certificate an admin uploaded by hand is renewed on the local rule even if the same CA signed it. When a renewal happens while the CA's window is in force, its audit entry says so. Nothing about this is configurable, and nothing about it needs to be: the local rule is what runs whenever the CA has not said otherwise.
Where the keys live
| Material | Storage |
|---|---|
| FluxDeploy's own self-signed root | CaPfx app setting, a PKCS#12 encrypted with ASP.NET Data Protection |
| The enterprise-signed CA | CaSubordinatePfx, encrypted the same way |
| Subordinate key awaiting signature | CaPendingKey, encrypted the same way |
| Pending request | CaPendingCsr (public material, stored as-is) |
| Issuer chain above the CA | CaChainPem |
| ACME account key | AcmeAccountKey, encrypted the same way. In ACME mode this is the only private key FluxDeploy holds for issuance - it identifies the account, it does not sign certificates |
| ACME external-account HMAC key | AcmeEabHmacKey, encrypted the same way |
| Staged ACME certificate | AcmePendingCertPfx, encrypted the same way, plus its thumbprint and dates. Cleared at the cutover, or by Discard staged certificate |
| Mode | CertAuthorityMode - selfsigned, subordinate or acme |
Upgrades from a version where this CA was Connected Cache-specific migrate the old MccCa* settings automatically on first use; the old keys are left in place and the CA is not regenerated.
Only Admin users can change these settings; ReadOnly users see the state but no actions, and Operator users have no access to Settings at all.