nginx: serve mgmt /static/ assets from disk (no Flask round-trip)
Generated management-domain server blocks now include a location /static/ aliasing webui/static/ with Cache-Control: no-cache (ETag revalidation -> 304), nosniff, and a restrictive CSP, so SPA asset requests no longer reach Flask. Flask's static route remains the dev-mode fallback. - lib/nginx.py + daemon/handlers/nginx.py: static_root render context (the handler renders the template directly, so both paths need it) - template: alias uses a trailing slash (nginx concatenates the location remainder onto the alias value) - install.sh: a+rX on webui/static plus execute-up-the-parent-chain so the nginx worker (www-data) can traverse repo-in-$HOME installs - tests: mgmt static location assertions (positive + non-mgmt negative) - docs: AGENTS.md, architecture.md, security.md static-serving notes
This commit is contained in:
+1
-1
@@ -70,7 +70,7 @@ The `daemon/client.py` module resolves `<param>` placeholders in URL paths befor
|
||||
|
||||
### Management Interface
|
||||
|
||||
The Flask WebUI binds exclusively to `127.0.0.1:9090`. It is not exposed directly to any network interface. All external access to the management UI is routed through an nginx reverse proxy on the designated management domain, which provides SSL termination. Authentication is handled at the Flask layer via JWT validation — no nginx-level `auth_basic` is applied to the management domain.
|
||||
The Flask WebUI binds exclusively to `127.0.0.1:9090`. It is not exposed directly to any network interface. All external access to the management UI is routed through an nginx reverse proxy on the designated management domain, which provides SSL termination. Authentication is handled at the Flask layer via JWT validation — no nginx-level `auth_basic` is applied to the management domain. Static assets under `/static/` are served directly by nginx from `webui/static/` (unauthenticated, the same exposure as the Flask static route) with `Cache-Control: no-cache`, `X-Content-Type-Options: nosniff`, and a restrictive `Content-Security-Policy: default-src 'none'`.
|
||||
|
||||
JWT tokens are stored in browser `sessionStorage` and injected as `Authorization: Bearer <token>` headers. The API **never** reads cookies — authentication is header-only. This eliminates CSRF concerns: cross-origin requests cannot set custom headers.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user