70 lines
3.7 KiB
Markdown
70 lines
3.7 KiB
Markdown
# HAN Message Safety v2
|
|
|
|
Production-oriented internal FastAPI service for deterministic text, URL and quarantined-file
|
|
safety checks. PostgreSQL is the durable source of truth for idempotency, tasks, leases, fencing,
|
|
caches, audit and immutable config snapshots. Redis is intentionally optional and may only
|
|
accelerate hot-cache/rate/wakeup paths.
|
|
|
|
## Local verification
|
|
|
|
Python 3.12 is required. These commands do not start services:
|
|
|
|
```sh
|
|
python -m pip install -e ".[dev]"
|
|
pytest
|
|
ruff check .
|
|
message-safety-config validate app/artifacts/seed-config.yaml
|
|
```
|
|
|
|
Migrations and config administration require
|
|
`MESSAGE_SAFETY_CONFIG_ADMIN_DATABASE_URL_FILE`. Runtime secrets are accepted only through
|
|
`*_FILE`; the entrypoint rejects missing/empty files without printing their values.
|
|
|
|
```sh
|
|
alembic upgrade head
|
|
message-safety-config create app/artifacts/seed-config.yaml --version 1 --actor migration
|
|
message-safety-config activate --version 1 --approved-by security-owner
|
|
```
|
|
|
|
## Deployment boundary
|
|
|
|
`docker-compose.fragment.yml` is an include fragment for the root VM2 Compose. It publishes no
|
|
host port, runs API and worker as UID 10001 with a read-only filesystem, drops all capabilities,
|
|
and mounts only service-specific secret files plus the broker Unix socket
|
|
`/run/han-kesl/scan.sock` into the worker. The root project owns networks/secrets and the
|
|
root-owned emergency mode file. KESL 12.4 standalone and its root-owned fail-closed broker are
|
|
host services, not Compose services; `clamd` and `freshclam` are absent from Compose.
|
|
|
|
The broker invokes the fixed host command `kesl-control --scan-file --action Inform`. A clean
|
|
result may continue to allow, an infected result denies, and scanner errors, unknown output,
|
|
timeouts or a stale KESL database remain retryable and eventually return `503` rather than
|
|
allowing content. Runtime records `scanner_engine=kesl`; `signatures_version` is the hash of KESL
|
|
version plus database date. KESL database updates run hourly under the operator KESL runbook.
|
|
|
|
## External release gates
|
|
|
|
The following cannot be proven by repository-only tests and must remain fail-closed until the
|
|
target environment verifies them:
|
|
|
|
- Selectel S3 supports version-specific `GetObject`, signed conditional ETag behavior, bucket
|
|
versioning, checksum metadata, virtual-host addressing and a read-only IAM policy without
|
|
list/write/delete.
|
|
- KESL version/database date is supplied through the broker to readiness and task cache keys;
|
|
hourly update, stale-database alarms and clean/EICAR/malformed corpora pass on VM2.
|
|
- The broker is a custom integration: exact `kesl-control` output/exit semantics, socket
|
|
permissions, cleanup and throughput must pass gates on the target VM2 with KESL 12.4.
|
|
- HEIF native decoding and PDF parser sandbox resource limits pass the approved corpus. The
|
|
in-process detector is bounded by 5 MiB and validates active/encrypted PDF markers, but OS-level
|
|
CPU/memory/wall-time isolation must be enforced by the worker container and target runtime.
|
|
- Managed PostgreSQL role grants prove runtime cannot migrate or activate config, while the
|
|
config-admin role can; migration constraint, concurrent activation, lease and fencing tests run
|
|
against PostgreSQL (not SQLite).
|
|
- Trusted resolver, DNS rebinding corpus, S3 canary and worker heartbeat are wired into production
|
|
readiness probes.
|
|
- Image dependencies are resolved to a reviewed lock/SBOM and the final image is pinned by digest
|
|
in the root Compose release manifest.
|
|
- Target load gates (10 text checks/s, 2 file checks/s, 100 pending tasks, five worker slots) and
|
|
privacy/log redaction are verified in production-like infrastructure.
|
|
|
|
No HTTP fetch, redirect following or rendering of user-provided URLs exists in this service.
|