Commit Graph

103 Commits

Author SHA1 Message Date
tomas.kracmar ad5816dc2d Release v1.7.16: CI workflow fix for Gitea Actions, repository cleanup
CI / lint-and-test (push) Successful in 1m54s
Release / build-and-push (push) Successful in 2m4s
v1.7.16
2026-05-28 16:07:25 +02:00
tomas.kracmar 53724c1671 Fix CI: use venv to avoid PEP 668 externally-managed-environment error
CI / lint-and-test (push) Successful in 1m21s
2026-05-28 15:38:55 +02:00
tomas.kracmar 401d4e2717 Fix CI: use system python3 + apt-get instead of actions/setup-python
CI / lint-and-test (push) Failing after 25s
2026-05-28 15:24:33 +02:00
tomas.kracmar eea54dd203 Fix CI: override working-directory for pre-checkout apt-get step
CI / lint-and-test (push) Failing after 1m14s
2026-05-28 15:19:23 +02:00
tomas.kracmar da0f082b45 Clean up: remove working files, expand .gitignore for venvs, caches, temp files
CI / lint-and-test (push) Failing after 11s
2026-05-28 15:18:10 +02:00
tomas.kracmar 5e6997cbd6 Fix Gitea Actions CI: use python:3.11-slim container instead of actions/setup-python
CI / lint-and-test (push) Failing after 21s
2026-05-28 15:02:34 +02:00
tomas.kracmar 85db9d14a8 Add v1.7.15 release notes
CI / lint-and-test (push) Failing after 52s
2026-05-28 14:57:53 +02:00
tomas.kracmar f7fca05210 Release v1.7.15: security hardening, async auth, CSP tightening, model validation, SSRF guard, rate limiting improvements, frontend extraction, Docker compose security
Release / build-and-push (push) Successful in 3m12s
v1.7.15
2026-05-28 14:57:09 +02:00
tomas.kracmar fe95dfcfce docs: update AGENTS.md, README.md, DEPLOY.md, ROADMAP.md for v1.7.14 security features
Release / build-and-push (push) Successful in 21s
CI / lint-and-test (push) Successful in 25s
v1.7.14
2026-04-27 16:52:35 +02:00
tomas.kracmar 8d951fc335 v1.7.14: LLM/SIEM domain allowlists, SRI hashes, auth misconfig warning, Azure Key Vault integration
CI / lint-and-test (push) Successful in 22s
Release / build-and-push (push) Successful in 1m7s
2026-04-27 16:45:06 +02:00
tomas.kracmar 35eca65234 v1.7.13: switch Alpine.js to CSP build, remove unsafe-eval from CSP
Release / build-and-push (push) Successful in 40s
CI / lint-and-test (push) Successful in 33s
v1.7.13
2026-04-27 16:08:34 +02:00
tomas.kracmar 07a841615b v1.7.12: security hardening — CORS fix, security headers, fail-closed rate limiter, OpenAPI docs disabled by default, config auth privacy, webhook validation
Release / build-and-push (push) Successful in 44s
CI / lint-and-test (push) Successful in 22s
v1.7.12
2026-04-27 14:19:28 +02:00
tomas.kracmar c086fa4260 hotfix(v1.7.11): add unsafe-eval to CSP for Alpine.js
CI / lint-and-test (push) Successful in 1m26s
Release / build-and-push (push) Successful in 3m1s
v1.7.11
2026-04-27 10:39:33 +02:00
tomas.kracmar be700fefc3 hotfix(v1.7.10): add font-src to CSP for data URI fonts
CI / lint-and-test (push) Successful in 1m29s
Release / build-and-push (push) Successful in 2m53s
v1.7.10
2026-04-27 10:32:35 +02:00
tomas.kracmar e2cea50d87 hotfix(v1.7.9): auth diagnostics and rate-limit exemptions
CI / lint-and-test (push) Successful in 2m30s
Release / build-and-push (push) Successful in 4m46s
- Exempt /api/config/auth, /api/config/features, /health, /metrics from rate limiting
- Fix generic exception handler to return proper JSON for HTTPException instead of re-raising
- Add startup log with auth_enabled and version
- Add frontend console logging for auth config fetch errors
- Show 'Auth: OFF' or 'Auth: misconfigured' on auth button instead of empty text
- Add backend debug logging to /api/config/auth endpoint
v1.7.9
2026-04-27 10:09:44 +02:00
tomas.kracmar 7fe53f882a hotfix(v1.7.8): restore CORS wildcard and fix CSP for MSAL auth
CI / lint-and-test (push) Successful in 51s
Release / build-and-push (push) Successful in 2m4s
- Revert automatic CORS wildcard stripping that broke production deployments
  with CORS_ORIGINS=* (now logs a warning but preserves the config)
