# PufferPanel Panel/daemon are deployed rootlessly on Klops, with loopback health verified. Public HTTPS at `https://games.bugabinga.net` is deployed and returns HTTP 200 through the dedicated Unix ingress. Latest verified rollout is fork revision `b9bd1f7`, image `registry.bugabinga.net/pufferpanel:fork-b9bd1f7`, digest `sha256:72480e7645dfcf59f51306f77d08c32080f8ea7aebfcd528d397a5fae61b197a`. Vanilla Steam Valheim `valheim1` is deployed with public UDP 2456–2457 over IPv4 and IPv6, forwarding through WireGuard-only container bindings. Friend assignments and scheduled game-consistent encrypted backups remain pending implementation/deployment. Initial selection is Valheim, Minecraft Java, and vanilla Terraria, reachable with ordinary game clients. Game passwords/allowlists restrict play; public network reachability does not imply unrestricted game access. ## Public ingress `games.bugabinga.net` is configured for HTTPS ingress through public Caddy, a dedicated rootless Caddy gateway, and a Unix socket at `/data/pufferpanel-ingress/http.sock`. The gateway is HTTP-only on private `pufferpanel.network`, proxies all paths including WebSockets to `pufferpanel:8080`, preserves HTTPS forwarded-proto, has no TCP listener, admin endpoint, TLS state, Podman socket, credentials, or game-data mount. The panel remains bound to `127.0.0.1:8082`; SFTP remains unexposed. Deployment creates a `pufferpanel`-owned shared socket directory with narrow ACL access for the configured public Caddy user, persistent container SELinux labeling, then narrowly adds its read-only mount to Caddy's deployed Quadlet without replacing unrelated fields. Live checks confirm HTTP 200 from the proxy user over Unix and from public HTTPS, separate confined gateway/public-Caddy process labels, read-only public-Caddy socket mount, and continued loopback-only panel TCP binding. Both PufferPanel user units, Podman socket, and registry auto-update timer are active. Gateway/public-Caddy confinement does not establish panel confinement: the panel currently uses `--security-opt label=disable`. Caddy's `/data/sites` mount intentionally omits relabeling: CI-owned shared-label files otherwise prevent rootless restarts. ## Mail and registration `just generate pufferpanel-mail` provisions dedicated `games@bugabinga.net` mailbox through Mail-in-a-Box at SSH alias `box`. Private SMTP credentials reside in ignored `keys/pufferpanel-email.env`, mode 0600; never commit or publish them. Deployment transfers that file to `/home/pufferpanel/.config/pufferpanel-email.env` for Quadlet environment injection, without storing credential values in OpenTofu inputs/state. The Quadlet enables public self-registration; new accounts have login scope only. Email ownership is not verified, and failed welcome-email delivery does not prevent signup. Mailbox creation, TLS SMTP authentication/submission, and receipt in its inbox were verified independently of panel deployment. Native PufferPanel signup/email behavior still needs live verification. Owner administrator creation through the native CLI, public HTTPS password login, and administrator API access were verified. Generated owner credentials reside in ignored `keys/pufferpanel-owner.env`, mode 0600; never commit or publish them. Live owner-account WebAuthn remains unverified. ## Authentication verification The previous image omitted `Secure` from manually issued authentication cookies behind HTTP ingress, despite configured secure cookies. Released native fix honors configured Secure or direct TLS and emits actual logout-cookie deletion, preserving cookie scope, lifetime, and HttpOnly distinctions. Public HTTPS login and administrator API returned HTTP 200; both authentication cookies now carry `Secure`. Logout returned HTTP 204 with cookie deletion; replaying the old session returned HTTP 401. Only `pufferpanel.service` was restarted; gateway and public-Caddy container IDs/start times remained unchanged. Focused regressions fail against the old source; patched race tests pass ten repetitions. Full exact-tree release gate passed: frontend tests/lint/build, Ace byte verification, uncached normal/race Go suites, vet, and Actionlint. Verified candidate tree is `5367e7452888015904b8465e1343699626f4d47b`. Security commit `e85fd63558e272d6b5dbc783a7ac629e1073b065` is pushed to fork `origin/trunk`, so scheduled maintenance inherits the fix; no upstream submission was made. ## Initial game exposure profiles - Valheim Steam backend: UDP 2456–2457, shared password; optional platform-ID allowlist. - Minecraft Java: TCP 25565, `online-mode=true`, account-name/UUID allowlist. - Vanilla Terraria: TCP 7777, shared password. RCON/admin endpoints remain private; panel users do not control relay/firewall rules. Valheim Crossplay can instead use its relay backend; initial direct-port profile assumes Steam clients. Valheim's profile is deployed; Minecraft and Terraria remain researched profiles, not provisioned servers. Valheim remains private/unadvertised (`-public 0`); join through `games.bugabinga.net:2456`. Relay and Klops use measured tunnel MTU 1392, with relay TCP MSS caps 1352/1332 for IPv4/IPv6 across all forwarded services. Both-family HTTPS, SSH reachability, and full-size tunnel probes passed after this fix; sustained Valheim gameplay remains to be confirmed. Graceful-stop world and definition backup was taken before the binding migration; this does not replace scheduled offsite backups. Consistent offsite backups require validated graceful game shutdown/save handling, encryption, retention, and restore tests. Private EU-jurisdiction R2 bucket `bugabinga-games-backups` exists in account `4a54eb05dec2f951ea1746d9a0e944af`; public r2.dev access is disabled and no custom domain is attached. S3 endpoint is `https://4a54eb05dec2f951ea1746d9a0e944af.eu.r2.cloudflarestorage.com`. Encrypted Restic repository is initialized under the bucket's `pufferpanel/` prefix. Storage-only backup/dump round-trip and full `restic check --read-data` passed; game-consistent snapshots, schedule, retention, and game restore tests remain pending. Bucket-scoped account-token credentials and Restic password reside in ignored `keys/pufferpanel-backup.env`, mode 0600. The token grants object read/write only on this EU bucket; desktop OAuth credentials must never be copied to Klops. Preserve an independent recovery copy of the Restic password; losing it makes stored data unrecoverable. Provisioning used the mise-managed Cloudflare `cf` CLI with `account_api_tokens:create` and an additional `workers-r2.write` OAuth grant. Bucket-item-only OAuth grants returned `is_selectable: false`; adding that R2-management grant enabled delegation without broadening the resulting service token. Cloudflare skills and authenticated Pi MCP are installed globally; `/reload` loads their tools into an existing Pi session. ## Native branding `just nugu` generates `assets/pufferpanel/Nugu.tar` from external `dotfiles/nugu/pufferpanel.nu`, `services/pufferpanel/theme/`, and original `assets/bugabinga.min.svg`. The archive contains native PufferPanel `manifest.json`, `theme.css`, and original logo. Palette values are generated, not hand-authored in deployment assets. The Quadlet selects `Nugu`, sets company name to `bugabinga Games`, and mounts `/data/pufferpanel/theme` read-only at native web theme directory. Deployment uploads the archive; its hash triggers redeployment when branding changes. No PufferPanel application source or compiled frontend modification is needed. Light/dark palettes support OS auto mode and explicit overrides. Upstream CSS retains layout, high-contrast mode, font accessibility controls, and responsive behavior. Logo CSS uses a generated `image/svg+xml` data URI because native tar-loaded asset blobs lack SVG MIME metadata. The SVG bytes remain identical to original asset. `services/pufferpanel/test-branding.sh` validates archive contents, mode controls, and logo identity. `services/pufferpanel/test-deploy.sh` validates rendered panel and ingress Quadlet contracts plus gateway Caddy adaptation. `bash services/pufferpanel/test-ingress-runtime.sh NEW_OS_TEMP_DIRECTORY` verifies stock Caddy's required rootless capability, private-network DNS, Unix HTTP, forwarded HTTPS, host filtering, read-only root, and exact gateway mount count. It uses isolated Podman storage, stops its containers, and retains test evidence in the supplied new OS temporary directory. Cross-user ACL/SELinux access was verified live on Klops through public HTTPS with both gateway and public Caddy confined. Local browser proof covers login page at desktop/mobile widths with both auto schemes and explicit overrides. Browser proof does not establish game runtime compatibility or owner-account WebAuthn login; live deployment is independently verified above.