demo-bot d9ec9e7ed1
Some checks failed
ci / validate (push) Has been cancelled
decomposer: scaffold crucible-agent-build-fastapi-endpoint
2026-08-09 15:51:44 +00:00

Endpoint Monitor Service

A typed FastAPI service for process-local endpoint monitors and secure, on-demand HTTP checks. The complete contract and security semantics are in SPEC.md.

Quick start

Requires Python 3.12.

python -m venv .venv
. .venv/bin/activate
pip install -e '.[dev]'
make check
uvicorn app.main:app --reload

Open http://127.0.0.1:8000/docs. Example:

curl -sS -X POST http://127.0.0.1:8000/monitors \
  -H 'content-type: application/json' \
  -d '{"name":"Example","url":"https://example.com/health?token=not-logged"}'
curl -sS -X POST http://127.0.0.1:8000/monitors/UUID/check
curl -sS http://127.0.0.1:8000/monitors/UUID/status

Configuration

Settings are validated at startup and use the MONITOR_ prefix: LOG_LEVEL (default INFO), TOTAL_TIMEOUT_SECONDS (10, max 60), CONNECT_TIMEOUT_SECONDS (3), READ_TIMEOUT_SECONDS (5), MAX_REDIRECTS (5, max 10), and USER_AGENT. Connect/read values cannot exceed total timeout.

Security behavior

Every hop is resolved and all returned addresses must be globally routable. A mixed public/private DNS response is rejected. A dedicated connector receives only the validated addresses for that hop, so the HTTP library cannot perform a second unvalidated lookup; TLS still verifies the URL hostname. Redirects are followed manually only after the next URL passes the same policy. Literal IPs are classified identically, URL credentials are rejected, environment proxies are ignored, redirect count is bounded, and the entire operation (including DNS and all hops) has a total timeout. Logs contain a redacted URL with no query, fragment, or credentials.

The checks in tests/test_security.py provide inspectable evidence for private/special IP blocking, mixed-answer rejection, address pinning, per-hop redirect validation, total timeout mapping, and query redaction. tests/test_atomic.py proves revision-based atomic status application. Outbound HTTP is faked in tests; tests never depend on the public network.

Docker

docker build -t endpoint-monitor:local .
docker run --rm -p 8000:8000 endpoint-monitor:local
# or
docker compose up --build

The image runs as a non-root user with exactly one Uvicorn worker and a healthcheck.

Layout

  • SPEC.md — route/status/error/security contract and architecture
  • app/main.py — FastAPI routes and dependency wiring
  • app/store.py — lock-protected volatile state and compare-and-set status
  • app/security.py — URL redaction, DNS resolution, and IP policy
  • app/checker.py — pinned transport, redirects, timeouts, latency/error mapping
  • tests/ — API, policy, timeout, logging, and concurrency tests

Operational limitation

There is deliberately no database. All monitors vanish on restart and multiple processes would have divergent state. Keep one worker, as the container does. For durability or horizontal scaling, replace MonitorStore with shared transactional storage before deployment. There is no authentication; place the service behind suitable network and identity controls.

Description
Auto-generated agent: build-fastapi-endpoint
Readme MIT 808 KiB
Languages
Python 97.9%
Shell 1.5%
Makefile 0.5%