Skip to main content
CID222 Docs

Certificates

Give the appliance an HTTPS certificate your machines already trust, distribute its root CA, and trust a TLS-inspecting proxy on the way out.

  • Version: 0.4
  • Role: superadmin, admin_user
  • Type: task

Settings → Certificates governs one thing: what this appliance presents on https:// — for the dashboard, the API and the LLM proxy. You either let the appliance sign its own certificate from a root CA you distribute once, or you install a certificate from a CA your machines already trust. The same page holds the outbound half: the CA to trust when your network re-signs HTTPS on the way out.

What do I need?

Licence
Any
Role
superadminadmin_user

Prerequisites

  • The appliance has completed the first-boot setup wizard. Until it does, every /admin route answers 423 SETUP_REQUIRED.
  • You sign in as superadmin. The dashboard lists this pane only for superadmin and for the read-only viewer role, although the API accepts admin_user.
  • Every DNS name your users will reach the appliance by already resolves to it — see Naming, DNS and TLS.
  • For your own certificate: a PEM leaf certificate, its intermediates, and either the matching unencrypted private key or a pending CSR from this page.
  • For outbound trust: the issuing CA certificate of your TLS-inspecting proxy, as PEM.

Three trust anchors, one page

The page says this itself under Which certificate do I need?, and it is the distinction that saves the most time:

  • This page — the appliance's HTTPS certificate. Needed by every browser opening the dashboard, by the browser extension, and by Claude Code and API clients pointed at the box.
  • Browser Inspection — the inline proxy's root CA. Needed only on devices whose traffic is routed through the inline proxy.
  • Endpoint agent — its own per-device CA. Generated and installed by the agent; nothing to download here.

The Mode field names which of five states the appliance is in.

ModeWhat the page showsWhat it means
appliance-caIssued by this appliance's own CAThe default for a new install. A box-local root CA, valid ten years, signs a leaf valid 825 days.
customCustomer certificateYour own certificate, uploaded with a key or issued against a CSR from this page.
legacy-self-signedSelf-signed (installed by the original setup)The bare self-signed leaf from the 0.3.48 installer. Every browser warns, on every device.
noneNo certificate yetA status file exists and names no certificate.
unavailableNot managed on this deploymentNo host reconciler has reported. TLS is terminated by something in front of the API, and the rest of the page is hidden.

Only the leaf changes when you rename or renew. The root CA is preserved, so trust you have already distributed survives both.

Set the names the appliance is reached by

Open the certificate settings

Select Settings → Certificates.

The page shows Mode, Subject, Issuer, Valid until with the days remaining, Names (SAN), Fingerprint (SHA-256) and Measured — how long ago the host last reported. It refreshes every ten seconds.

Enter the extra names

In Names, comma-separated, list every hostname and IPv4 address the appliance is reached by, besides its own address and hostname — for example app.cid.example.com, api.cid.example.com.

The helper line under the field shows Wanted: — the SAN set the host will issue for, including the names it derives itself. Each entry must be a hostname or an IPv4 address, at most 253 characters, and there is a limit of 32 names.

Reissue the leaf

Select Save names and reissue.

A toast reports Names saved — the certificate is being reissued, and the page shows Applying on the host: ensure until the host reconciler finishes. Names (SAN) then matches Wanted:.

Note

One host reconcile runs at a time. A second change while one is pending is refused with a host reconcile is already pending (tls/ensure); wait for it to finish.

Give the appliance a certificate

Use this when you can distribute one root certificate to your fleet — by Group Policy, MDM or by hand — and never think about it again.

Switch to the appliance CA

Select Use the appliance CA for HTTPS.

The button appears only when the mode is not already appliance-ca. A toast reports Switching to the appliance CA, and the mode changes once the host reconcile completes.

Download the root certificate

Under Appliance root CA, select cid222-appliance-root.crt.

The download needs no sign-in, so a machine that does not yet trust the dashboard can fetch it — the page prints the curl command for exactly that case. The same certificate is offered in PEM form beside it.

Check the fingerprint before you distribute it

Compare the downloaded file's SHA-256 fingerprint with CA fingerprint (SHA-256) on the page.

The page labels this step itself: verify this before trusting a downloaded file.

Install it as a trusted root on your machines

Distribute the file to the machine trust stores of every device that opens the dashboard, runs the browser extension, or points Claude Code and API clients at the appliance.

Browsers stop warning. Because only the leaf is reissued on a rename or renewal, this is a one-time distribution.

Warning

A custom certificate never renews itself. Thirty days out the page shows Certificate expires in N days with the note Renew it with your PKI and upload the new certificate. Past expiry the appliance keeps serving the expired certificate until you upload a replacement or switch back to the appliance CA.

Trust a TLS-inspecting proxy on the way out

If your network re-signs HTTPS with its own CA, the appliance cannot reach the LLM providers or the update channel until it trusts that CA.

Paste the proxy's issuing CA

Under Outbound trust (TLS-inspecting networks), paste the proxy's issuing CA certificate in PEM form.

