kanx ships two surfaces with different threat profiles.
Threats: malicious model checkpoints, supply-chain compromise.
- Mitigations:
tf.keras.models.load_modelrejects malformed archives; we wrap with aFileNotFoundErrorboundary check.- The library pins lower bounds (
tensorflow>=2.16,<3,numpy>=1.23,pyyaml>=6) and exposes optional extras for FastAPI/Pydantic. Audit viapip-auditis part of the CI roadmap. yaml.safe_loadis used everywhere — neveryaml.load.
Threats: unbounded inputs, untrusted file paths, denial of service.
| Threat | Mitigation |
|---|---|
| Oversized batch | KANX_MAX_BATCH (default 4096) returns 413 |
| Wrong feature count | Boundary check returns 400 |
| Wrong tensor rank | Boundary check returns 400 |
Path traversal on /api/load |
Server validates os.path.exists only — operator is responsible for restricting filesystem access (run as non-root, mount RO) |
| Arbitrary YAML execution | safe_load only, never load |
| CORS | Default * — override in production (see hardening) |
| Pickle gadgets in checkpoints | Only .keras archives accepted; tf.keras.models.load_model(compile=False) does not execute optimizer state |
- Run the container as a non-root user (Dockerfile USER directive — TODO P1).
- Restrict CORS to the known client origin in
api/app.py. - Mount
KANX_CHECKPOINTdirectory read-only (k8s/deployment.yamlalready does this viareadOnly: true). - Set
KANX_MAX_BATCHbased on pod memory budget. - Put the service behind an ingress with mTLS / OAuth2-proxy.
- Enable rate limiting at the ingress (nginx
limit_req). - Disable
/api/resetand/api/loadvia reverse-proxy ACLs if operators don't need hot-swap (defence-in-depth). - Drop the
--reloadflag from uvicorn in prod (the Dockerfile does so).
pyproject.tomldeclares precise lower bounds.requirements.txtis the same set, used by the Docker image.- CI installs from a clean
pipenvironment per matrix job, so anything that silently relies on a global install will fail. - Future P1: SBOM via
pip-licenses+cyclonedx-pypublished on release.
kanx does not log request payloads. inference_ms is the only
per-request telemetry surfaced. Operators who want full request/response
audit must add their own middleware.
kanx has no secrets in v0.1 (no API keys, no DB credentials, no model
registry tokens). All configuration is via plain env vars. If you wire in
S3-backed model loading later, fetch credentials via the cloud SDK's IAM
chain — do not bake them into the image.