feat(webui): auth and deployment boundary (#435)
Add bind-host assessment that refuses 0.0.0.0/:: without override, warns on non-loopback binds, and documents internal-only MVP serving. Health endpoint exposes deployment metadata; docs cover Access/VPN/WARP and runtime env assumptions without embedding secrets in the client. Closes #435
This commit is contained in:
+11
-3
@@ -9,6 +9,7 @@ from starlette.requests import Request
|
||||
from starlette.responses import HTMLResponse, JSONResponse, Response
|
||||
from starlette.routing import Route
|
||||
|
||||
from webui.deployment_boundary import deployment_snapshot
|
||||
from webui.layout import render_page
|
||||
from webui.project_registry import find_project, load_registry, registry_to_dict
|
||||
from webui.project_views import render_project_detail, render_projects_list
|
||||
@@ -47,11 +48,13 @@ async def home(_request: Request) -> HTMLResponse:
|
||||
|
||||
|
||||
async def health(_request: Request) -> JSONResponse:
|
||||
bind_host = _request.app.state.webui_bind_host
|
||||
return JSONResponse({
|
||||
"status": "ok",
|
||||
"service": "mcp-control-plane-webui",
|
||||
"mode": "read-only-mvp",
|
||||
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||
"deployment": deployment_snapshot(bind_host=bind_host),
|
||||
})
|
||||
|
||||
|
||||
@@ -156,9 +159,12 @@ async def method_not_allowed(request: Request, _exc: Exception) -> Response:
|
||||
return JSONResponse({"error": "not_found"}, status_code=404)
|
||||
|
||||
|
||||
def create_app() -> Starlette:
|
||||
def create_app(*, bind_host: str | None = None) -> Starlette:
|
||||
"""Build the read-only MVP Starlette app."""
|
||||
return Starlette(
|
||||
import os
|
||||
|
||||
resolved_bind = bind_host or os.environ.get("WEBUI_HOST", "127.0.0.1")
|
||||
app = Starlette(
|
||||
debug=False,
|
||||
routes=[
|
||||
Route("/", home, methods=["GET"]),
|
||||
@@ -177,4 +183,6 @@ def create_app() -> Starlette:
|
||||
Route("/leases", leases, methods=["GET"]),
|
||||
],
|
||||
exception_handlers={405: method_not_allowed},
|
||||
)
|
||||
)
|
||||
app.state.webui_bind_host = resolved_bind
|
||||
return app
|
||||
Reference in New Issue
Block a user