Production-ready vs reference (prod-delta) & local↔production checklist

Diátaxis quadrant: Reference. Audience: engineering leaders, security reviewers, and integrators promoting humanymous Gate from a local reference build toward a production deployment.

This is the honesty page. This repository is a reference implementation, not a production-hardened build. humanymous Gate (“Gate” after first mention) is the reverse-proxy enforcement layer: it terminates TLS, streams the detection bundle into HTML, scores layers L1–L7 inline, enforces the verdict at the edge, and writes every decision to a tamper-evident audit log in front of an origin app it does not control.

The reference build demonstrates every mechanism end-to-end so you can evaluate it, but several components ship as dev-grade stubs that are safe on a laptop and unsafe in production. This page names each one — what the reference ships versus what a production deployment must supply (the “prod-delta”) — and then gives a checklist for the local→production promotion.

For a component-level inventory of flags and presets, see CLI, config & policy reference. For key handling specifics, see the Key management guide. For install prerequisites, see Install requirements. For version-to-version moves, see the Upgrade & migration guide.

Warning: Nothing that is dev-only in the reference build should reach production. That specifically means ephemeral in-memory keys, the self-signed in-memory TLS certificate, the printed bearer dev tokens, and the default in-process (single-node) verdict and ban stores. Each has a production replacement listed below; shipping the dev-grade version is a security and availability risk, not a shortcut. (An experimental, off-by-default -redis shared-state backend for verdicts/bans/rate-limits now exists — treat Redis as a trusted, network-isolated component; see CLI flags.)


Component-by-component: reference vs prod-delta

Each row states what the reference binary ships and what a production deployment is responsible for adding or replacing. “prod-delta” means the item is deliberately out of scope for the reference and is a production responsibility.

Component What the reference ships Production responsibility (prod-delta)
TLS certificate A self-signed certificate minted in memory at boot. Fine for localhost, rejected by real clients. Real certificates via ACME or bring-your-own, backed by a real KMS/HSM for key custody.
Node signing / HMAC / vault keys Ephemeral by default: a restart mints a new Ed25519 signing key (verifier public key changes) and a new vault (all pseudonym linkage lost ≈ accidental mass crypto-shred). A sealed keystore (-keystore + HMN_UNSEAL) makes them persistent. Always run with -keystore + HMN_UNSEAL for a stable identity; back up the passphrase out-of-band. See Key management.
Automated key rotation Not implemented for the signing/HMAC keys. (The verdict-token epoch key rotates every 15 min in-process; that is separate.) Rotation would require re-anchoring the chain. An operational rotation procedure with re-anchoring. prod-delta.
Admin authentication Bearer RBAC tokens over the separate admin listener, constant-time compared (random per boot unless set via HMN_ADMIN_TOKENS), plus optional mTLS on the admin listener via -admin-mtls-ca: when set, a client certificate signed by your CA is required in addition to the bearer token. SSO for the admin plane (front it with an authenticating reverse proxy). prod-delta.
Verdict store & bans (fleet state) In-process, single node. Verdict trust tokens and IP/fingerprint bans live in memory on one Gate instance. A shared store (for example Redis) so verdicts and bans are consistent across a fleet. prod-delta.
TLS fingerprint capture (JA4) — Core engine The Core (cmd/server) does capture the raw ClientHello + H2 on its own accept loop, so JA3/JA4/H2 and their cross-checks fire when the Core is the direct TLS terminator. Same mechanism, hardened; requires no re-terminating CDN/L7-LB in front (see Supported topologies).
TLS fingerprint capture (JA4) — Gate proxy The Gate (cmd/gate) does NOT extract the ClientHello: JA3/JA4/H2 and their cross-checks (HR-2/HR-5/HR-11/HR-14) do not fire at the gate. Detection there is client + headers + behavior + IP-intel only. Wire raw ClientHello + H2 capture into the gate accept loop (the captureListener pattern exists in cmd/server), or deploy the Core as the terminator. prod-delta.
Datacenter-ASN signal (l5.ip.datacenter_asn) Fails open — no CIDR dataset ships, so the signal fires for no one. (An earlier stub flagged every public IP and mass-CHALLENGEd real users via HR-11; that is fixed.) Wire a real cloud/ASN CIDR feed via SetDatacenterCIDRs if datacenter egress is in your threat model. prod-delta.
Audit-log verification Live Integrity / SelfVerify (HMAC + STH + witness). Public keys published via boot log and GET /__hmn/admin/keys; library Verify can run with HMAC nil (hmac-unchecked). Empty chain fails (empty-chain). A packaged standalone offline verifier binary in cmd/ remains prod-delta. See Verify the audit log.
Retention retirement HOT / WARM / COLD labels are declared only (Tier(age) has no production enforcer; WAL unbounded with -audit-wal, RAM-only without). Operator retention schedule, archival, and optional WORM. prod-delta.
Live console updates The Ledger refreshes/polls; a manual refresh button re-verifies the chain on demand. SSE live-push for real-time console updates. prod-delta.
False-positive triage UI No dedicated FP/appeal-queue view. Triage is done from the Overview feed plus Sessions drill-down. A dedicated FP/appeal-queue view. prod-delta.
Challenge / PoW interstitial A minimal accessible interstitial (HTTP 401, no-store, lang="en", a plain-language message, loads the control-plane PoW loader). The code states production self-hosts the WCAG UI. A full self-hosted WCAG 2.2 AA-conformant challenge experience. prod-delta. See Challenge accessibility.
Observability export The audit stream (GET /audit with filters + cursor), the Integrity view/endpoint, the Overview KPIs, a Prometheus text-exposition GET /__hmn/admin/metrics gauge snapshot on the admin plane (uptime, chain size, active bans, kill-switch/monitor state, goroutines/heap), and GET /__hmn/healthz (liveness) + GET /__hmn/readyz (readiness — 503s during a graceful drain) answered by Gate itself. SIEM log shipping of the audit stream, and wiring the metrics/health probes into your platform. prod-delta. See Observability & SIEM.
Graceful shutdown & ingress caps On SIGINT/SIGTERM Gate drains both listeners (bounded by -shutdown-grace, readiness flips to draining first) then seals the keystore; an optional -max-body caps proxied request bodies (413 over the limit); add-only OWASP security response headers ship, with HSTS opt-in via -hsts. Tune -shutdown-grace to your orchestrator’s termination grace and set -max-body/-hsts for your traffic. Already shipped — no prod-delta.

