Files
aoc/RELEASE_NOTES_v1.7.15.md
T
tomas.kracmar 85db9d14a8
CI / lint-and-test (push) Failing after 52s
Add v1.7.15 release notes
2026-05-28 14:57:53 +02:00

3.8 KiB

AOC v1.7.15 Release Notes

Release Date: 2026-04-24

Security Hardening & Code Quality

This release continues the security hardening roadmap with async I/O improvements, stricter input validation, and infrastructure lockdown.

Async Authentication Refactor

  • require_auth() and _get_jwks() are now async def to avoid blocking the event loop during JWKS fetch and token validation
  • Impact: Eliminates synchronous I/O stalls on authenticated requests under load

CSP Tightening

  • Removed 'unsafe-inline' from the script-src directive in the Content-Security-Policy header
  • All JavaScript is now loaded from external files (app.js) or trusted CDNs with SRI hashes
  • 'unsafe-eval' is retained for Alpine.js expression evaluation
  • Impact: Mitigates XSS by preventing inline script injection

Model Validation Hardening

Added Field(min_length=, max_length=) constraints across request models:

Model Field Constraints
TagsUpdateRequest tags max_length=50
BulkTagsRequest tags max_length=50
CommentAddRequest text min_length=1, max_length=5000
AlertCondition field max_length=100
AlertRuleResponse conditions max_length=20
AlertRuleResponse message max_length=1000
AskRequest question min_length=1, max_length=2000
SavedSearchCreate name min_length=1, max_length=200
  • Impact: Rejects malformed or oversized inputs at the Pydantic/FastAPI layer before they reach business logic

Notification SSRF Guard

  • _validate_webhook_url() in notifications.py now blocks:
    • Non-HTTP(S) schemes
    • localhost, private, and link-local IP addresses
  • Impact: Prevents Server-Side Request Forgery via malicious webhook URLs in alert notifications

Rate Limiting Improvements

  • New category: "explain" → 20 requests per minute
  • Categories: fetch=10/hr, ask=30/min, explain=20/min, write=20/min, default=120/min
  • Fail-closed on Redis/Valkey error: raises RateLimitExceeded(retry_after=60)
  • Impact: Prevents abuse of the new explain endpoint and ensures graceful degradation if the rate limit store is unreachable

Frontend JavaScript Extraction

  • All inline JavaScript has been extracted from index.html into backend/frontend/app.js
  • Alpine.js SPA loads /app.js?v=1 before Alpine initialization
  • Impact: Enables stricter CSP, improves cacheability, and separates markup from logic

Docker Compose Security

  • Backend port binding changed from "8000:8000" to "127.0.0.1:8000:8000"
  • Impact: Prevents direct external access to the backend when nginx is the intended reverse proxy

Files Changed

File Change
backend/auth.py require_auth() and _get_jwks() made async
backend/main.py CSP tightened; startup warnings
backend/models/api.py Added Field validation constraints
backend/notifications.py SSRF guard for webhook URLs
backend/rate_limiter.py Added "explain" rate limit category
backend/routes/saved_searches.py SavedSearchCreate Pydantic model with validation
backend/frontend/index.html Extracted inline JS to app.js
backend/frontend/app.js New — extracted frontend JavaScript
docker-compose.yml Backend port bound to 127.0.0.1 only
nginx/nginx.conf Security headers alignment
backend/tests/test_auth.py Updated for async require_auth()
backend/tests/test_api.py Updated saved searches validation test
backend/tests/test_ask.py Updated empty question test for 422
.gitignore Added memory/
VERSION Bumped to 1.7.15

Test Results

  • 80/80 pytest tests passing
  • Ruff lint/format clean

Docker Image

git.cqre.net/cqrenet/aoc-backend:v1.7.15