Platform support¶
localca's certificate generation is pure Go and works anywhere Go builds. Installing the
root into a trust store does not — that part shells out to platform tools, and the platforms
differ. This page states exactly where each store works.
Which stores work on which OS¶
| OS | StoreSystem |
StoreNSS (Firefox/Chromium) |
|---|---|---|
| Linux | works | works when certutil is installed |
| macOS | works | works when certutil is installed |
| Windows | does not work — see below | not supported |
| FreeBSD | untested; the underlying library has a FreeBSD path | not supported |
| anything else | not supported | not supported |
The trust-store install is not exercised by the default pipeline — it mutates the real
machine, so it lives behind env-gated integration tests (INT_TEST=1) that are run by hand
on Linux. macOS uses the same code path as mkcert and is expected to work, but has no
automated coverage either. Certificate generation and the pure logic around it are unit
tested on every pipeline.
What a system-store install actually does¶
StoreSystem is the OS-wide trust store — the one Chrome, Safari, Edge and Go's own
net/http client read.
Linux. The root certificate is written into the distribution's anchor directory and the
distribution's update command is run, both through sudo. The anchor directory is detected
at runtime, in this order: /etc/pki/ca-trust/source/anchors/ (with update-ca-trust
extract), /usr/local/share/ca-certificates/ (with update-ca-certificates),
/usr/share/pki/trust/anchors/ (with update-ca-certificates),
/etc/ca-certificates/trust-source/anchors/ (with trust extract-compat), then
/etc/ssl/certs/ (with trust extract-compat). The file is named after the trust-store
entry name, <AppName>-localca-<serial>.
macOS. security add-trusted-cert adds the root to the system keychain, then the trust
settings are exported, patched and re-imported — again through sudo.
If none of the Linux anchor directories exists, the install fails rather than silently doing nothing.
Why Windows does not work¶
Two independent reasons, and both are in localca or its trust library rather than in
Windows:
- The elevation pre-flight cannot succeed. Before any system-store install,
localcachecks that it can obtain administrator privileges: it is satisfied byos.Geteuid() == 0, otherwise it requiressudoonPATHand an interactive terminal on standard input. On Windowsos.Geteuid()always returns-1, so the root branch can never be taken — not even in an already-elevated Administrator console. With nosudoonPATHthe check returnsErrElevationUnavailablebefore the install is attempted. Where asudoshim is onPATHthe check proceeds to runsudo -v, which is not a command Windowssudoaccepts, and the install fails with a wrapped error instead. - NSS is not implemented for Windows. The underlying trust library supports NSS on
macOS and Linux only. On Windows, targeting
StoreNSSis silently skipped andTrustState.NSSis alwaysfalse.
What still works on Windows: minting the root and leaf, storing them, and serving TLS with
them. What does not: getting a browser to trust the result without importing rootCA.pem
into the Windows root store yourself.
This is a gap in this module, not a decision. It is recorded in limitations.
What StoreNSS covers¶
NSS is the certificate database Mozilla products use. localca installs into every NSS
profile it finds:
- every directory matching the Firefox profile glob —
~/.mozilla/firefox/*on Linux,~/Library/Application Support/Firefox/Profiles/*on macOS; ~/.pki/nssdb, which is what Chrome and Chromium read on Linux.
Chrome and Chromium on macOS read the system keychain, not NSS, so StoreSystem is what
covers them there.
A profile counts only if it contains a cert9.db (modern, SQLite) or a cert8.db (legacy).
A profile directory that a browser has never opened contains neither and is skipped.
certutil is required for NSS¶
The NSS install runs certutil from the NSS tools package. Without it:
Installskips NSS silently and continues with the system store;InstalledreportsNSS: false;- nothing errors.
Install it with one of:
sudo apt-get install -y libnss3-tools # Debian, Ubuntu
sudo dnf install -y nss-tools # Fedora, RHEL
brew install nss # macOS
On macOS, certutil is also found via brew --prefix nss when it is not on PATH.
If you cannot install packages, see
getting certutil without root.
TrustState.NSS means every profile¶
The NSS state check reports true only when the root is present in every NSS profile it
finds. Adding a new Firefox profile after installing flips NSS back to false until you
install again. This never affects serving, because only the system store gates provisioning.
What elevation looks like¶
| Situation | Behaviour |
|---|---|
Only StoreNSS targeted |
no elevation, no prompt |
Process already running as root (euid == 0) |
no prompt |
Non-root, sudo present, interactive terminal |
one sudo -v password prompt, then the install runs without prompting again |
Non-root, no sudo on PATH |
ErrElevationUnavailable, nothing is installed |
| Non-root, no interactive terminal (service, CI, GUI app) | ErrElevationUnavailable, nothing is installed |
The pre-flight exists so a tool never hangs on a password prompt that nothing can answer.
A consumer catches ErrElevationUnavailable and falls back — to an NSS-only install, to an
untrusted self-signed certificate, or to telling the user to run one command in a terminal.
There is no desktop password dialog. A windowed application with no terminal gets
ErrElevationUnavailable; see
no GUI elevation.
Headless servers and CI¶
A headless Linux box with no sudo, no TTY and no certutil is a supported build target
and an unsupported install target: certificate generation works, trust installation
returns ErrElevationUnavailable. For CI that needs the root trusted, run the container as
root — the pre-flight passes on euid == 0 and no prompt appears.