tls

package
v0.0.0-...-99cc010 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package tls handles certificate lifecycle for the global routing layer.

The Provider interface abstracts cert issuance so the router can run with (mkcert) or without (HTTP-only fallback) trusted certs. Providers must be safe for concurrent use.

Index

Constants

View Source
const MkcertVersion = "v1.4.4"

MkcertVersion is the pinned upstream release used by EnsureBinary. Bumping this string is the only place we re-point the auto-download.

Variables

This section is empty.

Functions

This section is empty.

Types

type CertPath

type CertPath struct {
	CertFile string
	KeyFile  string
}

CertPath points at on-disk PEM files. Both files are owned by the user running Locorum; the router container bind-mounts them read-only.

func (CertPath) IsZero

func (p CertPath) IsZero() bool

IsZero reports whether p has no usable file paths.

type CertSpec

type CertSpec struct {
	// Name is the directory the certificate is stored under
	// (~/.locorum/certs/<Name>/{cert,key}.pem). Must be filesystem-safe.
	Name string

	// Hostnames are the SANs the certificate must cover. Order is
	// canonicalised internally before SAN comparisons, so callers don't
	// need to sort.
	Hostnames []string
}

CertSpec is the desired-state input to Issue.

type Mkcert

type Mkcert struct {
	// contains filtered or unexported fields
}

Mkcert issues per-site and per-service certs by shelling out to the mkcert CLI (https://github.com/FiloSottile/mkcert). Detection is cached; the UI can poll Available() every frame without performance concerns.

Binary resolution order (first hit wins): bundled next to the Locorum executable (`<exeDir>/mkcert[.exe]` or `<exeDir>/bin/mkcert[.exe]`), downloaded into binDir (typically `~/.locorum/bin`), then $PATH. This lets release builds ship mkcert alongside the app and dev runs fall back to a system install or an on-demand download via EnsureBinary.

func NewMkcert

func NewMkcert(certDir, binDir string) *Mkcert

NewMkcert constructs a provider that stores certs under certDir (typically ~/.locorum/certs) and downloads/looks for the mkcert binary under binDir (typically ~/.locorum/bin). Pass an empty binDir to disable auto-download; resolution then falls back to bundled-next-to-executable or $PATH.

func (*Mkcert) Available

func (m *Mkcert) Available(ctx context.Context) (Status, error)

func (*Mkcert) EnsureBinary

func (m *Mkcert) EnsureBinary(ctx context.Context) (string, error)

EnsureBinary returns the path to a usable mkcert binary, downloading it into m.binDir if no existing binary is found. Safe to call repeatedly: once a binary exists in any of the resolution slots, the download is skipped. Errors only when no binary is present and the download fails (unsupported platform, network failure, write failure).

func (*Mkcert) InstallCA

func (m *Mkcert) InstallCA(ctx context.Context) error

InstallCA runs `mkcert -install` to generate (if needed) and install the local CA into the OS / browser trust stores. Calls EnsureBinary first so the user doesn't need a separate setup step. mkcert prints non-fatal warnings (e.g. failed sudo for the system store on Linux) but still succeeds and writes the rootCA file — combined output is captured and surfaced verbatim on error so the UI can show what happened.

On Linux the system trust store install needs sudo, which would hang a GUI process with no TTY; we set TRUST_STORES=nss so mkcert only writes to user-level NSS DBs (Firefox + Chromium-family). Users who want full curl/wget/java trust can re-run `mkcert -install` from a terminal.

func (*Mkcert) Issue

func (m *Mkcert) Issue(ctx context.Context, spec CertSpec) (CertPath, error)

Issue generates (or reuses) a cert covering spec.Hostnames. Idempotent: if the existing cert at ~/.locorum/certs/<spec.Name>/cert.pem already covers every requested SAN, it is returned unchanged. Otherwise mkcert is invoked, the new cert and key are written to a sibling temp dir, then atomically moved into place so a watching router never reads a half-written file.

func (*Mkcert) Remove

func (m *Mkcert) Remove(_ context.Context, name string) error

type Provider

type Provider interface {
	// Available reports whether the provider can issue certs on this machine.
	// For mkcert: checks the binary is on PATH and the local CA appears
	// installed. Cheap; callers may invoke this on every UI tick.
	Available(ctx context.Context) (Status, error)

	// Issue creates or refreshes a cert covering the given hostnames and
	// returns its on-disk paths. Idempotent: regenerates only if the
	// existing cert's SANs do not match the spec (so repeated calls are
	// safe and cheap).
	Issue(ctx context.Context, spec CertSpec) (CertPath, error)

	// Remove deletes a previously-issued cert (used when a site is removed).
	// Returns nil if the cert does not exist.
	Remove(ctx context.Context, name string) error
}

type Status

type Status struct {
	Installed bool   // provider's binary/dependency is available
	CARoot    string // path returned by `mkcert -CAROOT` (or empty)
	CATrusted bool   // best-effort: the local CA appears installed in a trust store
	Message   string // human-readable summary suitable for the UI
}

Status reports the state of the certificate provider.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL