3.2 KiB
Endpoint Monitor service contract
Scope and lifecycle
This is a single-process FastAPI service with an asynchronous, lock-protected in-memory repository. Data is lost at process exit and is neither shared nor replicated between workers; production deployments must therefore use exactly one worker. There is no authentication.
Resource and routes
A monitor has id (UUID), name, HTTP(S) url, creation/update timestamps, and a current check status. Status starts as unknown. up means the last response was HTTP 200–399, down means HTTP 400–599, and error means no usable HTTP response (timeout, network/protocol failure, redirect-policy failure, or blocked target).
| Method | Route | Meaning |
|---|---|---|
| POST | /v1/monitors |
Create; 201 |
| GET | /v1/monitors |
List; 200 |
| GET | /v1/monitors/{id} |
Retrieve; 200 |
| PATCH | /v1/monitors/{id} |
Update name and/or URL; 200 |
| DELETE | /v1/monitors/{id} |
Delete; 204 |
| POST | /v1/monitors/{id}/checks |
Run one bounded check; 200, or 400 for an unsafe target |
| GET | /v1/monitors/{id}/status |
Retrieve current status; 200 |
| GET | /healthz |
Liveness; 200 |
| GET | /readyz |
Readiness of process-local dependencies; 200 |
Missing resources return 404 with {"detail":{"code":"monitor_not_found","message":"Monitor not found"}}. Validation uses FastAPI's 422 response. Unsafe initial targets and unsafe redirect destinations return 400 with code unsafe_target; the monitor records error. Endpoint timeouts and transport failures are check outcomes, not service failures, and return a typed error result.
Check and concurrency semantics
Checks use configured total timeout, response-byte and redirect limits. Every initial target and redirect is HTTP(S), has no user information, and has all DNS answers checked; loopback, private, link-local, multicast, reserved, unspecified, and otherwise non-global addresses are blocked. Redirects are followed manually and revalidated. DNS validation materially reduces SSRF exposure, but this application-level approach cannot fully remove DNS time-of-check/time-of-use rebinding risk in the underlying client; a production egress proxy/firewall is required for a hard network boundary.
Repository operations are serialized with asyncio.Lock. A check captures the monitor revision before I/O. Its status update is a compare-and-set and is discarded if the monitor was updated or deleted while I/O was in flight, preventing stale results from overwriting newer state. Latency is monotonic elapsed time for the complete redirect chain.
Logging and configuration
Logs are one-line JSON. URLs are emitted without user information and with query/fragment replaced by redaction markers. Bodies and request headers are never logged. Environment settings use the MONITOR_ prefix and are validated at startup; see README. Secrets in URL query strings are not persisted in logs, although the monitor resource itself necessarily stores the configured URL.
Project structure
app/ contains settings, schemas, lock-protected storage, checker/security policy, logging, and API assembly. tests/ contains API and focused unit tests. docs/ contains this contract and an honest verification record. Runtime/package files live at repository root.