Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@
- [ ] **Add a "How It Actually Works" tutorial**
- Walk through a single evolution cycle step by step with real logs
- Lower the barrier for new contributors
- [ ] **Improve API reference**
- [x] **Improve API reference** _(done 2026-07-31)_
- Ensure all public classes/functions have docstrings
- Auto-generate API docs (MkDocs + mkdocstrings)

Expand Down
28 changes: 18 additions & 10 deletions docs/API_REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,22 +307,30 @@ WebSocket connections handle errors gracefully:

## Authentication

### Current Implementation
- No authentication required (local access only)
- Dashboard only accessible on localhost interface
### Bearer Token (Optional)

When the dashboard is constructed with `auth_token`, all `/api/*` and `/ws` requests must
present a valid token:

- **HTTP**: `Authorization: Bearer <token>` header
- **WebSocket**: `?token=<value>` query parameter

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

rg -n -C 12 'def _auth_middleware|Authorization|bearer\.|query.*token|WebSocket' evoseal/services/monitoring_dashboard.py

Repository: SHA888/EVOSEAL

Length of output: 14684


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== API_REFERENCE WebSocket lines =="
sed -n '300,325p' docs/API_REFERENCE.md

echo
echo "== auth/websocket tests mentioning dashboard websocket =="
git ls-files | rg '(test|tests|spec)' | xargs -r rg -n -i 'monitoring_dashboard|MonitoringDashboard|websocket|Bearer|bearer\.|Sec-WebSocket-Protocol|auth_token|query.*token' || true

echo
echo "== static verifier for supported WebSocket auth branches and docs token phrasing =="
python3 - <<'PY'
from pathlib import Path
import re

service = Path("evoseal/services/monitoring_dashboard.py").read_text()
md = Path("docs/API_REFERENCE.md").read_text()

auth = service[service.find("async def _auth_middleware"):service.find("    `@staticmethod`", service.find("async def _auth_middleware"))]
ws_handler = service[service.find("async def websocket_handler"):service.find("    async def _get_current_metrics", service.find("async def websocket_handler"))]
dashboard_js = service[service.find("    async def dashboard_page"):service.find("        return \"\"\"", service.find("    async def __call__", service.find("    async def dashboard_page")))]

checks = {
    "middleware_checks Authorization bearer": "Authorization" in auth and "Bearer {self.auth_token}" in auth,
    "middleware checks Sec-WebSocket-Protocol bearer": "Sec-WebSocket-Protocol" in auth and 'proto.startswith("bearer.")' in auth,
    "middleware checks query token": "request.query.get(\"token\", \"\")" in auth,
    "route /ws added": 'self.app.router.add_get("/ws", self.websocket_handler)' in service,
    "handler selects Sec-WebSocket-Protocol bearer": "Sec-WebSocket-Protocol" in ws_handler and 'proto.startswith("bearer.")' in ws_handler,
    "js uses bearer subprotocol": re.search(r"WebSocket\(wsUrl,\s*authToken\s*\?\s*\['bearer\.\'\s*\+\s*authToken\s*\]\s*:\s*undefined\)", service) is not None,
    "js comment says header not URL/logs": "Sec-WebSocket-Protocol" in dashboard_js and "access logs" in dashboard_js,
    "docs line says ?token=<value>": "?token=<value>" in md,
}
for name, ok in checks.items():
    print(f"{name}: {ok}")

# Extract exact documentation line around dashboard API token.
for i, line in enumerate(md.splitlines(), 1):
    if "?token=" in line or "WebSocket" in line and "token" in line:
        pos = line.find("WebSocket")
        print(f"doc_hit_{i}: {line[pos:pos+80] if pos!=-1 else line}")
PY

Repository: SHA888/EVOSEAL

Length of output: 8553


Document the supported WebSocket auth transport correctly.

doc/API_REFERENCE.md:316 currently says only ?token=<value>, but evoseal/services/monitoring_dashboard.py supports Sec-WebSocket-Protocol: bearer.<token> as the header-based handshake path and the embedded dashboard JS uses that path. Update the API reference to list the supported WebSocket mechanisms and avoid making ?token=<value> look like the only or preferred option.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/API_REFERENCE.md` at line 316, Update the WebSocket authentication entry
in API_REFERENCE.md to document both the token query parameter and the
Sec-WebSocket-Protocol bearer.<token> handshake mechanism supported by
monitoring_dashboard.py. Present them as supported alternatives without implying
that ?token=<value> is the sole or preferred transport.

- The dashboard HTML page (`/`) is not gated by auth.

When `auth_token` is `None` (the default), no authentication is enforced.

### Security Considerations
- Dashboard binds only to localhost (127.0.0.1)
- No external network access
- Dashboard defaults to localhost (127.0.0.1) binding

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Use the actual default host value.

MonitoringDashboard.__init__ defaults host to "localhost", not the literal "127.0.0.1". Replace the parenthetical unless the binding implementation guarantees IPv4 loopback resolution. This avoids misleading operators on systems where localhost resolves to ::1.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/API_REFERENCE.md` at line 322, Update the Dashboard default-host
documentation to reflect that MonitoringDashboard.__init__ uses "localhost"
rather than asserting the literal IPv4 address 127.0.0.1, unless the binding
implementation explicitly guarantees IPv4 loopback resolution.

- Binding to `0.0.0.0` logs a security warning — ensure `auth_token` is set or restrict
access via firewall when exposing externally
- Runs as user service (no root privileges)

## CORS Configuration

Cross-Origin Resource Sharing (CORS) is configured to allow:
- **Origins**: All origins (`*`)
- **Methods**: All methods
- **Headers**: All headers
- **Credentials**: Allowed
Cross-Origin Resource Sharing (CORS) is configured as follows:

- **Origins**: Defaults to the dashboard's own `host:port` (not `*`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Document the wildcard-bind CORS exception.

evoseal/services/monitoring_dashboard.py:54-138 sets the default origin to http://localhost:<port> when host is 0.0.0.0 or ::. It does not use the wildcard host value as the default origin.

Proposed wording
-- **Origins**: Defaults to the dashboard's own `host:port` (not `*`)
+- **Origins**: Defaults to the dashboard origin; for `0.0.0.0` or `::`, defaults to `http://localhost:<port>` (not `*`)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **Origins**: Defaults to the dashboard's own `host:port` (not `*`)
- **Origins**: Defaults to the dashboard origin; for `0.0.0.0` or `::`, defaults to `http://localhost:<port>` (not `*`)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/API_REFERENCE.md` at line 331, Update the Origins documentation to state
that when the dashboard binds to wildcard hosts 0.0.0.0 or ::, the default CORS
origin is http://localhost:<port>; otherwise it uses the dashboard host and
port, never the wildcard bind address itself.

- Wildcard `*` origins explicitly disable `allow_credentials` per the CORS specification
- Methods and headers are unrestricted for allowed origins

## Usage Examples

Expand Down
Loading
Loading