# Join the public relay
One command on the box signs you in with GitHub and claims the box on the
public relay: your apps get https://<hash>-<you>.public.getpiper.dev URLs
with no port forwarding and no domain of your own.
## One command
On a box running piperd, one command signs you in and claims the box:
piper login
# To log in, open: https://github.com/login/device ... enter the code: XXXX-XXXX
# logged in to relay as alice
# claiming this box… enrolled as ab12-alice.public.getpiper.dev
# applying… piperd connected — this box is live
piper login is the whole flow: GitHub device-flow identity, then it hands
the account credential to piperd over a local enrollment socket. piperd
itself calls the relay, validates the token with a real tunnel handshake,
persists relay.json, and applies it — draining and re-executing its own
process so the enrollment is live within seconds. No sudo command to
copy-paste, no manual restart, on any install (systemd, Homebrew, or a manual
dev box).
login opens the verification page in a browser as a convenience; the URL and
code are always printed too. Set PIPER_NO_BROWSER=1 to skip the launch — for
a headless box, an SSH session, or a test harness driving the CLI.
Run login on the box: on a machine with no piperd install (no systemd
install, launchd agent, or existing data dir) it stops after identity —
"identity only — no piperd on this machine; run piper login on a box to
connect it." Exit 0; that's the expected shape for a laptop that only drives
boxes remotely (see Remote control), not an
error.
piper login claims the box in terminated mode: piperd holds no cert and
serves apps on :80; the relay assigns each app a single-label hostname
<app-hash>-<username>.public.getpiper.dev, terminates its HTTPS with its
wildcard cert, and forwards plaintext HTTP over the tunnel.
piper login # GitHub sign-in + claims this box, terminated
piper deploy blog --path . # → https://<hash>-<you>.public.getpiper.dev
Re-running piper login converges instead of redoing work: a saved credential
skips the device flow, an already-enrolled box skips the claim (already enrolled as …), and a tunnel that's merely down gets re-verified. Flags shape
the claim:
--org <slug>— enroll the box for a GitHub org you own instead of your personal account.--no-enroll— stop after identity; leave this box's enrollment untouched (the laptop/remote-management shape, forced).--re-enroll— force a fresh claim on an already-enrolled box — recovery afterpiper box rm, or after switching accounts or relays.--relogin— authenticate again even though the saved credential still works, for signing in as a different GitHub account.--data-dir <path>— the piperd data directory to probe for the enrollment socket, when it isn't the default.
An operator who pins PIPER_RELAY_ADDR/PIPER_RELAY_TOKEN/PIPER_BASE_DOMAIN
in /etc/piper/piperd.env (or piperd's process environment) locks the
enrollment: piper login prints "this box's enrollment is operator-managed
via /etc/piper/piperd.env — nothing to do" and exits 0 rather than touching
it.
piper login --relay <url> targets a self-hosted relay instead of the default
https://api.public.getpiper.dev. Environment variables (PIPER_RELAY_ADDR,
PIPER_RELAY_TOKEN, PIPER_BASE_DOMAIN) still override relay.json.
## List and remove boxes
piper box ls # base domain, owner, connected
piper box rm ab12-alice.public.getpiper.dev --yes # frees the box slot
Removal frees the box slot for a fresh claim — piper login --re-enroll on
the box; a connected box must be stopped first (the relay refuses with a
conflict otherwise). The box's relay-assigned <hash>-<user>.<apex> app URL
stays reserved on the account, but any custom domains it held are released and
can be re-claimed elsewhere.
## Your own domain instead
Bring-your-own-domain apps stay end-to-end (the box terminates TLS; the relay
only splices SNI) — set PIPER_BASE_DOMAIN + cert/DNS config instead of
claiming through piper login; see Custom domains.
Add PIPER_SERVE=direct and the box serves :443 itself with no relay at all
(Direct serve).
A self-hosted relay (Run your own relay) runs passthrough-only when
PIPER_RELAY_TLS_CERT/KEY are unset.