A modern, responsive web interface for managing CrowdSec alerts and decisions. Built with React, Vite, Bun, and Tailwind CSS.
High-level overview of total alerts and active decisions. Statistics and top lists with dynamic filtering.
View detailed logs of security events.
Detailed modal view showing attacker IP, AS information, location with map, and triggered events breakdown.
View and manage active bans/decisions. Supports filtering by status (active/expired) and hiding duplicate decisions.
Ban IPs directly from the UI with custom duration and reason.
Automatically detects new container images on GitHub Container Registry (GHCR). A badge appears in the sidebar when an update is available for your current tag.
- Dark/Light Mode: Full support for both themes.
- Responsive: Optimized for mobile and desktop.
- Real-time: Fast interactions using modern React technology.
Caution
Security Notice: This application does not provide any built-in authentication mechanism. It is NOT intended to be exposed publicly without protection. We strongly recommend deploying this application behind a reverse proxy with an Identity Provider (IdP) such as Authentik, Authelia, or Keycloak to handle authentication and authorization.
- Frontend: React (Vite) + Tailwind CSS. Located in
frontend/. - Backend: Bun (Hono). Acts as an intelligent caching layer for CrowdSec Local API (LAPI) with delta updates and optimized chunked historical data sync.
- Database: SQLite (native bun:sqlite). Persists alerts and decisions locally in
/app/data/crowdsec.dbto reduce memory usage and support historical data. - Security: The application runs as a non-root user (
bun) inside the container and communicates with CrowdSec via HTTP/LAPI. It uses Machine Authentication (User/Password) to obtain a JWT for full access (read/write).
-
CrowdSec: A running CrowdSec instance.
-
Machine Account: You must register a "Machine" (Watcher) for this web UI to allow it to push alerts (add decisions).
- Generate a secure password:
openssl rand -hex 32
- Create the machine:
docker exec crowdsec cscli machines add crowdsec-web-ui --password <generated_password> -f /dev/null
- Generate a secure password:
Note
The -f /dev/null flag is crucial. It tells cscli not to overwrite the existing credentials file of the CrowdSec container. We only want to register the machine in the database, not change the container's local config.
By default, CrowdSec may restrict certain write operations (like deleting alerts) to trusted IP addresses. If you encounter 403 Forbidden errors when trying to delete alerts, you may need to add the Web UI's IP to CrowdSec's trusted IPs list.
Docker Setup: Add the Web UI container's network to the CrowdSec configuration in /etc/crowdsec/config.yaml or via environment variable:
api:
server:
trusted_ips:
- 127.0.0.1
- ::1
- 172.16.0.0/12 # Docker default bridge networkOr using TRUSTED_IPS environment variable on the CrowdSec container:
TRUSTED_IPS="127.0.0.1,::1,172.16.0.0/12"See the CrowdSec documentation for more details on LAPI configuration.
-
Build the image:
docker build -t crowdsec-web-ui .You can optionally specify
DOCKER_IMAGE_REFto override the default image reference used for checking updates (useful for forks or private registries):docker build --build-arg DOCKER_IMAGE_REF=my-registry/my-image -t crowdsec-web-ui . -
Run the container: Provide the CrowdSec LAPI URL and your Machine Credentials.
docker run -d \ -p 3000:3000 \ -e CROWDSEC_URL=http://crowdsec-container-name:8080 \ -e CROWDSEC_USER=crowdsec-web-ui \ -e CROWDSEC_PASSWORD=<your-secure-password> \ -e CROWDSEC_LOOKBACK_PERIOD=5d \ -e CROWDSEC_REFRESH_INTERVAL=0 \ -v $(pwd)/data:/app/data \ --network your_crowdsec_network \ crowdsec-web-ui
Note
Ensure the container is on the same Docker network as CrowdSec so it can reach the URL.
services:
crowdsec-web-ui:
image: ghcr.io/theduffman85/crowdsec-web-ui:latest
container_name: crowdsec_web_ui
ports:
- "3000:3000"
environment:
- CROWDSEC_URL=http://crowdsec:8080
- CROWDSEC_USER=crowdsec-web-ui
- CROWDSEC_PASSWORD=<generated_password>
# Optional: Lookback period for alerts/stats (default: 168h/7d)
- CROWDSEC_LOOKBACK_PERIOD=5d
# Optional: Backend auto-refresh interval. Values: 0 (Off), 5s, 30s (default), 1m, 5m
- CROWDSEC_REFRESH_INTERVAL=30s
# Optional: Idle Mode settings to save resources
# Interval to use when no users are active (default: 5m)
- CROWDSEC_IDLE_REFRESH_INTERVAL=5m
# Time without API requests to consider system idle (default: 2m)
- CROWDSEC_IDLE_THRESHOLD=2m
# Optional: Interval for full cache refresh (default: 5m)
# Forces a complete data reload when active, skipped when idle.
- CROWDSEC_FULL_REFRESH_INTERVAL=5m
volumes:
- ./data:/app/data
restart: unless-stoppedA Helm chart for deploying crowdsec-web-ui on Kubernetes is available (maintained by the zekker6):
https://github.com/zekker6/helm-charts/tree/main/charts/apps/crowdsec-web-ui
To persist alert history, decisions cache, and configuration across container restarts, mount the /app/data directory. All data is stored in a single SQLite database.
Docker Run:
Add -v $(pwd)/data:/app/data to your command.
Docker Compose: Add the volume mapping:
volumes:
- ./data:/app/data-
Install Dependencies: You need Bun installed.
bun run install-all
-
Configuration: Create a
.envfile in the root directory with your CrowdSec credentials:CROWDSEC_URL=http://localhost:8080 CROWDSEC_USER=crowdsec-web-ui CROWDSEC_PASSWORD=<your-secure-password> CROWDSEC_REFRESH_INTERVAL=30s
-
Start the Application: The project includes a helper script
run.shto manage both services.Development Mode (Hot Reload): Starts both backend (port 3000) and frontend (port 5173).
./run.sh dev
Production Mode (Optimized Build): Builds the frontend and starts the backend (port 3000).
./run.sh