Note: The /health route is an origin app path mapped to the off preset (a bypass), not a Gate probe. For Gate’s own health, use GET /__hmn/healthz (liveness) and GET /__hmn/readyz (readiness — it returns 503 once a graceful shutdown starts, so a load balancer drains the node first). Both are answered by Gate and carry no data.


Local → production checklist

Work through this before any deployment that faces real traffic. Each item removes one dev-only behavior described above.

Identity and keys

  • Run with a sealed keystore. Set -keystore <path> and HMN_UNSEAL so the signing key, per-record HMAC key, and pseudonym vault persist across restarts. Without this, keys are ephemeral and a restart is an accidental mass crypto-shred (cryptographic erasure) — the verifier public key changes and all pseudonym linkage is lost.
  • Back up HMN_UNSEAL out-of-band. Losing the passphrase means the sealed identity cannot be opened (you lose chain-signing continuity and vault linkage ≈ mass crypto-shred). Store it separately from the keystore file. See Key management.
  • Plan key rotation as an operational procedure. Automated rotation of the signing/HMAC keys is not implemented and requires re-anchoring; decide who rotates, when, and how the chain is re-anchored.

Transport and origin trust

  • Replace the self-signed dev certificate with real certificates (ACME or bring-your-own) backed by a real KMS/HSM. The in-memory self-signed cert is for localhost only.
  • Set a real -origin-key. Provide a stable origin-cloaking HMAC key so the origin can validate X-Hmny-Origin-Auth. If left unset the key is random and ephemeral, and the origin cannot reliably distinguish Gate-forwarded traffic from a direct hit.

State and fleet

  • Externalize fleet state. The reference keeps verdict trust tokens and IP/fingerprint bans in-process on a single node. For more than one Gate instance, move them to a shared store (for example Redis) so verdicts and bans are consistent fleet-wide.

Admin plane

  • Harden admin auth beyond bearer dev tokens. Do not carry the printed dev tokens (or a static HMN_ADMIN_TOKENS value) into production. Enable mTLS on the admin listener with -admin-mtls-ca <pem> so a client certificate signed by your CA is required in addition to the bearer token; put SSO in front with an authenticating reverse proxy. Preserve the RBAC role separation — Auditor, Operator, Approver, DPO — and keep dual-control intact (a distinct Approver commits a permanent/CIDR ban or the kill switch; a distinct DPO commits an erasure). See RBAC & separation of duties.

Verification, observability, and challenge UX

  • Provide an offline audit verifier package if your compliance posture requires a separate binary off-box. The library path (internal/audit.Verify + published keys) already supports public-key-only checks; packaging it under cmd/ is still a prod-delta.
  • Add observability integration. The reference now ships a Prometheus GET /__hmn/admin/metrics (admin plane) plus /__hmn/healthz (liveness) and /__hmn/readyz (readiness) probes — point your orchestrator’s probes at them and set a stop_grace_period/terminationGracePeriodSeconds-shutdown-grace. Wire the audit stream into your SIEM for the decision record. See Observability & SIEM.
  • Self-host the full WCAG challenge UI. The reference serves only a minimal accessible interstitial. Any accessibility conformance statement applies to the deployed challenge you host, not to the reference page. See Challenge accessibility.
  • Plan for retention retirement. The reference declares tier labels but does not prune, compress, or WORM-retire the audit chain; implement an operator schedule if your policy requires it.

Warning: Cryptographic erasure (crypto-shred) is irreversible — it destroys the per-subject linkage key while the hash chain and Merkle anchors stay intact. Running with ephemeral keys turns every restart into an unintended fleet-wide erasure of pseudonym linkage. Confirm the keystore checklist items above before production.


What is not a prod-delta

Some limitations are design boundaries, not stubs a production build removes:

  • The T4 ceiling. Anti-detect tooling combined with real-human click-farms (tier T4) is an explicit design boundary, not something a production deployment “fixes.” It is mitigated only by rate and reputation controls, never eliminated.
  • The unanchored in-window residual. The audit log is tamper-evident, not tamper-proof: records after the last signed checkpoint remain re-writable by the writer until the next checkpoint (every 32 records). This is an honestly-scoped property, not a gap a production build closes.
  • Fail-open on safe-method GET/HEAD (non-strict routes). This is a documented accepted residual covered by fingerprint/subnet rate metering, chosen deliberately — not a stub.

For the reasoning behind these boundaries, see What Gate is and Hard rules & verdicts.