Skip to content

ADR-024 — AoE web dashboard via Caddy + oauth2-proxy (Option B)

Date: 2026-05-28 (placeholder; not yet implemented) Status: Proposed Related: ADR-023 · ADR-022 · ADR-008

Placeholder. ADR-023 deferred Option B — the aoe serve web dashboard exposed via the existing Caddy + oauth2-proxy + PocketID stack — to a follow-up ADR. This file holds the shape of that future decision so it isn't lost; flesh it out when the work actually starts.

Context

Per ADR-023:

  • Option A (Claude Code Remote Control via claude.ai/code, outbound-HTTPS only) is the initial access path for untrusted hardware. Validated and shipped via agents.yml.
  • Option B — AoE's own web dashboard, exposed under aoe.eva-00.network behind the existing Caddy → oauth2-proxy → PocketID stack — was explicitly deferred because it adds externally reachable surface and auth plumbing that deserves its own diff after Option A is proven in production.

This ADR records the Option B follow-up when the work happens.

What this ADR will need to decide

  • The AoE listen port and bind address on agents-lxc (TBD until aoe serve is run there).
  • Caddy vhost shape — should mirror dev.eva-00.network:
    aoe.eva-00.network {
        reverse_proxy 192.168.1.135:<oauth2-proxy port>
    }
    
  • oauth2-proxy upstream config (a new entry in chizuru-v2/services/external-proxies/).
  • PocketID OAuth provider entry — client ID, client secret, redirect URI https://aoe.eva-00.network/oauth2/callback.
  • Vault entries for the oauth2-proxy client / cookie secrets, scoped to the agents-lxc Vault role (separate from dev-LXC's secrets, per ADR-023).
  • Second Glance entry under the Dev category: https://aoe.eva-00.network (icon TBD).
  • A systemd unit on agents-lxc for aoe serve, mirroring claude-remote-control.service.j2's patterns: hardening, After=network-online.target, OnFailure=ntfy-alert@%n.service, StartLimitIntervalSec=15min/StartLimitBurst=5.
  • Whether and how to manage Caddy/PocketID idempotency from Ansible — the Caddyfile is a single shared file, oauth2-proxy provider entries are config-driven.

IaC changes when this lands

File Change
chizuru-v2/ansible/playbooks/agents.yml Add a section that renders and deploys aoe-serve.service
chizuru-v2/services/agents/aoe-serve.service.j2 New — systemd unit template for the AoE web daemon (mirror claude-remote-control.service.j2)
chizuru-v2/services/caddy/Caddyfile Add aoe.eva-00.network { reverse_proxy 192.168.1.135:<port> }
chizuru-v2/services/external-proxies/docker-compose.yml (or per-vhost config) Add the AoE oauth2-proxy upstream
Vault New path (e.g. secret/agents-aoe) — pocketid_client_id, pocketid_client_secret, oauth2_cookie_secret. Add via the same pattern as secret/code-server-dev.
PocketID New provider entry; document the redirect URI
chizuru-v2/services/glance/glance.yml Add second link under Dev: title: AoE, url: https://aoe.eva-00.network

Decision

(To be filled in when the implementation work starts.)

Consequences

(To be filled in when the implementation work starts. Expect: adds one externally reachable surface, brings AoE's full multi-session view into a browser, doubles the auth-plumbing surface, requires the agents-lxc Vault role from ADR-023 to actually be provisioned first.)

When to revisit

  • Option A's claude remote-control workflow is stable in production for at least a week of regular use, and
  • Milton finds himself wanting AoE's full multi-session TUI (not just a single Claude session) from a browser, or a non-browser-restricted fallback to claude.ai.

Until either condition is met, this ADR stays in Proposed/placeholder state.