buttons agent gives a workspace a durable, cryptographically-provable identity and a stable public URL. It’s how a machine enrolls with a hosted registry and how a drawer gets a webhook address the outside world can reach.
Identity is proven by signature, not asserted: the device holds an Ed25519 keypair, and the registry verifies requests against the public key it saw at enrollment.
The device keypair
On first use, Buttons generates an Ed25519 keypair and stores it inagent.json in the active data directory (~/.buttons/agent.json, or .buttons/agent.json in a project), written 0600.
- The private seed never leaves the machine — only signatures and the public key are sent.
agent.jsonalso holds the registeredslug, the backing tunnel id, and (if the broker provisioned one) a tunnel run-token.- Because it holds the private seed and run-token,
agent.jsonis machine-local and must never be committed.buttons initadds it to.buttons/.gitignoreautomatically.
Registry target and enrollment token
Two environment inputs drive setup — this public repo bakes in no registry host:| Input | Purpose |
|---|---|
$BUTTONS_REGISTRY_URL | Base URL of the registry the agent enrolls with. Required. |
ENROLL_TOKEN battery (or $BUTTONS_BAT_ENROLL_TOKEN) | One-time enrollment token, consumed the first time a device binds. |
buttons agent setup <slug>
One idempotent command sets everything up. It generates the device key on first use, enrolls with the ENROLL_TOKEN if the device isn’t bound yet, registers the slug, and prints the resulting URLs. Safe to re-run — it re-points to the current tunnel.
slug must be a single DNS label: lowercase letters, digits, and hyphens, starting alphanumeric, max 63 characters.
Choosing the tunnel — --tunnel is optional. When omitted, the tunnel is resolved in order:
- the tunnel from a configured named webhook setup (
buttons webhook setup), then - this agent’s previously provisioned tunnel (stored in
agent.json), then - if there’s still none, the broker provisions one and returns a run-token, which is saved to
agent.json.
--principal optionally records the principal this agent serves.
buttons agent status
Shows the device’s identity — never any secret:
not set up. In --json mode it returns { "enrolled": false } or { "enrolled": true, "device_id": "…", "slug": "…" }.
How it relates to the registry
Agent identity is the trust anchor under the registry. The registry authorizes reads and writes with theREGISTRY_KEY / REGISTRY_WRITE_KEY batteries (bearer keys), while the agent’s Ed25519 signature proves which device is acting — the two are complementary. Enroll once with buttons agent setup, then buttons add / buttons install / buttons publish against $BUTTONS_REGISTRY_URL.
Related
- Registry — install and publish shared packages
- Webhooks — the tunnel and public URL a drawer is reached at
- buttons agent — CLI reference
- buttons agent setup
- buttons agent status