Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ Useful environment variables:
- `WAF_IDS_STATE_PATH`: optional JSON state path. When omitted, the service runs with seeded in-memory state.
- `DNSBL_ORIGIN`: DNSBL zone origin, default `dnsbl.local`
- `EVENT_LIMIT`: retained event count, default `1000`; must be greater than zero
- `RATE_LIMIT`: optional per-client gateway request budget; `0` disables local limiting
- `RATE_LIMIT_WINDOW`: fixed-window length in seconds for `RATE_LIMIT`, default `60`
- `RATE_LIMIT_MAX_CLIENTS`: maximum in-memory client buckets retained by the local limiter, default `4096`; may also be bootstrapped via `WAF_IDS_CREDENTIALS_PATH` as `rate_limit_max_clients`
- `TRUSTED_PROXY_IPS`: optional comma-separated proxy peer IPs allowed to supply `X-Forwarded-For`

When the local limiter returns HTTP `429`, the response includes a `Retry-After`
header plus JSON `reason` codes that distinguish per-client quota exhaustion
from local limiter saturation (`local_rate_limiter_capacity_exceeded`).
Forwarded client-IP headers are ignored unless the connected peer IP is present
in `TRUSTED_PROXY_IPS`.

Example with persistent local state:

Expand Down
Binary file not shown.
32 changes: 32 additions & 0 deletions docs/runbooks/operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,30 @@ The smoke test starts the service on a temporary port with a temporary JSON stat

When `WAF_IDS_STATE_PATH` is enabled, the process writes a temporary sibling file and atomically replaces the configured state path. If a management write cannot be persisted, the in-memory mutation is rolled back and the API returns `500`.

## Local Admission Control

`RATE_LIMIT` and `RATE_LIMIT_WINDOW` enable a per-client fixed-window limiter for
`/gateway` traffic. `RATE_LIMIT_MAX_CLIENTS` bounds the number of in-memory
client buckets the process will retain; stale buckets age out after one full
window. When the map is full, unseen clients receive `429 Too Many Requests`
with `Retry-After` and reason
`local_rate_limiter_capacity_exceeded` until older buckets expire.
By default the limiter keys on the connected peer IP. `X-Forwarded-For` is
considered only when the peer IP is listed in `TRUSTED_PROXY_IPS`, which
prevents direct clients from manufacturing new local limiter buckets with
spoofed forwarding headers. `X-Real-IP` is not trusted for limiter identity
because the header does not carry a verifiable proxy chain.

This is a local emergency guard, not the distributed quota authority described
in issue `#83`. The contract follows RFC 6585's guidance that `429` responses
may include `Retry-After`, and it aligns with OWASP ASVS 5.0 availability
controls by failing with a bounded, operator-visible response instead of
allowing attacker-controlled client cardinality to grow process memory without
limit. Welsh et al. (2001) and Welsh and Culler (2002) motivate this choice:
overload control should be explicit in the service design, and excess demand
should be shed early enough to bound queue growth, latency, and memory rather
than letting attacker-driven request cardinality expand invisibly.

## Safe Change Procedure

1. Start new routes in `monitor` mode.
Expand Down Expand Up @@ -107,3 +131,11 @@ This baseline is suitable for local and controlled lab deployments. Internet-fac
- Live Suricata EVE tailing / shipper (HTTP ingest of EVE alerts is available at `POST /api/ids/suricata/eve`)
- Live MISP REST pull or live OpenCTI GraphQL pull (HTTP STIX/MISP/OpenCTI document ingest and TAXII 2.1 poll are available at `POST /api/threat-intel/stix`, `POST /api/threat-intel/misp`, `POST /api/threat-intel/opencti`, and `POST /api/threat-intel/taxii/poll`)
- human approval workflow for AI SOC recommendations that change enforcement

## References

- Nottingham, M., & Fielding, R. (2012). *Additional HTTP status codes* (RFC 6585). https://www.rfc-editor.org/info/rfc6585
- OWASP Foundation. (2025). *OWASP Application Security Verification Standard 5.0.0*. https://owasp.org/www-project-application-security-verification-standard/
- Souppaya, M., Scarfone, K., & Dodson, D. (2022). *Secure Software Development Framework (SSDF) version 1.1* (NIST SP 800-218). https://doi.org/10.6028/NIST.SP.800-218
Comment thread
seonghobae marked this conversation as resolved.
- Welsh, M., Culler, D., & Brewer, E. (2001). *SEDA: An architecture for well-conditioned, scalable Internet services*. Proceedings of the Eighteenth ACM Symposium on Operating Systems Principles, 230-243. https://www.sosp.org/2001/papers/welsh.pdf
- Welsh, M., & Culler, D. (2002). *Overload management as a fundamental service design primitive*. Proceedings of the 10th ACM SIGOPS European Workshop, 63-69. Local PDF: `docs/papers/overload-management-service-design-primitive-ew10-2002.pdf`
Loading
Loading