Paste the issuing CA, not a leaf: a certificate without CA:TRUE is refused.

Install it

Select Trust this CA for outbound connections.

A toast reports Site CA accepted: with the certificate's subject. The host adds the CA to its trust store and recreates the gateway container with that bundle, so outbound HTTPS from the appliance validates against it.

Fields reference

Values the status block shows, from GET /admin/certificates/status.

Field on the pageResponse fieldWhat it holds
ModemodeOne of the five states above.
SubjectsubjectSubject of the certificate currently served.
IssuerissuerWho signed it.
Valid untilnot_after, days_leftLeaf expiry, and the days remaining.
Names (SAN)sansThe SANs the served leaf actually carries.
Fingerprint (SHA-256)fingerprint_sha256SHA-256 over the leaf, colon-separated hex.
Measuredmeasured_atWhen the host last wrote its status, as a relative time.
CA subject, CA valid until, CA fingerprint (SHA-256)ca_subject, ca_not_after, ca_fingerprint_sha256The appliance root CA.
Wanted:wanted_sansThe SAN set the host will issue for on the next reconcile.
namesThe operator-set extra names, as saved.
Applying on the hostpending_intentThe reconcile in flight, and its action.
csr_pendingTrue only when a request was asked for and the file exists on the host.

No private key is ever readable through this page or its API.

Verify

  1. Settings → Certificates shows the Mode you chose, an Applying on the host notice that has cleared, and Names (SAN) equal to Wanted:.

  2. Valid until is in the future and Measured is recent — a stale Measured means the host reconciler is not running, whatever the rest of the page says.

  3. Open the dashboard from a machine that trusts your CA, over the appliance's own name. The browser shows no certificate warning.

  4. From an untrusted machine, fetch the root certificate anonymously and confirm it downloads as a certificate rather than an HTML page:

    curl -kO https://<appliance-fqdn>/certs/appliance-root.crt
    openssl x509 -in appliance-root.crt -noout -fingerprint -sha256

    The fingerprint matches CA fingerprint (SHA-256) on the page.

Note

Certificate changes write no row to Event logs — the module logs to the container log only. The page's own status, and the last_apply record the host writes back, are the audit trail available to you.

If it fails

The appliance is not reachable on 443, or the certificate has expired:

Runbooktls

The certificate has expired, or nothing is serving 443

You might see: ERR_CERT_DATE_INVALID · NET::ERR_CERT_AUTHORITY_INVALID · connection refused on 443 · the dashboard cannot be reached over HTTPS

Before you start

Checks

  1. 1

    Verify something is actually holding port 443 on the appliance host

    diagnostics · appliance.tls.servedBy

  2. 2

    Verify the appliance has a certificate to serve

    diagnostics · appliance.tls.mode = "none"

  3. 3

    Read how many days the served certificate has left

    diagnostics · appliance.tls.daysLeft = 0

  4. 4

    Check whether the certificate is inside the renewal window — 30 days, the `CID_TLS_RENEW_DAYS` default `appliance/tls/ensure-tls.sh` renews an appliance-issued leaf at and warns about a customer certificate at

    diagnostics · appliance.tls.daysLeft = 30

  5. 5

    Verify the appliance root CA is present, so clients can be made to trust an appliance-issued certificate

    diagnostics · appliance.tls.caPresent = true

Everything the gateway refuses surfaces verbatim in a red toast. The ones worth knowing:

  • a host reconcile is already pending (tls/install); wait for it to finish → one reconcile runs at a time. Wait for Applying on the host to clear, then repeat the action. Note that the files you submitted are already staged on the host, so you do not need to re-paste them for the validation to have happened — but the action itself did not queue.
  • cert is a CA certificate; upload the server (leaf) certificate, with the CA in chain → you pasted your CA into Certificate (PEM). It belongs in Chain.
  • chain link 1 (…) did not issue … — order the chain leaf-side first → the intermediates are in the wrong order. The certificate that signed your leaf comes first.
  • key is not a PEM private key (encrypted keys are not accepted — decrypt it first) → the key is passphrase-protected.
  • the private key does not match the certificate → the two halves are from different issuances.
  • no key uploaded and no CSR is pending — generate a CSR first, or upload the key with the certificate → you left the key box empty without a pending request on this appliance.
  • the certificate has no subjectAltName; browsers reject certificates without one → the CA issued on the common name alone. Re-issue with SANs.
  • this certificate is not a CA (basicConstraints CA:TRUE); upload the proxy's issuing CA, not a leaf → outbound trust was given a server certificate.
  • not a hostname or IPv4 address: … or at most 32 names → the names field. Only hostnames and IPv4 addresses are accepted, and no more than 32 of them.
  • no CSR is pending — generate one first (404) → the request was consumed by an install, or never generated.
  • this appliance has no root CA yet (404 on the download) → the host has not created the CA. Switch to the appliance CA to make it.

Next steps

Last updated on

On this page

Download PDF