Skip to content
This repository was archived by the owner on Sep 12, 2026. It is now read-only.

feat: Signed-cookie auth gate for the /panel/dash reverse proxy - #21

Merged
mabry1985 merged 2 commits into
mainfrom
feat/bd-weta-signed-cookie-auth-gate-for-the-panel-da
Aug 28, 2026
Merged

mabry1985 merged 2 commits into
mainfrom
feat/bd-weta-signed-cookie-auth-gate-for-the-panel-da

Conversation

@mabry1985

Copy link
Copy Markdown
Member

Summary

Adds a short-lived signed-cookie auth gate so the interactive browser panel's full-mode dashboard proxy (/panel/dash + its CDP screencast WebSocket surface) can't be reached unauthenticated on token-gated deployments — the iframe that loads it cannot carry an Authorization bearer.

  • Mint routePOST /api/plugins/agent_browser/dash-session (under /api, so it inherits the host's operator-bearer gate) issues an ab_session cookie: HttpOnly, SameSite=Strict, path-scoped to /plugins/agent_browser/, Max-Age=300 (~5 min), and Secure when the origin (or X-Forwarded-Proto) is HTTPS. The value is an HMAC-signed <expiry>.<sig> token.
  • Proxy gateGET /panel/dash validates the cookie (constant-time HMAC + expiry) and returns 401 on a missing / tampered / expired cookie when the deployment is token-gated (require_auth config flag, set by the same host that applies the bearer gate). Non-token-gated deployments serve openly, unchanged — backward compatible.
  • Signing key — per-boot secrets.token_bytes(32), in-memory only; cookies can't outlive a restart and there's no key at rest to steal.
  • Client — the panel POSTs dash-session via kit.apiFetch (carrying the bearer) inside connect(), before the stream handshake, so the cookie is set before the proxied surface is reached.

Tests cover the token round-trip/expiry/tamper cases, cookie attributes (HttpOnly / SameSite / path / Max-Age / Secure-on-HTTPS-and-XFP), the gated 401 paths, the valid-cookie 200 path, the non-gated backward-compatible path, and the client-side mint-before-connect wiring.

Fixes #9

mabry1985 and others added 2 commits August 28, 2026 02:04
The full-mode dashboard proxy (/panel/dash + CDP screencast WS) loads in an
iframe, which cannot carry an Authorization bearer — so on token-gated
deployments it was reachable unauthenticated. Add a short-lived HMAC-signed
ab_session cookie: a bearer-gated POST /dash-session mints it, and the
/panel/dash proxy rejects a missing/tampered/expired cookie with 401. The
signing key is per-boot + in-memory only. Non-token-gated deployments stay
open (backward compatible).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…= exchange on /panel/dash)

The review confirmed browsers drop a Path=/plugins/agent_browser/ cookie set
from the POST /api/plugins/agent_browser/dash-session response — RFC 6265
path-matching requires the Set-Cookie URL to match the cookie Path, so
token-gated deployments never retained the cookie and /panel/dash always 401'd.

The bearer-gated POST now returns the signed token in the body; GET
/panel/dash?dash=<token> exchanges it for the ab_session cookie, set from the
proxy's own URL (path-matches by construction) with the Path derived from the
request path so it also survives the fleet-proxy /agents/<slug> prefix. The
panel's ensureDashSession() does mint → exchange before the WS connect.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@mabry1985
mabry1985 merged commit 3c44881 into main Aug 28, 2026
1 check passed
@mabry1985
mabry1985 deleted the feat/bd-weta-signed-cookie-auth-gate-for-the-panel-da branch August 28, 2026 09:13

@protoreview protoreview Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QA panel review — PASS

code-review-structural · head 0f1902dfad92 · formal

⚠️ PR advanced 1 commit(s) during this round (0f1902dfad92b7f39fafd5db); 0 finding(s) in the delta were demoted to possibly addressed.

No code defects were identified by any review-finder on this PR. The one material concern is a process gap: the structural (security) pass failed to run, so the panel's "clean" verdict carries a known blind spot. Before merging, retry the structural pass so the security lane is actually covered. No findings to re-rank, dedup, or drop; the verifier confirmed the empty array is correct.

No findings — the review came back clean.

findings JSON (machine-readable)
[]

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

The /panel/dash reverse proxy is unauthenticated by necessity — needs a designed gate

1 participant