dcec519565
CI / Check (pull_request) Successful in 8m12s
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
Symptom: "unable to load repositories" — agent returns
"Missing authorization header" 401 on every protected endpoint
because the dashboard's server functions were calling reqwest::get
without an Authorization header. The Keycloak OIDC flow
(auth_login / auth_callback) was already wired up and storing the
access_token in tower-sessions, but the access_token was never
threaded into outbound calls.
Fix
- New `infrastructure::agent_client` module exposes:
- `agent_request(method, path) -> RequestBuilder`
- `agent_get(path) -> RequestBuilder` (sugar for GET)
Both pull the session's access_token (via FullstackContext extract)
and attach `Authorization: Bearer <token>`. When Keycloak is not
configured the helper short-circuits — matching the dashboard's
require_auth middleware which short-circuits in the same state.
- Migrated every #[server] function in:
- chat, dast, findings, graph, issues, notifications, pentest,
repositories, sbom, scans, stats
- 57 call sites total, all replaced.
- Left as-is:
- `infrastructure::server::webhook_proxy` — forwards to the agent's
separate webhook server (port 3002), which is HMAC-authenticated,
not JWT-authenticated.
- `infrastructure::auth::auth_callback` — performs the KC token
exchange itself; bearer auth would be circular.
Test plan
- cargo fmt --all clean
- cargo clippy -p compliance-dashboard --features server -- -D warnings
clean
- cargo check -p compliance-dashboard --features server clean
- cargo check -p compliance-dashboard (web target) implicit via build
- Manual: after deploy, dashboard's repositories page loads without
401; calls now carry Authorization: Bearer header to the agent.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>