- Expand CSP headers to allow MSAL auth flows:
  - connect-src: login.microsoftonline.com
  - frame-src: login.microsoftonline.com
  - form-action: login.microsoftonline.com
v1.7.8
2026-04-27 09:41:28 +02:00
tomas.kracmar d01e7801ed security: v1.7.7 hardening release
CI / lint-and-test (push) Successful in 51s
Release / build-and-push (push) Successful in 1m57s
- Add WEBHOOK_CLIENT_SECRET validation for Graph webhooks
- Add Redis-backed rate limiting (fetch/ask/write/default tiers)
- Validate LLM_BASE_URL to prevent SSRF (HTTPS only, block private IPs)
- Enforce non-wildcard CORS when AUTH_ENABLED=true
- Add Content-Security-Policy headers
- Fix audit middleware to use verified JWT claims via contextvars
- Cap bulk_tags updates to 10,000 documents
- Return generic error messages to clients (no internal detail leakage)
- Strict AlertCondition Pydantic model for alert rules
- Security warning on MCP stdio server startup
- Remove MongoDB/Redis host ports from docker-compose
- Remove mongo_query from /ask API response
v1.7.7
2026-04-27 09:16:57 +02:00
tomas.kracmar 7cd7709b4a fix: dedupe alert_rules before creating unique index in setup_indexes()
CI / lint-and-test (push) Successful in 1m7s
Release / build-and-push (push) Successful in 2m25s
The unique index on alert_rules.name was being created before duplicates
were cleaned up, causing DuplicateKeyError on startup when existing
duplicates were present. Move deduplication into setup_indexes() so it
runs before the unique index is created.

v1.7.6
v1.7.6
2026-04-22 15:20:19 +02:00
tomas.kracmar 9cd50d1257 chore: bump version to 1.7.5
CI / lint-and-test (push) Successful in 30s
Release / build-and-push (push) Successful in 1m29s
v1.7.5
2026-04-22 15:13:55 +02:00
tomas.kracmar 646d61f72e fix: dedupe existing rules + unique index to prevent duplicates
- Add unique index on alert_rules.name in setup_indexes()
- seed_default_rules() now removes duplicates by name before upserting
- Keeps the oldest document (_id ascending) when deduping
2026-04-22 15:13:41 +02:00
tomas.kracmar 5f7a98f21c chore: bump version to 1.7.4
CI / lint-and-test (push) Successful in 28s
Release / build-and-push (push) Successful in 1m30s
v1.7.4
2026-04-22 14:57:06 +02:00
tomas.kracmar 19ed231a31 fix: prevent duplicate default rules on multi-worker startup
- Replace insert_many with replace_one(..., upsert=True) keyed by rule name
- Safe for concurrent startup with multiple gunicorn workers
2026-04-22 14:56:53 +02:00
tomas.kracmar f812fda150 chore: bump version to 1.7.3
CI / lint-and-test (push) Successful in 44s
Release / build-and-push (push) Successful in 1m40s
v1.7.3
2026-04-22 14:48:17 +02:00
tomas.kracmar a194c78c59 feat: all panels are now collapsible
- Source Health, Alerts, Alert Rules, Filters, Ask, Events panels all collapsible
- Click panel header to expand/collapse
- Chevron indicator rotates to show state
- Collapsed state persisted to localStorage (aoc_panels key)
2026-04-22 14:48:03 +02:00
tomas.kracmar e984899d4c chore: bump version to 1.7.2
Release / build-and-push (push) Successful in 1m39s
CI / lint-and-test (push) Successful in 43s
v1.7.2
2026-04-22 14:43:13 +02:00
tomas.kracmar b618cb29ea feat: alert rules management UI
- Add Alert Rules panel between Alerts and Filters sections
- List all rules with severity badge, on/off toggle, conditions preview
- Add Rule button opens modal with form for name, severity, message, conditions
- Edit existing rules inline
- Delete rules with confirmation
- Condition builder supports eq, neq, contains, in, after_hours operators
2026-04-22 14:42:58 +02:00
tomas.kracmar 3e1416cd52 chore: bump version to 1.7.1
CI / lint-and-test (push) Successful in 31s
Release / build-and-push (push) Successful in 1m32s
v1.7.1
2026-04-22 14:21:46 +02:00
tomas.kracmar 94983c43e9 fix: alert panel always visible, version display normalization
- Remove x-show condition hiding alert panel when no alerts exist
- Add empty state message explaining alerts appear on rule triggers
- Normalize appVersion in loadVersion() to strip leading 'v' (prevents vv1.7.0 in footer)
2026-04-22 14:21:34 +02:00
tomas.kracmar 0a16cf6870 chore: bump version to 1.7.0
CI / lint-and-test (push) Successful in 26s
Release / build-and-push (push) Successful in 1m15s
v1.7.0
2026-04-22 14:12:49 +02:00
tomas.kracmar e348881083 feat: Admin Operations SIEM — alerts, notifications, pre-built rules
- Add pluggable notification system (webhook, Slack, Teams) with retry
- Add alert deduplication: same rule + actor within 15 min = one alert
- Add 10 pre-built admin-ops rule templates seeded on startup:
  - Failed Conditional Access, After-Hours Admin Activity
  - New Application Registration, Admin Role Assignment
  - License Change, Bulk User Deletion
  - Device Compliance Failure, Exchange Transport Rule Change
  - Service Principal Credential Added, External Sharing Enabled
