From ed8e96d5ac78dd0c05438f2d618dbe5c9c55a677 Mon Sep 17 00:00:00 2001 From: demo-bot Date: Sun, 9 Aug 2026 15:47:00 +0000 Subject: [PATCH] decomposer: generate deliverable files for Define the service contract and project architecture for the FastAPI endpoint monitoring service.; Implement the typed monitor CRUD API and concurrency-safe in-memory state according to the service design.; Implement secure on-demand endpoint checks with status updates, latency measurement, robust error handling, and redacted structured logs.; Add operational API endpoints and environment-driven runtime configuration to the monitoring service.; Create automated tests for the monitoring service.; Package the service with Docker and developer documentation.; Validate the complete project. --- README.md | 80 +++++++++++++++++++++---------------------------------- 1 file changed, 31 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 9c79c04..3a175d1 100644 --- a/README.md +++ b/README.md @@ -1,71 +1,53 @@ -# Endpoint Monitor Service +# Endpoint Monitor -A typed FastAPI service that stores endpoint monitors in concurrency-safe process memory and -runs SSRF-aware on-demand HTTP checks. +A typed, unauthenticated FastAPI service for process-local monitor CRUD and secure on-demand HTTP checks. See [SERVICE_DESIGN.md](SERVICE_DESIGN.md) for the complete contract and [VERIFICATION.md](VERIFICATION.md) for honest generation-time evidence. -## Quick start +## Layout + +- `app/main.py`: API composition and lifecycle +- `app/models.py`, `app/store.py`: schemas and lock-protected memory +- `app/security.py`, `app/checker.py`: SSRF policy, redirects, timing, HTTP +- `tests/`: API, checker/security, store, and redaction tests + +## Local development Requires Python 3.12. -```sh +```bash python -m venv .venv . .venv/bin/activate pip install -e '.[dev]' -uvicorn app.main:app --reload -``` - -OpenAPI is at `http://localhost:8000/docs`. - -```sh -curl -s -X POST http://localhost:8000/monitors \ - -H 'content-type: application/json' \ - -d '{"name":"Example","url":"https://example.com","expected_status":200}' -curl -s -X POST http://localhost:8000/monitors/UUID/check -curl -s http://localhost:8000/monitors/UUID/status -``` - -See `docs/service-contract.md` for routes, schemas, status semantics, error behavior, security, -and architecture. - -## Configuration - -All settings are validated at startup and use the `MONITOR_` prefix: - -| Variable | Default | Constraint | -|---|---:|---| -| `MONITOR_HOST` | `0.0.0.0` | bind host | -| `MONITOR_PORT` | `8000` | 1..65535 | -| `MONITOR_LOG_LEVEL` | `INFO` | logging level | -| `MONITOR_CHECK_TIMEOUT_SECONDS` | `5` | >0, <=30 | -| `MONITOR_MAX_REDIRECTS` | `3` | 0..10 | - -## Quality checks - -```sh ruff format --check . ruff check . mypy app pytest -./scripts/verify.sh +uvicorn app.main:app --reload ``` -Tests use mocked HTTP transports and cover typed CRUD/error behavior, concurrent state changes, -status persistence, timeout-safe checking, DNS/private-address blocking, redirect revalidation, -and log redaction. No test sends outbound traffic. +Create and check a monitor: -## Containers +```bash +curl -sS -X POST http://localhost:8000/v1/monitors \ + -H 'content-type: application/json' \ + -d '{"name":"example","url":"https://example.com/"}' +curl -sS -X POST http://localhost:8000/v1/monitors/UUID_FROM_ABOVE/check +curl -sS http://localhost:8000/v1/monitors/UUID_FROM_ABOVE/status +``` -```sh +OpenAPI is at `/docs` and `/openapi.json`. + +## Configuration + +All settings are validated at startup. Variables are `MONITOR_REQUEST_TIMEOUT_SECONDS` (default 5, max 30), `MONITOR_CONNECT_TIMEOUT_SECONDS` (default 2, max 10), `MONITOR_MAX_REDIRECTS` (default 5, max 10), and `MONITOR_LOG_LEVEL` (default `INFO`). + +## Container + +```bash docker build -t endpoint-monitor . docker run --rm -p 8000:8000 endpoint-monitor # or docker compose up --build +curl -f http://localhost:8000/readyz ``` -The image runs as an unprivileged user, uses one worker, and has a health check. - -## Important limitation - -Storage is deliberately process-local and ephemeral. Restarting loses every monitor. Multiple -workers or replicas each have independent data and readiness only establishes that the local -process can serve requests. Use one worker; add a shared database before scaling horizontally. +The image runs as a non-root user and intentionally starts one worker. Memory is lost on restart, is not shared between workers/containers, and has no durability or horizontal consistency. The API has no authentication and should not be exposed directly to untrusted networks. DNS re-resolution by the underlying HTTP transport leaves a DNS-rebinding window after policy validation; use network-level egress controls in production.