# AOC v1.7.7 Release Notes **Release date:** 2026-04-24 --- ## Security Hardening This release is a focused security patch addressing findings from an internal audit. All users running AOC in production are encouraged to upgrade. ### Webhook authentication (`/api/webhooks/graph`) - **ClientState validation** — Notifications now require a matching `WEBHOOK_CLIENT_SECRET`. Set this in your `.env` to the same value used when creating Graph subscriptions. - Rejects spoofed notification payloads with `401 Unauthorized`. ### Rate limiting - **Redis-backed fixed-window rate limiting** is now enabled by default. - Per-category limits: - `/api/fetch-audit-logs` — 10 requests/hour - `/api/ask` — 30 requests/minute - `/api/events/bulk-tags` — 20 requests/minute - All other endpoints — 120 requests/minute - Returns `429 Too Many Requests` with a `Retry-After` header when exceeded. ### SSRF protection for LLM calls - `LLM_BASE_URL` is now validated before every outbound request. - Blocks non-HTTPS URLs, localhost, link-local addresses (`169.254.169.254`), and all private IP ranges. ### CORS enforcement - Wildcard (`*`) origins are **automatically stripped** when `AUTH_ENABLED=true`. - A startup warning is logged if an insecure CORS configuration is detected. ### Content Security Policy - API and HTML responses now include a `Content-Security-Policy` header. - Restricts script sources to self, CDN origins, and MSAL auth library. ### Audit trail integrity - The audit middleware no longer parses JWT tokens without signature verification. - Verified claims are now propagated safely via `contextvars`, eliminating audit log poisoning. ### Standalone MCP server - Prints a prominent security warning on startup reminding operators that the stdio transport has no authentication layer. --- ## Operational Improvements ### Bulk tag cap - `POST /api/events/bulk-tags` now refuses to update more than **10,000 events** in a single request. - Returns `400` with guidance to narrow filters. ### Generic error responses - Internal exception details are no longer leaked in HTTP 500/502 responses. - Full stack traces remain in server-side logs. ### Alert rule schema - `conditions` field now uses a strict Pydantic model (`AlertCondition`) instead of an unconstrained `list[dict]`. - Prevents stored data pollution from malformed rule payloads. ### Docker Compose - MongoDB (`27017`) and Redis (`6379`) ports are no longer forwarded to the Docker host. - Internal services are reachable only via the Docker network. --- ## Configuration Add to your `.env`: ```bash # Required if you use Graph webhooks WEBHOOK_CLIENT_SECRET=your-random-secret # Optional: disable rate limiting (not recommended) RATE_LIMIT_ENABLED=true RATE_LIMIT_REQUESTS=120 RATE_LIMIT_WINDOW_SECONDS=60 ``` --- ## Upgrade notes **No breaking changes.** Existing event data, tags, comments, and saved searches are preserved. After pulling: ```bash export AOC_VERSION=v1.7.7 docker compose -f docker-compose.prod.yml pull docker compose -f docker-compose.prod.yml up -d ``` --- ## Docker image ``` git.cqre.net/cqrenet/aoc-backend:v1.7.7 ```