Skip to content

Data directory layout

Everything localca persists lives in Config.DataDir. Nothing is written outside it, and no keychain, secret store or registry is used.

Files written under DataDir

File Mode Contents Created by
rootCA.pem 0644 The root certificate, PEM CERTIFICATE first Install or EnsureServed
rootCA-key.pem 0600 The root private key, PEM EC PRIVATE KEY (SEC 1, P-256) first Install or EnsureServed
leaf.pem 0644 The cached server certificate EnsureServed
leaf-key.pem 0600 The cached server key, PEM EC PRIVATE KEY EnsureServed
trust-install.json 0644 Which stores this root was installed into the default trust-store backend

The directory itself is created with mode 0700.

Authority.Leaf writes nothing — it returns an in-memory certificate. Only EnsureServed maintains the cached leaf files.

What is safe to copy, and what is not

rootCA.pem is a public certificate. Copying it to another machine and importing it there is the supported way to make a second device trust your certificates.

rootCA-key.pem is the signing key for a certificate authority your machine trusts. Anyone holding it can mint a certificate for any hostname that your machine will accept. It must not be copied off the machine, committed, backed up to a shared location, or baked into an image. That is the whole reason localca mints a fresh root per machine rather than shipping one; see the trust model.

trust-install.json

{"fingerprint":"<hex sha-256 of the root certificate DER>","system":true}

The OS system store has no portable "is this certificate trusted?" query, so localca records its own installs here and treats that record as the answer. The fingerprint ties the record to one specific root, so a re-minted root is correctly reported as not installed.

Consequences worth knowing:

  • Deleting this file makes localca believe the root is not installed. The next EnsureServed re-runs the install and prompts for elevation again. The install itself is idempotent, so no duplicate entry is created.
  • Removing the root from the OS store by hand does not update this file. localca keeps reporting System: true and will not reinstall until the file is deleted or the root is re-minted.
  • The NSS half of TrustState is never read from this file; it is queried live.

Temporary files during a write

Every file is written by creating .<name>.<random>.tmp in the same directory, setting the final mode on it, and renaming it over the target. A rename within one filesystem is atomic, so a crash mid-write leaves either the complete old file or the complete new one — never a truncated key. The temporary file is removed if any step fails.

If you find a stale .rootCA-key.pem.*.tmp in the data directory, a write was interrupted in a way that also prevented cleanup. It is safe to delete.

What survives which call

Call rootCA*.pem leaf*.pem trust-install.json
Install created if absent untouched written when StoreSystem is targeted
EnsureServed created if absent created or refreshed written when it installs
Uninstall kept kept set to system: false
Uninstall with Purge() deleted kept set to system: false

What Purge leaves behind

Purge() deletes rootCA.pem and rootCA-key.pem only. The cached leaf.pem and leaf-key.pem are left in place, and they are still signed by the root you just deleted.

If you provision again in the same data directory, EnsureServed mints a new root but reuses that stale leaf — it covers the same hosts and has not expired, so the cache check passes. The server then presents a certificate chaining to a root that is no longer installed anywhere, and every client rejects it, until the leaf drifts out of the cache (a different host list, or the seven-day renewal window).

Delete the leaf files yourself when you purge:

rm -f "$DATA_DIR"/leaf.pem "$DATA_DIR"/leaf-key.pem

Or remove the whole data directory, which is the cleanest reset:

rm -rf "$DATA_DIR"     # after Uninstall, so the trust store is cleaned up first

Recovering from a half-written root

localca reads the root certificate and key as a pair. If rootCA.pem exists but rootCA-key.pem does not, every call fails with:

localca: root cert present but key missing

This is deliberate — a certificate with no key is not something to silently replace, because the matching root may be installed in your trust store. Recover by removing the root from the trust stores if it is still there, then deleting rootCA.pem so the next call mints a fresh pair.

A corrupt leaf is handled differently: an unparseable leaf.pem is treated as no cached leaf at all and is quietly re-minted.