Skip to content

Prerequisites

  • The Hermetic desktop app, and the hermetic CLI its Install Command Line Tool… menu item puts on your PATH. README.md has the install, the one-time quarantine clearance for the unsigned build, and how updates arrive; this runbook assumes both are already in place. A source checkout needs Bun per .bun-version instead.

  • An AWS profile in ~/.aws/config with credentials for the account you want to target — SSO, assume-role, or static all work; hermetic reads the profile, never AWS_PROFILE/AWS_ACCESS_KEY_ID directly (it warns if either is set, since aws.client() ignores them).

  • One line in your tailnet policy file, pasted by hand before you create the OAuth client, because the client form only offers tags that already have an owner:

    "tagOwners": { "tag:hermetic": ["autogroup:admin"] }

    That is the only policy edit you make. hermetic writes its own ssh and acls entries itself once the client exists (§5.2), between // hermetic:managed markers, leaving every other byte of the file exactly as you wrote it.

  • A Tailscale OAuth client, created by hand in the Tailscale admin console, carrying three scopes — auth_keys write (mints each agent’s join key) and devices:core read + write (lets doctor check device drift and lets recreate/destroy delete an agent’s stale device), both restricted to tag:hermetic, plus policy_file (lets hermetic keep the entries above current). Tailscale will not restrict policy_file to a tag — it is tailnet-wide — and attaches devices:posture_attributes and devices:core:read to it. There is no API to create this, init cannot do it for you. A client with fewer scopes still works: with only auth_keys agents come up but stale devices accumulate and doctor reports device drift as unchecked; without policy_file you paste the ssh and acls entries yourself (hermetic policy prints them and says what is missing). Widening it is a new client (Tailscale cannot edit an existing one’s scopes) plus a rotation — see below.

  • HTTPS Certificates enabled for the tailnet (admin console → DNS; MagicDNS must be on). Every agent serves its dashboard and noVNC at https://<fleet>-<name>.<tailnet>.ts.net (the cloud name, §6.1); init --create refuses and hermetic doctor reports when it is off. The only cost: agent hostnames appear in public Certificate Transparency logs.

  • An agent’s dashboard asks for no login. Hermes runs in its unauthenticated local mode behind a loopback reverse proxy on the box, so the tailnet ACL is the perimeter: whoever your policy file lets reach tag:hermetic on 443 can drive every agent. Keep that ACL tight — there is no second gate, and Hermes’s audit log records no per-user identity (§6.4). That is a decision, not an oversight: Hermes does offer a password-gated posture, and hermetic declines it rather than issue and rotate a password per agent for operators already inside the tailnet.

  • Enough IAM permission on the profile to create a CloudFormation stack, DynamoDB tables, an S3 bucket, and EC2/SSM resources — the exact policy is the foundation stack’s own template (unverified — never applied).