- Add /api/alerts, /api/alerts/{id}/status, /api/alerts/summary endpoints
- Add alert dashboard to frontend with status filters and ack/resolve buttons
- Add alert summary badge in hero header (high/medium/low counts)
- New env vars: ALERT_WEBHOOK_URL, ALERT_WEBHOOK_FORMAT, ALERT_DEDUPE_MINUTES
2026-04-22 14:12:36 +02:00
tomas.kracmar a220494bcf docs: add Phase 6 multi-tenancy plan to roadmap
CI / lint-and-test (push) Successful in 43s
- Row-level isolation architecture
- Per-tenant Entra + Graph credentials
- License-gated premium feature
- Deferred until SIEM export and alerting are production-tested
2026-04-22 13:49:56 +02:00
tomas.kracmar 5bda1dd616 chore: bump version to 1.6.4
CI / lint-and-test (push) Successful in 25s
Release / build-and-push (push) Successful in 1m29s
v1.6.4
2026-04-22 12:16:32 +02:00
tomas.kracmar 3e333291c6 fix: revert to single-click service filter, show all services by default, page size 24
- Revert +/- buttons on service pills back to single-click = filter only this service
- Remove default exclusion of Exchange/SharePoint/Teams (privacy controls handle this server-side)
- Change default page size from 25 to 24 (divisible by 3 for the 3-column grid)
- Update DEFAULT_PAGE_SIZE config default to 24
2026-04-22 12:16:20 +02:00
tomas.kracmar aa62528862 chore: bump version to 1.6.3
CI / lint-and-test (push) Successful in 35s
Release / build-and-push (push) Successful in 1m47s
v1.6.3
2026-04-22 12:02:28 +02:00
tomas.kracmar ac155d8843 feat: +/- buttons on service pills for additive/subtractive filtering
- Replace single-click service pill filter with explicit +/− buttons
- '+' adds the service to the current filter (keeps other selections)
- '−' removes the service from the current filter
- Result pills keep toggle click behavior
- Add .pill__action styles for small inline buttons
2026-04-22 12:02:11 +02:00
tomas.kracmar ed7465f5cd chore: bump version to 1.6.2
Release / build-and-push (push) Successful in 1m33s
CI / lint-and-test (push) Successful in 33s
v1.6.2
2026-04-22 11:53:21 +02:00
tomas.kracmar 0eebcd0765 feat: clickable pills, configurable page size, CQRE.NET branding
- Service/category pills are now clickable: click to filter by that service
- Result pills (Success, Failure, etc.) are now clickable: click to filter by that result
- Click again to clear the filter (toggle behavior)
- Change default page size from 100 to 25
- Add DEFAULT_PAGE_SIZE config (env var, default 25), exposed via /api/config/features
- Change footer brand from CQRE to CQRE.NET
- Add pill--clickable hover styles
- Bump CSS cache-buster to v=10
2026-04-22 11:53:01 +02:00
tomas.kracmar 67f3c28e82 chore: bump version to 1.6.1
CI / lint-and-test (push) Successful in 32s
Release / build-and-push (push) Successful in 1m30s
v1.6.1
2026-04-22 11:31:57 +02:00
tomas.kracmar 04c41ee740 style: UI polish — topbar, footer, user info, product feel
- Add sticky top navigation bar with brand, repo/docs links, user chip
- Show logged-in user name + email from MSAL account
- Add footer with version, issue link, repo link, docs link
- Move action buttons (Fetch/Refresh/Login) to compact topbar
- Clean up hero section (removed buttons, just title + tagline)
- Bump CSS cache-buster to v=9
- Responsive stacking for mobile
2026-04-22 11:31:37 +02:00
tomas.kracmar cbd46adaa6 style: ruff format
CI / lint-and-test (push) Successful in 25s
2026-04-22 10:08:32 +02:00
tomas.kracmar e4bafbc4b0 chore: fix ruff import order in test_ask.py
CI / lint-and-test (push) Failing after 19s
2026-04-22 10:06:07 +02:00
tomas.kracmar f75f165911 feat: Redis caching + async queue for LLM scaling (v1.6.0)
Release / build-and-push (push) Successful in 1m24s
CI / lint-and-test (push) Failing after 29s
- Add async Redis client singleton (redis_client.py) for caching and arq pool
- Add arq job functions (jobs.py) for background LLM processing
- Cache ask/explain LLM responses with TTL (1h ask, 24h explain)
- Add async mode to /api/ask: enqueue job, return job_id, poll /api/jobs/{id}
- Add GET /api/jobs/{job_id} endpoint for job status polling
- Add arq worker service to docker-compose (dev + prod)
- Switch from Redis to Valkey (BSD fork) in Docker Compose
- Add REDIS_URL config setting
- Add tests for cache hit, async mode, and job status
v1.6.0
2026-04-22 09:55:05 +02:00
tomas.kracmar 47e0dfc2ca chore: bump version to 1.5.0
CI / lint-and-test (push) Successful in 37s
Release / build-and-push (push) Successful in 1m51s
v1.5.0
2026-04-22 08:30:20 +02:00
tomas.kracmar 2fffe3aec2 feat: operation-level privacy gating instead of broad service-level
CI / lint-and-test (push) Successful in 21s
- Replace broad service-level hiding with fine-grained operation-level gating
- PRIVACY_SENSITIVE_OPERATIONS config: hide specific operations across ALL services
- PRIVACY_SERVICES still works for broad service-level blocking (optional)
- Users without PRIVACY_SERVICE_ROLES:
  * Don't see sensitive operations in /api/filter-options
  * Can't query sensitive operations via /api/events or /api/ask
  * Get 403 on /api/events/{id}/explain for sensitive events
