60 lines
2.1 KiB
Markdown
60 lines
2.1 KiB
Markdown
# 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 contract
|
|
* `app/models.py`, `app/store.py` — typed resources and locked state
|
|
* `app/security.py`, `app/checker.py` — DNS/redirect SSRF policy and checks
|
|
* `app/main.py` — API and operational routes
|
|
* `tests/` — mocked API, checker, race, and redaction tests
|
|
* `docs/VERIFICATION.md` — reproducible validation record
|
|
|
|
## Local development
|
|
|
|
Python 3.12 is required.
|
|
|
|
```sh
|
|
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:
|
|
|
|
```sh
|
|
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
|
|
|
|
```sh
|
|
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.
|