Skip to content

ADR-0021: Host baseline and hardening

  • Status: Accepted. §5 and §6 superseded in part by ADR-0031
  • Date: 2026-08-17
  • Deciders: El, Lachlan
  • Supersedes: ADR-0014 §1 (in part), §2, §3

Context

ADR-0014 recorded nine unrelated decisions in one document, which meant no single part could be revised without reopening all of it. It is superseded by ADR-0021 through ADR-0027, one decision each. This ADR carries forward the host provider, sizing, SSH and firewall baseline substantially unchanged.

Decision

  1. Provider and region: Vultr, Melbourne (region per ADR-0008). The provider is an implementation detail chosen at provisioning time on price, specs and AU residency. The region is not.
  2. Sizing: one host to start, resize on demand. Size for the shared core stack plus tenant stacks with Metabase overhead assumed, not discovered, at roughly 2 GB per dashboard-paying tenant (ADR-0023). Dashboard clients, not automation clients, are what strain the box.
  3. SSH: key-only authentication, with passwords disabled after keys are verified working. Root SSH disabled. Per-person accounts (el, lachlan), each with their own key. Non-standard port. fail2ban.
  4. SSH private keys are never shared. Each person generates their own keypair, and both public keys are deployed by the role. A shared private key cannot be revoked for one person without locking out both, and it destroys attribution in the logs.
  5. Firewall: default-deny inbound. ~~Only the SSH port, 80 and 443 open.~~ Superseded by ADR-0031: public exposure is 80 and 443 only, with SSH reachable on the Tailscale interface. Port 80 exists solely for the ACME challenge and the redirect to HTTPS. Everything else is internal to the host and never internet-exposed.
  6. ~~Tailscale is deferred, with a trigger.~~ Superseded by ADR-0031: Tailscale is adopted from the start and the public SSH port is closed. The deferral rested on the premise that adoption was new work, which was false.

Consequences

The host is reproducible from Ansible with no hand-configured drift (ADR-0024). Per-person accounts preserve attribution in audit logs, which matters because the approval chain (ADR-0026) is evidence.

Alternatives considered

  • Password authentication retained as a fallback is rejected. It is the fallback that gets brute-forced.
  • Standard port 22 is kept as an option. The non-standard port is noise reduction rather than security, and is not relied on as a control.