Per-User Deployment: Loopback Auth
This guide covers the per-user deployment mode where kaged runs under the operator's UID on their workstation or laptop. Authentication uses a cookie-nonce mechanism — no OAuth sidecar required.
This is the simplest deployment and the recommended starting point.
Architecture
operator browser
│
▼ http://127.0.0.1:7777
kaged daemon (loopback, cookie-nonce auth)
The OS user boundary provides isolation. The cookie nonce gates access to the daemon. Anyone who can reach the loopback port without the cookie gets a 401.
Prerequisites
- Linux or macOS workstation
- Bun runtime installed
- kaged binary in
$PATH(or at~/.local/bin/kaged)
Step 1: First launch
Run the daemon:
kaged start
On first launch, kaged:
- Creates
~/.config/kaged/config.tomlwith per-user defaults - Generates a per-startup nonce and writes it to
$XDG_RUNTIME_DIR/kaged/auth-cookie - Prints a launch URL to stderr:
kaged: ready — launch URL: http://127.0.0.1:7777/launch?token=a1b2c3d4...
Step 2: Open the launch URL
Open the URL in a browser. This:
- Validates the one-time token against the nonce
- Sets a session cookie (
kaged_session) - Redirects to
/— the kaged UI
The cookie persists across browser restarts. You only need the launch URL once per daemon startup.
Step 3: Install as a user service (optional)
For the daemon to run in the background and survive logouts:
mkdir -p ~/.config/systemd/user
cp examples/deployment/systemd-user/kaged.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now kaged
# Run when logged out:
loginctl enable-linger "$USER"
After enabling, get the launch URL:
kaged auth open
This prints the URL and attempts to open it in the default browser.
Configuration
The per-user config at ~/.config/kaged/config.toml:
[daemon]
bind = "127.0.0.1:7777"
home = "/home/operator/.local/share/kaged"
[auth]
mode = "secure" # cookie-nonce auth
[storage]
url = "sqlite:///home/operator/.local/share/kaged/kaged.db"
[sandbox]
mode = "enabled"
[logging]
operational = "stderr"
level = "info"
[ui]
serve = true
Managing auth
| Command | What it does |
|---|---|
kaged auth nonce |
Print the current auth nonce (for scripting) |
kaged auth open |
Print and open the launch URL in a browser |
Exposing to other devices
Per-user mode binds to loopback by default. To access kaged from other devices on the same network (phone, tablet), you have two options:
Option A: Tailscale / WireGuard (recommended)
Run a VPN that puts your devices on the same virtual network, then bind to the Tailscale IP:
kaged start --bind 100.x.y.z:7777
The cookie-nonce auth still applies — devices need the launch URL.
Option B: Behind a tunnel + sidecar
Follow the system-wide deployment guide, but run the per-user daemon instead. Set auth.mode = "sidecar" in config to switch from cookie-nonce to header validation.
Troubleshooting
"401 unauthenticated" after opening launch URL: The token is one-use. If the browser refreshes or redirects fail, generate a new one with kaged auth open.
Daemon won't start — "address already in use": Another process is using the port. Change it with --bind 127.0.0.1:OTHER_PORT or in config.
Cookie lost after browser clear: Run kaged auth open again to get a fresh launch URL.