- Exchange/Teams services remain visible; only privacy ops are hidden
- Update .env.example with new operation-level config docs
2026-04-22 08:23:46 +02:00
tomas.kracmar b2f4cabef4 feat: service-level role gating for privacy-sensitive services (Option A)
CI / lint-and-test (push) Successful in 25s
- Add PRIVACY_SERVICES and PRIVACY_SERVICE_ROLES config variables
- Add user_can_access_privacy_services(claims) helper in auth.py
- /api/events filters out privacy services for users without required roles
- /api/filter-options excludes privacy services from dropdown options
- /api/ask excludes privacy services from NLQ queries
- /api/events/{id}/explain returns 403 for privacy events if unauthorized
- Teams added to default noisy service exclusion (frontend + backend)
- Update .env.example with privacy config documentation
- Add tests for event filtering, filter-options exclusion, and explain 403
2026-04-22 07:26:21 +02:00
tomas.kracmar e069869a94 feat: exclude Teams from defaults + GUID resolution in explain
CI / lint-and-test (push) Successful in 26s
- Add Teams to noisy services excluded by default (frontend + backend ask)
- Exchange, SharePoint, and Teams now unchecked by default in filters
- Enhance explain endpoint with GUID resolution:
  * Extract UUIDs from raw event JSON recursively
  * Resolve directory objects via Graph API (user, group, SP, device)
  * Include resolved names in LLM prompt so explanations reference
    human-readable names instead of raw GUIDs
- Add asyncio import for to_thread wrapper around sync Graph calls
2026-04-22 07:12:10 +02:00
tomas.kracmar fb2386e190 feat: saved searches (bookmarks)
CI / lint-and-test (push) Successful in 23s
- Add saved_searches_collection to database.py with index on created_by+created_at
- New routes/saved_searches.py: GET /api/saved-searches, POST, DELETE
- Saved searches are scoped per user (created_by = token sub)
- Mount router in main.py
- Frontend: Save filters button, saved search pills with load/delete
- loadSavedSearches called on initApp
- applySavedSearch restores filters and validates services against current options
- Add CSS for saved-searches row
- Add tests for CRUD, delete 404, and name validation
2026-04-22 07:04:07 +02:00
tomas.kracmar 05f5f07e7b chore: bump version to 1.4.0
CI / lint-and-test (push) Successful in 30s
Release / build-and-push (push) Successful in 1m24s
v1.4.0
2026-04-22 06:48:47 +02:00
tomas.kracmar 681f7d468a ui: persist filters, default exclude noisy services, true=green
CI / lint-and-test (push) Successful in 32s
- Add 'true' to result pill success keywords (pill--ok)
- Persist filter state to localStorage (loadSavedFilters/saveFilters)
- Default service selection excludes Exchange and SharePoint
- clearFilters resets to default selection (excluding noisy services)
- Restore saved services only if they still exist in current options
2026-04-22 06:41:33 +02:00
tomas.kracmar fb5d45dfb3 chore: bump version to 1.3.2
CI / lint-and-test (push) Successful in 23s
Release / build-and-push (push) Successful in 1m38s
v1.3.2
2026-04-21 22:28:52 +02:00