Feature: CrowdSec Dashboard Integration with Observable Metrics#887
Feature: CrowdSec Dashboard Integration with Observable Metrics#887Wikid82 merged 58 commits intodevelopmentfrom
Conversation
…n-major-updates chore(deps): update dependency knip to ^6.0.5 (feature/beta-release)
|
You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool. What Enabling Code Scanning Means:
For more information about GitHub Code Scanning, check out the documentation. |
✅ Supply Chain Verification Results✅ PASSED 📦 SBOM Summary
🔍 Vulnerability Scan
📎 Artifacts
Generated by Supply Chain Verification workflow • View Details |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
…ec configuration page - Implemented TopAttackingIPsChart component for visualizing top attacking IPs. - Created hooks for fetching CrowdSec dashboard data including summary, timeline, top IPs, scenarios, and alerts. - Added tests for the new hooks to ensure data fetching works as expected. - Updated translation files for new dashboard terms in multiple languages. - Refactored CrowdSecConfig page to include a tabbed interface for configuration and dashboard views. - Added end-to-end tests for CrowdSec dashboard functionality including tab navigation, data display, and interaction with time range and refresh features.
- Added ~40 backend tests covering uncovered branches in CrowdSec dashboard handlers (error paths, validation, export edge cases) - Patch coverage improved from 81.5% to 98.3%, exceeding 90% threshold - Fixed DoD ordering: coverage tests now run before the patch report (the report requires coverage artifacts as input) - Rewrote the local patch coverage DoD step in both the Management agent and testing instructions to clarify purpose, prerequisites, required action on findings, and blocking gate semantics - Eliminated ambiguous "advisory" language that allowed agents to skip acting on uncovered lines
- Removed redundant `gin.SetMode(gin.TestMode)` calls from individual test files. - Introduced a centralized `TestMain` function in `testmain_test.go` to set the Gin mode for all tests. - Ensured consistent test environment setup across various handler test files.
…d Moby privilege validation issues
…e-actions-deploy-pages-5.x
…e-codecov-codecov-action-6.x
…e-eslint-markdown-8.x
…e-eslint-plugin-unicorn-64.x
…e-react-i18next-17.x
…tions-deploy-pages-5.x chore(deps): update actions/deploy-pages action to v5 (feature/beta-release)
…decov-codecov-action-6.x chore(deps): update codecov/codecov-action action to v6 (feature/beta-release)
…asi-threads, @playwright/test, and dotenv for compatibility improvements
…s in configuration files
…e-react-i18next-17.x
…act-i18next-17.x fix(deps): update dependency react-i18next to v17 (feature/beta-release)
…e-non-major-updates
…n-major-updates fix(deps): update non-major-updates (feature/beta-release)
…act-i18next-17.x fix(deps): update dependency react-i18next to v17 (feature/beta-release)
There was a problem hiding this comment.
Pull request overview
Adds a CrowdSec analytics dashboard to the Security section so administrators can observe attack/ban trends directly in the UI, backed by new backend aggregation/storage and updated CI/test protocols.
Changes:
- Add CrowdSec dashboard entry points in the frontend (tabbed UI + lazy-loaded dashboard hooks/components) and corresponding unit tests.
- Enrich backend decision storage for analytics and introduce a small in-memory dashboard cache; centralize
gin.TestModesetup in handler tests. - Update docs/changelog, bump container/dependency versions, and harden CI workflows (explicit permissions, action pin updates, added npm audit step).
Reviewed changes
Copilot reviewed 165 out of 168 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Updates security feature list/marketing copy to mention the CrowdSec analytics dashboard. |
| package.json | Updates devDependencies and adds an override for a transitive dependency. |
| frontend/src/pages/CrowdSecConfig.tsx | Adds Radix Tabs and lazy-loads the new CrowdSec Dashboard tab content. |
| frontend/src/hooks/useCrowdsecDashboard.ts | Introduces React Query hooks for dashboard endpoints (summary/timeline/top IPs/scenarios/alerts). |
| frontend/src/components/tests/TopAttackingIPsChart.test.tsx | Adds unit coverage for the “Top attacking IPs” chart states and accessibility label. |
| frontend/src/components/tests/BanTimelineChart.test.tsx | Adds unit coverage for the ban timeline chart states and accessibility label. |
| docs/features.md | Adds a new high-level marketing feature section for the CrowdSec Dashboard. |
| Dockerfile | Bumps CrowdSec/Caddy-security/Coraza deps and Node builder image; updates pinned grpc version used during build. |
| CHANGELOG.md | Adds release notes for the CrowdSec Dashboard feature. |
| backend/internal/models/security_decision.go | Adds dashboard-enrichment fields and composite indexes to support analytics queries. |
| backend/internal/api/handlers/websocket_status_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/user_integration_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/uptime_monitor_initial_state_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/update_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/testmain_test.go | Adds package-level TestMain to set gin.TestMode for all handler tests. |
| backend/internal/api/handlers/system_permissions_wave6_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/system_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_toggles_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_ratelimit_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_priority_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_notifications_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_notifications_single_source_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_notifications_patch_coverage_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_notifications_final_blockers_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_headers_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_handler_fixed_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_handler_cache_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_handler_authz_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_geoip_endpoints_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/security_event_intake_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/proxy_host_handler_update_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/notification_provider_patch_coverage_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/notification_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/manual_challenge_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/logs_ws_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/logs_handler_coverage_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/import_handler_sanitize_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/health_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/feature_flags_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/feature_flags_blocker3_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/encryption_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/dns_provider_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/dns_detection_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/db_health_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_wave7_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_wave6_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_wave3_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_state_sync_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_pull_apply_integration_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_lapi_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_dashboard_cache.go | Adds a TTL cache used to reduce backend aggregation load for the dashboard. |
| backend/internal/api/handlers/crowdsec_coverage_gap_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_coverage_boost_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_cache_verification_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/crowdsec_archive_validation_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/credential_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/coverage_quick_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/certificate_handler_security_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/certificate_handler_coverage_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/cerberus_logs_ws_test.go | Removes gin.SetMode from init-time setup (now handled by TestMain). |
| backend/internal/api/handlers/backup_handler_sanitize_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/access_list_handler_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| backend/internal/api/handlers/access_list_handler_coverage_test.go | Removes per-test gin.SetMode now that it’s centralized. |
| .github/workflows/waf-integration.yml | Adds explicit contents: read permissions. |
| .github/workflows/supply-chain-pr.yml | Updates pinned upload-sarif action SHA. |
| .github/workflows/security-weekly-rebuild.yml | Adds explicit permissions and updates pinned action SHAs. |
| .github/workflows/security-pr.yml | Adds explicit permissions and updates pinned action SHAs/comments. |
| .github/workflows/repo-health.yml | Adds explicit contents: read permissions. |
| .github/workflows/renovate.yml | Updates pinned Renovate action SHA. |
| .github/workflows/release-goreleaser.yml | Updates pinned setup-go action SHA. |
| .github/workflows/rate-limit-integration.yml | Adds explicit contents: read permissions. |
| .github/workflows/quality-checks.yml | Updates pinned setup-go action SHA; adds frontend npm audit step. |
| .github/workflows/pr-checklist.yml | Adds explicit permissions including pull-requests: write. |
| .github/workflows/history-rewrite-tests.yml | Adds explicit contents: read permissions. |
| .github/workflows/gh_cache_cleanup.yml | Adds explicit contents: read permissions. |
| .github/workflows/docs.yml | Updates pinned deploy-pages action SHA (major version bump). |
| .github/workflows/crowdsec-integration.yml | Adds explicit contents: read permissions. |
| .github/workflows/create-labels.yml | Adds explicit contents: read permissions. |
| .github/workflows/codeql.yml | Updates pinned CodeQL/setup-go action SHAs. |
| .github/workflows/codecov-upload.yml | Updates pinned setup-go and Codecov action SHAs (major version bump). |
| .github/workflows/cerberus-integration.yml | Adds explicit contents: read permissions. |
| .github/workflows/benchmark.yml | Updates pinned setup-go action SHA. |
| .github/workflows/auto-label-issues.yml | Adds explicit contents: read permissions. |
| .github/workflows/auto-changelog.yml | Sets workflow permissions to contents: write. |
| .github/workflows/auto-add-to-project.yml | Adds explicit contents: read permissions. |
| .github/renovate.json | Enables npmDedupe post-update option. |
| .github/instructions/testing.instructions.md | Adjusts testing protocol ordering/requirements for local patch coverage reporting. |
| .github/agents/Management.agent.md | Aligns management agent DoD with updated patch coverage report timing and thresholds. |
…n-major-updates fix(deps): update dependency tldts to ^7.0.28 (feature/beta-release)
…ility improvements
Summary
Adds a CrowdSec analytics dashboard to Charon's Security section, making security posture observable directly from the UI. Previously, viewing attack trends, scenario breakdowns, ban history, or top offenders required SSH access and running
csclicommands. This feature closes that visibility gap.Closes #26
What Changed
Backend: Aggregation API + Model Enrichment
/api/v1/admin/crowdsec/(admin auth required):GET /dashboard/summary— aggregate counts (total decisions, active bans, unique IPs, top scenario, trend %)GET /dashboard/timeline— time-bucketed decision counts with configurable intervals (5m/15m/1h/6h/1d)GET /dashboard/top-ips— top attacking IPs ranked by decision countGET /dashboard/scenarios— scenario breakdown with percentagesGET /alerts— paginated LAPI alerts withcsclifallbackGET /decisions/export— CSV/JSON export with CSV injection protection and 100k row limitScenario,Country,ExpiresAtfields + 3 composite indexes for performant aggregation on large tablesvalidateCrowdsecLAPIBaseURLFuncfrom package-level mutable to instance field onCrowdsecHandler; consolidatedgin.SetModeintoTestMainentrypointFrontend: Dashboard UI + Charts
aria-live="polite"for screen readersrole="radiogroup"with roving tabindex and arrow key navigationReact.lazy()+<Suspense>to avoid loading Recharts on the Configuration tabTesting
Stability Fixes
validateCrowdsecLAPIBaseURLFuncby moving to handler struct fieldgin.SetMode(gin.TestMode)into singleTestMainentrypoint across 80+ test functionsos.Setenv/os.Unsetenvcalls from parallel cookie testsNew API Endpoints
GET/admin/crowdsec/dashboard/summary?range=24hGET/admin/crowdsec/dashboard/timeline?range=24h&interval=1hGET/admin/crowdsec/dashboard/top-ips?range=24h&limit=10GET/admin/crowdsec/dashboard/scenarios?range=24hGET/admin/crowdsec/alerts?range=24h&limit=20&offset=0GET/admin/crowdsec/decisions/export?format=csv&range=24hAll endpoints require admin authentication. Time ranges:
1h,6h,24h,7d,30d.Frontend Components
Accessibility
role="radiogroup"/role="radio"witharia-checked, roving tabindex, Arrow/Home/End key supportaria-live="polite"for dynamic updatesrole="img"with descriptivearia-labelaria-controlsSecurity
validateCrowdsecLAPIBaseURL=,+,-,@are escaped)Performance
React.lazy(Recharts not loaded until tab visited)Quality Gates
-race)Screenshots
Out of Scope