Retire Local Web UI and Enforce Strict HTTP Basic Authentication¶
Status: Accepted (Amends ADR 0040 and ADR 0024)
We retire local Web UI hosting via convenience scripts and direct Uvicorn execution, consolidating the Sandbox Web Dashboard exclusively into the cloud-hosted Modal Control Plane (sandbox/function.py). We eliminate permissive authentication mode and enforce strict HTTP Basic Authentication for the Web UI, reserving Bearer token authentication exclusively for machine-to-machine API endpoints.
Context¶
In ADR 0024, the Sandbox Web Dashboard was introduced with dual hosting options:
1. Local execution via scripts/web_ui.py or uvicorn sandbox.web:app.
2. Cloud deployment via modal deploy sandbox/function.py.
Additionally, authentication in sandbox/web.py permitted unauthenticated access when credentials were not configured (permissive mode), and accepted MODAL_SANDBOX_AUTH_TOKEN interchangeably as either a Bearer token or as an HTTP Basic Auth password.
This dual-hosting and blended authentication model introduced several liabilities:
1. Redundant Local Serving Surface: Running the dashboard locally required maintaining local Uvicorn processes and CLI arg-parsing bloat in sandbox/web.py, duplicating functionality already provided by Modal's cloud ASGI app (modal serve / modal deploy).
2. Insecure Permissive Fallback: In environments without explicit authentication secrets, permissive mode left the Web UI and underlying sandbox management endpoints completely unprotected.
3. Overloaded Authentication Schemes: Allowing MODAL_SANDBOX_AUTH_TOKEN to unlock browser sessions blurred the boundary between interactive user interfaces and headless automated pipelines (POST /launch, POST /snapshot).
Decisions¶
- Retire Local Web UI Launcher & Uvicorn CLI Entrypoint:
- Delete
scripts/web_ui.py. - Remove
main()and CLI argument parsing fromsandbox/web.py. -
The Web UI is strictly served as an ASGI router mounted within the Modal Cloud application (
sandbox/function.py). Developers runmodal serve sandbox/function.pyfor interactive development ormodal deploy sandbox/function.pyfor hosted ingress. -
Strict HTTP Basic Authentication for Web UI (
sandbox/web.py): check_authenticationinsandbox/web.pyvalidates requests strictly againstWEB_UI_USERNAMEandWEB_UI_PASSWORDusing constant-time digest comparison (secrets.compare_digest).- All Bearer token logic and
MODAL_SANDBOX_AUTH_TOKENchecks are removed fromsandbox/web.py. - Permissive fallback is eliminated: if
WEB_UI_USERNAMEorWEB_UI_PASSWORDis unconfigured at runtime, the endpoint fails closed withHTTP 500 Internal Server Error. -
GET /favicon.icoandGET /healthremain accessible without credentials. -
Deploy & Serve-Time Credential Enforcement (
sandbox/function.py): - Top-level initialization in
sandbox/function.pyeagerly validates thatWEB_UI_USERNAMEandWEB_UI_PASSWORDexist inos.environor.env/secrets/.env. - If either required variable is missing during
modal deployormodal serve, execution aborts immediately with a descriptiveRuntimeError. MODAL_SANDBOX_AUTH_TOKENis retained strictly for headless machine-to-machine API routes (POST /launch,POST /snapshot) and is not enforced at Web UI deployment time.- Validation is bypassed under
pytestexecution to allow isolated unit testing.
Consequences¶
- The attack surface is hardened: no unauthenticated Web UI instances can be deployed or accessed.
- Code complexity is reduced by removing redundant local Uvicorn runners.
- Separation of concerns is restored: Web UI uses HTTP Basic Auth; headless machine-to-machine APIs use Bearer tokens.
- All code files strictly adhere to the universal 500 physical line budget ratchet (ADR 0027 / AGENTS.md).