Endpoint Monitor
A typed FastAPI service that stores endpoint monitors in memory and runs secure, on-demand HTTP checks. There is no authentication; do not expose it directly to untrusted networks.
Layout
docs/SERVICE_DESIGN.md— complete API/status/security contractapp/models.py,app/store.py— typed resources and locked stateapp/security.py,app/checker.py— DNS/redirect SSRF policy and checksapp/main.py— API and operational routestests/— mocked API, checker, race, and redaction testsdocs/VERIFICATION.md— reproducible validation record
Local development
Python 3.12 is required.
python -m venv .venv
. .venv/bin/activate
pip install -e '.[dev]'
ruff format --check .
ruff check .
mypy app
pytest
uvicorn app.main:app --reload
Create and check a monitor:
curl -sS -X POST http://localhost:8000/api/v1/monitors \
-H 'content-type: application/json' \
-d '{"name":"Example","url":"https://example.com/health?token=not-logged"}'
curl -sS -X POST http://localhost:8000/api/v1/monitors/MONITOR_UUID/check
curl -sS http://localhost:8000/api/v1/monitors/MONITOR_UUID/status
curl -sS http://localhost:8000/healthz
OpenAPI is at /docs and /openapi.json.
Configuration
All settings use the MONITOR_ prefix: APP_NAME, LOG_LEVEL, REQUEST_TIMEOUT_SECONDS (default 5, max 30), MAX_REDIRECTS (default 5, max 10), and MAX_RESPONSE_BYTES (default 65536, max 1048576). Invalid values fail startup.
Container
docker build -t endpoint-monitor .
docker run --rm -p 8000:8000 endpoint-monitor
# or
docker compose up --build
The image uses an unprivileged user and one Uvicorn worker. One worker is mandatory because data is process-local.
Important limitations
State is neither persistent nor shared: restart loses all monitors and multiple workers have divergent data. DNS checks occur before each hop, but the default HTTP stack resolves again while connecting. Use an egress proxy/firewall in hostile production environments to close that DNS-rebinding timing window. Logs redact URL credentials, query, and fragment; avoid secrets in path segments.