Headless mode, signals, the status socket, the audit log, metrics, and the container image for a pod.
How-toFor developers
Connect runs Gatekeeper with a dashboard in a terminal. This page is for a service, a script, or a pod.
Headless
sh
gatekeeperrun--headless
Log lines go to stdout, which is what a container or a systemd unit wants. --log-format json is for a log shipper; --log-level takes debug, info, warn or error.
Signals:
SIGHUP reloads the configuration in place and re-attests every endpoint. A reload that fails to load or validate changes nothing.
SIGINT and SIGTERM drain the listeners (--drain-timeout, 30 seconds by default) and exit.
Status from another process
Add an admin section so gatekeeper status in one terminal can report on a gatekeeper run in another. Loopback or a Unix socket only: it carries verdicts.
The audit log is one JSON object per line: every verdict and every blocked request, never a request or response body. Each verdict line carries rootAnchor, one of trustedRoots, attested (registry) or attested (operator-pinned), so a review can tell what admitted a cloud without reconstructing the configuration in force at the time. Metrics are Prometheus, off unless metrics.listen is set.
Every tuning knob has an environment override, globally (CR_GATEKEEPER_REATTEST_INTERVAL) or per endpoint (CR_GATEKEEPER_ENDPOINT_ROUTER_FAIL_MODE). Precedence, weakest first: built-in defaults, the file, CR_GATEKEEPER_*, command-line flags.
The container image
What a person installs is a binary from a GitHub release. The other packaging is a container image, for a pod that runs Gatekeeper beside the process it serves:
It holds the same static binary the archives do, runs as uid 65532 on a read-only root filesystem, and writes nothing. Pin it by digest and give it nothing it does not need:
The entrypoint is a supervisor rather than Gatekeeper itself. It waits for $GATEKEEPER_CONFIG (default /etc/gatekeeper/config.yaml) to hold a configuration Gatekeeper will run, starts gatekeeper run --headless, and sends SIGHUP whenever the file's contents change, so a configuration rendered by whoever owns the file is applied in place. $GATEKEEPER_WATCH_INTERVAL (default 2s) tunes the poll. SIGTERM is passed through.
Two things it does not forward: identical bytes (a rewrite that changed nothing does not re-attest every endpoint), and a file that is not a configuration (a writer that truncates before it writes is briefly an empty file). Render to a temporary file and rename, and the second case never happens.
One-shot commands skip the supervisor: --entrypoint /usr/local/bin/gatekeeper.
Policies
User policies are Rego modules, ANDed with the built-in pin policy, so a policy can narrow trust but never widen it:
The offline run is policy-only: no signature, chain, freshness or live channel is checked, and it says so. The input document is specified in the repository: docs/contracts/rego-input.md.