Skip to content

REST API abuse controls

ZapTrace applies bounded request-body and per-client request-rate controls in the REST API process. These controls reduce accidental and low-complexity abuse; they do not replace a reverse proxy, API gateway, WAF, authentication, or deployment monitoring.

Policy table

Control Default Failure response Boundary
Request body 10 MiB 413 PAYLOAD_TOO_LARGE Counts streamed chunks and also rejects an oversized declared Content-Length.
Request rate 120 requests / 60 seconds 429 RATE_LIMITED Sliding window per resolved client identity.
Client-key cardinality 10,000 active keys 429 RATE_LIMITED New identities fail closed when the bounded in-memory table is full.
Forwarded client address Disabled unless the direct peer is trusted Uses direct peer Only configured proxy CIDRs may supply X-Forwarded-For.
Worker count One with the built-in backend Startup failure Multi-worker service requires an injected shared rate-limit backend or gateway-level enforcement.

Rejected requests emit a structured zaptrace.api.security log record with the event api_request_rejected, response code, resolved client identity, path, and rejection reason.

Environment configuration

Variable Meaning Default
ZAPTRACE_API_TRUSTED_PROXIES Comma-separated IP addresses or CIDRs allowed to provide X-Forwarded-For. Empty; forwarding headers ignored.
ZAPTRACE_API_MAX_BODY_BYTES Maximum request body after counting all streamed chunks. 10485760
ZAPTRACE_API_RATE_LIMIT_REQUESTS Requests allowed in one window. 120
ZAPTRACE_API_RATE_LIMIT_WINDOW_SECONDS Sliding-window duration. 60
ZAPTRACE_API_RATE_LIMIT_MAX_KEYS Maximum active in-memory client identities. 10000
ZAPTRACE_API_RATE_LIMIT_CLEANUP_INTERVAL_SECONDS Maximum delay between global stale-key sweeps. 300
ZAPTRACE_API_RATE_LIMIT_BACKEND Built-in backend selection. The distributed package currently accepts memory. memory
ZAPTRACE_API_WORKERS Intended API worker count used for startup validation. 1

Every numeric setting must be a positive integer. Invalid networks, values, or unsupported backends fail startup rather than silently weakening controls.

Trusted reverse proxy example

A deployment with a reverse proxy on 10.20.0.0/16 can use:

export ZAPTRACE_API_TRUSTED_PROXIES="10.20.0.0/16"
export ZAPTRACE_API_MAX_BODY_BYTES="10485760"
export ZAPTRACE_API_RATE_LIMIT_REQUESTS="120"
export ZAPTRACE_API_RATE_LIMIT_WINDOW_SECONDS="60"
export ZAPTRACE_API_RATE_LIMIT_MAX_KEYS="10000"
export ZAPTRACE_API_WORKERS="1"

The proxy must overwrite, not append blindly to, inbound forwarding headers and must enforce its own connection, header, request-body, and request-rate limits. ZapTrace evaluates a trusted chain from right to left and selects the nearest untrusted address. A direct untrusted peer cannot change its rate-limit identity by sending a forged forwarding header.

Single-process and multi-worker deployments

The built-in backend is dependency-light and intentionally single-process. Its state resets on process restart and is not synchronized between workers. Setting ZAPTRACE_API_WORKERS above 1 with ZAPTRACE_API_RATE_LIMIT_BACKEND=memory fails configuration validation.

A controlled multi-worker integration must inject an implementation of the RateLimitBackend protocol backed by a shared rate-limit backend, or enforce the same policy at a trusted gateway. Starting several independent memory-backed workers and describing the result as one consistent rate limit is unsupported.

Operational non-claims

A successful local rate-limit decision does not establish identity, authorization, DDoS resistance, or multi-tenant isolation. Keep non-loopback authentication, object authorization, gateway policy, logs, and resource monitoring enabled.