Skip to content

Upgrade Guide: v0.7.3 to v0.7.4

v0.7.4 finishes the local-first / zero-plaintext-secure direction of the 0.7 line. The headline auth.mode: open | secure is unchanged, but the network surface is simplified and the default posture is now local-only:

  • One listener per mode. internal_http_port is removed; the credential bus and the Connect tunnel ride the single listener (pinned TLS in secure mode, plain HTTP in open), gated by the credentials scope. Secure mode now has no plaintext anywhere.
  • One bind knob, loopback by default. http_bind/ssh_bind are unified into a single bind_address that governs every listener and defaults to loopback (127.0.0.1) in both modes — shed is a local-development tool unless explicitly exposed.
  • http_port is optional in secure mode (it serves no plain HTTP).

A breaking patch

Like v0.7.1/v0.7.2, this is a 0.7.x patch that carries breaking config changes — the auth/network interface is still settling in the 0.7 line. The biggest behavior change is the loopback default: a server that relied on the old all-interfaces default becomes local-only after upgrade until you set bind_address. If you reach your server from another machine, read the pre-upgrade checklist below first.

What changed

  • internal_http_port removed. The optional loopback-only listener that carried the credential bus + Connect tunnel is gone. Both now ride the single listener (TLS in secure mode, plain HTTP in open), gated by the credentials scope in secure mode. A co-located host-agent reaches the bus at https://127.0.0.1:8443 with the pinned cert. Bonus: remote shed forward works uniformly again (the old split forced the Connect tunnel to loopback).
  • http_bind + ssh_bindbind_address. One interface for every listener (HTTP, HTTPS, SSH). It defaults to loopback (127.0.0.1) in both open and secure mode. Set a routable address (0.0.0.0/* for all IPv4, :: for all interfaces, or a specific LAN/tailnet IP) to reach the server off-box. In open mode a non-loopback bind also requires allow_insecure_exposure: true (open mode has no transport security); secure mode needs no acknowledgment.
  • http_port optional. Secure mode serves no plain HTTP, so http_port is no longer required there and is omitted from /api/info and the written client config entry. Open mode still requires it.

Pre-upgrade checklist (do this first if your server is networked)

Because the default flipped to loopback, before upgrading a server you reach from other machines, set bind_address so it stays reachable. Pick a posture:

  • Recommended — secure mode (pinned TLS + tokens + SSH allowlist):
    auth:
      mode: secure
      ssh:
        github_users: [your-github-username]
    bind_address: 0.0.0.0          # or a specific LAN/tailnet IP
    
  • Open on a trusted private network (plaintext — Tailscale / LAN only):
    bind_address: 0.0.0.0          # or a specific LAN/tailnet IP
    allow_insecure_exposure: true
    

A purely local server (used only on the same machine) needs no change — loopback is the new default.

Breaking: removed/renamed config now hard-fails

Rejected at startup (the server names the gap and exits). Edit your server config before upgrading an affected host, or it will fail to restart:

v0.7.3 (now removed / renamed) v0.7.4 replacement
internal_http_port: <n> Remove it — the bus + Connect ride the single listener (credentials scope). For an off-network bus, bind the whole secure server to loopback.
http_bind: <addr> bind_address: <addr> (one interface for all listeners).
ssh_bind: <addr> bind_address: <addr> (HTTP and SSH now share one interface).

And a silent behavior change (the config still validates, but changes meaning):

Was (v0.7.3) Now (v0.7.4)
unset bind → all interfaces unset bind_addressloopback only

Copy-paste migrations

Remote open server (Tailscale / LAN) — before → after:

# v0.7.3
http_bind: 0.0.0.0
ssh_bind: 0.0.0.0
# v0.7.4
bind_address: 0.0.0.0
allow_insecure_exposure: true   # open mode has no TLS; acknowledge LAN exposure

Remote secure server (VPS) — before → after:

# v0.7.3 (bound all interfaces by default)
auth: { mode: secure, ssh: { github_users: [charliek] } }
tls_names: [shed.example.com]
# v0.7.4 — secure mode now defaults to loopback too, so set bind_address
auth: { mode: secure, ssh: { github_users: [charliek] } }
tls_names: [shed.example.com]
bind_address: 0.0.0.0

Co-located host-agent (was the internal_http_port "Case 4") — before → after:

# v0.7.3
auth: { mode: secure, ssh: { github_users: [charliek] } }
internal_http_port: 8081
# v0.7.4 — the bus rides the pinned-TLS listener (credentials scope); the
# co-located agent reaches it at https://127.0.0.1:8443 with the pinned cert.
auth: { mode: secure, ssh: { github_users: [charliek] } }
bind_address: 0.0.0.0

Locked out? (upgraded a remote server without reading this)

If you upgraded a networked server and can no longer reach it, the daemon is now bound to loopback. Recover from the host console (or a local shell on the box):

  1. Edit /etc/shed/server.yaml (deb) or $(brew --prefix)/etc/shed/server.yaml (brew).
  2. Add bind_address: 0.0.0.0 (and allow_insecure_exposure: true if open mode — or, preferably, switch to auth.mode: secure).
  3. Restart: sudo systemctl restart shed-server (deb) or brew services restart shed (brew).

Clients

Clients are unaffected. shed server add … --https-port 8443 (or --secure, or the auto-fallback) and the auto-minted, auto-refreshing tokens work exactly as in v0.7.3. A secure server's ~/.shed/config.yaml entry simply no longer carries a vestigial http_port.

See Security and Security Configuration for the full model, and Public VPS Deployment for the end-to-end secure flow.