2.7 KiB
Endpoint Monitor service contract
Resources and lifecycle
A monitor has an immutable UUID, name, HTTP(S) url, timestamps, and a current
check snapshot. New and URL-updated monitors are unknown. State is process-local
memory, protected by one async lock, and is lost on restart. Multiple workers do not
share state. No authentication is provided; deploy behind an authenticated gateway.
HTTP API
| Method and path | Success | Notes |
|---|---|---|
POST /monitors |
201 | Create; duplicate names are allowed |
GET /monitors |
200 | Stable creation-order list |
GET /monitors/{id} |
200 | Retrieve |
PUT /monitors/{id} |
200 | Full update |
DELETE /monitors/{id} |
204 | Delete |
POST /monitors/{id}/check |
200 | Run one bounded check and atomically publish it |
GET /monitors/{id}/status |
200 | Current snapshot; no network call |
GET /health/live |
200 | Process is serving HTTP |
GET /health/ready |
200 | Configuration and in-memory store are available |
Missing monitor IDs return 404 {"detail":"monitor not found"}. Validation failures
use FastAPI's 422 response. A check transport failure is a successful invocation and
returns a snapshot with error; an unsafe target returns blocked. These are not API
5xx responses because the service completed the requested check.
Status semantics
unknown means never checked or URL changed. up means final status 200-399 after
safe redirects. down means final status 400-599. error means timeout, DNS failure,
or HTTP transport failure. blocked means SSRF policy rejected a host/address or
redirect. Snapshots contain completion time, latency in milliseconds, optional HTTP
status, and a bounded non-sensitive error code.
Check security and consistency
Only HTTP(S), no URL credentials, and a non-empty hostname are accepted. Every hop is resolved before I/O; every resolved address must be globally routable. Redirects are followed manually and revalidated, with a configured maximum. Timeouts and redirect counts are bounded. The store uses a revision compare-and-set so a result from an old URL cannot overwrite a concurrent update. This DNS preflight mitigates ordinary SSRF; deployments requiring protection from DNS rebinding should also enforce egress policy at the network layer.
Logs are JSON and include monitor ID, outcome, latency, and a URL with credentials, query, and fragment removed. Raw exception text and redirect locations are never logged.
Layout
app/ contains settings, models, locked store, SSRF validation, checker, logging, and
FastAPI composition. tests/ contains API/unit security tests. Packaging is in
pyproject.toml, Dockerfile, and compose.yaml; operational evidence is in
VERIFICATION.md.