A production-grade, zero-trust network intrusion detection system with AI-driven anomaly detection, mutual TLS, hash-chained audit logging, and enterprise-grade identity management.
Features β’ Architecture β’ Tech Stack β’ Quick Start β’ API Reference β’ Security Model β’ Deployment β’ Testing
- Credential stuffing detection β Identifies mass login attempts from a single IP targeting different usernames
- Impossible travel analysis β Flags logins from geographically impossible IP locations in short timeframes
- Brute-force escalation patterns β Detects rapid failure rate increases before account lockout triggers
- Off-hours access monitoring β Alerts on successful authentications outside configured business hours
- Session anomaly detection β Identifies abnormal session creation rates per user
- Dynamic risk scoring β Computes a 0β100 risk score per user/IP based on weighted anomaly signals
- Mutual TLS (mTLS) β Bidirectional certificate-based authentication for all sensor-to-server communication
- Private PKI β Automated certificate lifecycle via step-ca with ACME protocol
- Zero Trust Network Access (ZTNA) β Device identity verification, geo-allowlisting, user-agent filtering, and risk-score-based access gating
- CRL (Certificate Revocation List) β Real-time revocation with 60-second refresh intervals
- Keycloak SSO β OIDC/OAuth2 integration with MFA support for all administrative access
- Role-Based Access Control (RBAC) β Four distinct roles:
Super Admin,Security Analyst,Auditor,Sensor Manager - PII Data Masking β Automatic field-level masking based on JWT role claims
- Session Management β Redis-backed sessions with idle timeout (15 min), absolute timeout (8 hrs), and concurrent session limits
- Hash-chained logs β SHA-256 chain linking each entry to its predecessor, making tampering detectable
- Append-only storage β Immutable log shipping to Grafana Loki
- Structured logging β JSON-structured events via
structlogfor every authentication attempt, config change, and data access
- Centralized secrets β Runtime secret injection via Infisical (self-hosted)
- Automated rotation health checks β Continuous monitoring of certificate expiry, API key age, and secret staleness
- SOPS + age encryption β Encrypted secrets at rest in configuration files
- UUID-based sensor identity β Each sensor registered with unique identifiers
- Short-lived certificates β 30-day auto-rotating certificates via ACME protocol
- Bootstrap enrollment β Single-use, 1-hour API keys for initial sensor onboarding
- CRUD operations β Full sensor lifecycle management through the REST API
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β NIDS Architecture β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β ββββββββββββ mTLS ββββββββββββββββββββββββββββββββββββββββ β
β β Sensor βββββββββββββΊβ FastAPI App (:8000) β β
β β Network β β ββββββββββ¬ββββββββββ¬βββββββββββββ β β
β ββββββββββββ β β Auth β Sensors β Security β β β
β β β Router β Router β Router β β β
β ββββββββββββ OIDC/ β ββββββββββ΄ββββββββββ΄βββββββββββββ€ β β
β βDashboard ββββJWTβββββββΊβ β Middleware Layer β β β
β β (User) β β β ZTNA β Audit β Rate Limit β β β
β ββββββββββββ β βββββββββ΄ββββββββ΄ββββββββββββββββ€ β β
β β β Service Layer β β β
β β β Anomaly β mTLS β Rotation β β β
β β β Lockout β CRL β Session β β β
β β ββββββββββββββββββββββββββββββββββββ β β
β ββββββββββ¬ββββββββ¬ββββββββ¬ββββββββββββββ β
β β β β β
β ββββββββββββββββββββΌββββββββΌββββββββΌβββββββββββ β
β β β β β β β
β βββββββΌββββββ ββββββββΌβββ ββββΌββββ βββΌβββββββ β β
β β MariaDB β βKeycloak β βRedis β β Loki β β β
β β 11.4 β β 26.0 β β 7 β β 3.0 β β β
β βββββββββββββ βββββββββββ ββββββββ ββββββββββ β β
β β β β
β βββββββΌββββββ ββββββββββββ ββββββββββββββββ β β
β β step-ca β βInfisical β β fail2ban β β β
β β (PKI) β β(Secrets) β β(IP Blocking) β β β
β βββββββββββββ ββββββββββββ ββββββββββββββββ β β
β β β β
β βββββββββββββnids-internalβββββββββββββββββββββ β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Network | Access | Services |
|---|---|---|
nids-internal |
Private (no external access) | MariaDB, Redis, Loki, step-ca, Infisical |
nids-frontend |
Bridged (external access) | FastAPI App, Keycloak |
| Layer | Technology | Purpose |
|---|---|---|
| API Framework | FastAPI 0.115+ | Async REST API with automatic OpenAPI docs |
| Language | Python 3.12 | Core application runtime |
| Database | MariaDB 11.4 | Persistent storage for sensors, API keys, audit state |
| Cache / Sessions | Redis 7 (Alpine) | Session storage, rate limiting, anomaly event streams |
| Identity Provider | Keycloak 26.0 | OIDC/OAuth2 SSO, MFA, user federation |
| PKI / mTLS | step-ca (Smallstep) | Private CA, automated cert issuance & renewal |
| Audit Logging | Grafana Loki 3.0 | Append-only, immutable log aggregation |
| Secrets Management | Infisical | Centralized runtime secret injection |
| IP Blocking | fail2ban | Network-level brute-force protection |
| Service Mesh | Linkerd | Internal mTLS, per-route metrics, retries (K8s) |
| Migrations | Alembic | Database schema versioning |
| ORM | SQLAlchemy 2.0 | Async database operations |
| Structured Logging | structlog | JSON-formatted, contextual logging |
| Containerization | Docker + Compose | Multi-service orchestration |
| Orchestration | Kubernetes | Production deployment with NetworkPolicies |
- Docker β₯ 24.0
- Docker Compose β₯ 2.20
- Git
git clone https://github.com/<your-username>/NIDS.git
cd NIDScp .env.example .envOpen .env and replace all change_me_* values with strong, unique passwords:
DB_ROOT_PASSWORD=<strong-password>
DB_PASSWORD=<strong-password>
REDIS_PASSWORD=<strong-password>
KEYCLOAK_ADMIN_PASSWORD=<strong-password>
KEYCLOAK_CLIENT_SECRET=<generated-secret>
STEP_CA_PASSWORD=<strong-password>
INFISICAL_ENCRYPTION_KEY=<32-byte-hex-key>
INFISICAL_AUTH_SECRET=<strong-secret>Tip
Generate secure random passwords with:
openssl rand -base64 32Development (with hot-reload):
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -dProduction:
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -ddocker compose ps| Service | URL | Description |
|---|---|---|
| NIDS API | http://localhost:8000 |
FastAPI application |
| API Docs | http://localhost:8000/docs |
Swagger UI |
| Keycloak | http://localhost:8080 |
Admin console |
| Loki | http://localhost:3100 |
Log aggregation |
| step-ca | https://localhost:9000 |
Certificate authority |
| Infisical | http://localhost:8085 |
Secrets dashboard |
curl http://localhost:8000/healthExpected response:
{
"status": "healthy",
"database": "connected",
"redis": "connected",
"keycloak": "reachable",
"loki": "reachable"
}Base URL: http://localhost:8000
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/auth/login |
Authenticate user via Keycloak | None |
POST |
/auth/logout |
Revoke session and tokens | Bearer JWT |
POST |
/auth/refresh |
Rotate refresh token | Refresh Token |
GET |
/auth/sessions |
List active sessions | Bearer JWT |
DELETE |
/auth/sessions/{id} |
Revoke a specific session | Bearer JWT |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
POST |
/sensors/register |
Register a new sensor | Bearer JWT (Sensor Manager+) |
GET |
/sensors/ |
List all sensors | Bearer JWT |
GET |
/sensors/{id} |
Get sensor details | Bearer JWT |
PUT |
/sensors/{id} |
Update sensor metadata | Bearer JWT (Sensor Manager+) |
DELETE |
/sensors/{id} |
Decommission a sensor | Bearer JWT (Super Admin) |
POST |
/sensors/data |
Submit sensor telemetry | mTLS Certificate |
POST |
/sensors/{id}/api-key |
Generate bootstrap API key | Bearer JWT (Sensor Manager+) |
POST |
/sensors/{id}/certificate |
Issue mTLS certificate | API Key (Bootstrap) |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
GET |
/audit/logs |
Query audit logs | Bearer JWT (Auditor+) |
GET |
/audit/chain/verify |
Verify hash-chain integrity | Bearer JWT (Super Admin) |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
GET |
/security/anomalies |
List detected anomalies | Bearer JWT (Analyst+) |
GET |
/security/risk-score |
Get risk score for user/IP | Bearer JWT (Analyst+) |
GET |
/security/rotation-status |
Check secret/cert rotation health | Bearer JWT (Super Admin) |
| Method | Endpoint | Description | Auth |
|---|---|---|---|
GET |
/health |
System health check | None |
GET |
/health/ready |
Readiness probe (K8s) | None |
Note
Full interactive API documentation is available at /docs (Swagger UI) and /redoc (ReDoc) when the server is running.
The security architecture is organized into three progressive phases:
Phase 1 β Foundation Phase 2 β Enhanced Phase 3 β Advanced
βββββββββββββββββββββ ββββββββββββββββββββ ββββββββββββββββββββββ
β
Keycloak SSO + MFA β
mTLS via step-ca β
AI Anomaly Detection
β
RBAC (4 roles) β
CRL Revocation β
ZTNA Policy Engine
β
Redis Sessions β
Hash-Chained Audit Logs β
Infisical Secrets
β
Brute-Force Protection β
JWT Token Lifecycle β
Linkerd Service Mesh
β
fail2ban IP Blocking β
Data Masking (PII) β
Rotation Health Checks
β
SOPS + age Encryption β
Environment-Aware CORS β
Dynamic Risk Scoring
| Capability | Super Admin | Security Analyst | Auditor | Sensor Manager |
|---|---|---|---|---|
| Manage users & global config | β | β | β | β |
| View dashboards & alerts | β | β | β | β |
| Investigate incidents | β | β | β | β |
| Read audit logs | β | β | β | β |
| Generate/revoke API keys | β | β | β | β |
| View sensor health | β | β | β | β |
| Unmask PII fields | β | β | β | β |
| View raw payloads | β | β | β | β |
| Data Type | Super Admin | Analyst | Auditor | Sensor Manager |
|---|---|---|---|---|
| IP Addresses | Full | Masked | Masked | N/A |
| Hostnames | Full | Masked | Masked | N/A |
| Raw Payloads | Full | Metadata only | Hidden | N/A |
| Usernames | Full | Masked | Masked | N/A |
| Sensor Metadata | Full | Full | Read-only | Full |
# Production with optimized settings
docker compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# View logs
docker compose logs -f app
# Stop all services
docker compose down
# Stop and remove volumes (β οΈ destroys data)
docker compose down -vThe k8s/ directory provides Linkerd service mesh configuration with:
- Namespace-level mTLS injection β All pods in the
nidsnamespace get automatic mTLS sidecars - Deny-all NetworkPolicies β Only explicitly allowed service-to-service traffic is permitted
- ServiceProfile β Per-route metrics and retry policies for the NIDS API
- ServerAuthorization β Only authenticated mesh identities can reach the API
# Install Linkerd
curl -fsL https://run.linkerd.io/install | sh
linkerd install --crds | kubectl apply -f -
linkerd install | kubectl apply -f -
linkerd check
# Apply NIDS manifests
kubectl apply -f k8s/linkerd-annotations.yml
# Verify mesh injection
linkerd viz stat deploy -n nids| Variable | Development | Staging | Production |
|---|---|---|---|
ENVIRONMENT |
development |
staging |
production |
MTLS_ENABLED |
false |
true |
true |
ZTNA_ENABLED |
false |
false |
true |
ANOMALY_DETECTION_ENABLED |
true |
true |
true |
CORS_ORIGINS |
http://localhost:3000 |
https://staging-* |
https://dashboard.* |
The project includes a comprehensive test suite covering all security layers:
# Run all tests
docker compose exec app pytest tests/ -v
# Run specific test modules
docker compose exec app pytest tests/test_anomaly.py -v # AI anomaly detection
docker compose exec app pytest tests/test_auth.py -v # Authentication flows
docker compose exec app pytest tests/test_lockout.py -v # Brute-force protection
docker compose exec app pytest tests/test_ztna.py -v # Zero Trust policies
docker compose exec app pytest tests/test_loki.py -v # Audit logging
docker compose exec app pytest tests/test_rotation.py -v # Secret rotation
# Run with coverage
docker compose exec app pytest tests/ --cov=. --cov-report=html| Module | Tests | Coverage Area |
|---|---|---|
test_anomaly.py |
Credential stuffing, impossible travel, brute-force escalation, risk scoring | |
test_auth.py |
Login, logout, token refresh, session management | |
test_auth_flow.py |
End-to-end authentication workflows | |
test_lockout.py |
Progressive lockout, permanent lock, exponential backoff | |
test_ztna.py |
Device ID enforcement, user-agent filtering, geo-allowlist | |
test_loki.py |
Log shipping, hash-chain integrity, structured events | |
test_rotation.py |
Certificate expiry warnings, secret age checks, health metrics | |
test_data_masking.py |
PII masking per role, unmask audit trail | |
test_sensors.py |
Sensor CRUD, bootstrap enrollment, certificate issuance | |
test_session_keycloak.py |
Idle/absolute timeouts, concurrent session limits | |
test_token_revocation.py |
JWT blacklisting, refresh token rotation | |
test_rate_limits.py |
Per-IP and per-token rate limiting | |
test_compose_security.py |
Docker Compose security configuration validation | |
test_security_regressions.py |
Regression tests for previously fixed vulnerabilities |
NIDS/
βββ app/
β βββ main.py # FastAPI application entry point
β βββ config.py # Pydantic settings with env validation
β βββ database.py # SQLAlchemy async engine & session
β βββ Dockerfile # Production container image
β βββ Dockerfile.dev # Development image with hot-reload
β βββ requirements.txt # Python dependencies
β βββ alembic/ # Database migration scripts
β βββ models/ # SQLAlchemy ORM models
β β βββ sensor.py # Sensor registration & metadata
β β βββ api_key.py # Bootstrap API key model
β β βββ audit_log.py # Audit log entries
β β βββ audit_chain_state.py # Hash-chain state tracking
β βββ schemas/ # Pydantic request/response schemas
β βββ routers/ # API route handlers
β β βββ auth.py # Authentication endpoints
β β βββ sensors.py # Sensor management endpoints
β β βββ audit.py # Audit log queries
β β βββ health.py # Health & readiness probes
β β βββ security.py # Anomaly & risk score endpoints
β βββ services/ # Business logic layer
β β βββ anomaly_service.py # AI-driven anomaly detection engine
β β βββ keycloak_service.py # Keycloak admin API integration
β β βββ mtls_service.py # mTLS certificate operations
β β βββ crl_service.py # CRL refresh loop
β β βββ loki_service.py # Audit log shipping to Loki
β β βββ session_service.py # Redis session management
β β βββ lockout_service.py # Brute-force lockout logic
β β βββ rotation_service.py # Secret & cert rotation health
β β βββ infisical_service.py # Centralized secrets fetching
β β βββ sensor_service.py # Sensor data processing
β β βββ audit_service.py # Audit chain operations
β β βββ token_revocation_service.py # JWT blacklisting
β βββ middleware/ # Request processing pipeline
β β βββ ztna.py # Zero Trust access enforcement
β β βββ audit.py # Request/response audit logging
β β βββ data_masking.py # PII field masking per role
β β βββ rate_limit.py # Rate limiting configuration
β βββ dependencies/ # FastAPI dependency injection
β βββ utils/ # Shared utilities
βββ tests/ # Comprehensive test suite (19 modules)
βββ keycloak/
β βββ realm-export.json # Pre-configured Keycloak realm
βββ loki/
β βββ loki-config.yml # Loki storage & retention config
βββ fail2ban/
β βββ jail.local # fail2ban jail configuration
β βββ filter.d/ # Custom filter rules
βββ k8s/
β βββ linkerd-annotations.yml # Kubernetes + Linkerd manifests
βββ secrets/ # SOPS-encrypted secrets (gitignored)
βββ docker-compose.yml # Base service definitions
βββ docker-compose.dev.yml # Development overrides
βββ docker-compose.prod.yml # Production overrides
βββ init-db.sql # Database initialization script
βββ auth-map.md # Authentication strategy documentation
βββ .env.example # Environment template
βββ .gitignore
All configuration is managed via environment variables with sensible defaults. See .env.example for the full list.
ποΈ Database
| Variable | Default | Description |
|---|---|---|
DB_HOST |
mariadb |
Database hostname |
DB_PORT |
3306 |
Database port |
DB_NAME |
nids |
Database name |
DB_USER |
nids |
Database user |
DB_PASSWORD |
β | Database password (required) |
π Keycloak
| Variable | Default | Description |
|---|---|---|
KEYCLOAK_URL |
http://keycloak:8080 |
Keycloak base URL |
KEYCLOAK_REALM |
nids |
Realm name |
KEYCLOAK_CLIENT_ID |
nids-api |
OIDC client ID |
KEYCLOAK_CLIENT_SECRET |
β | OIDC client secret (required) |
π€ Anomaly Detection
| Variable | Default | Description |
|---|---|---|
ANOMALY_DETECTION_ENABLED |
true |
Enable/disable anomaly engine |
ANOMALY_WINDOW |
3600 |
Sliding window in seconds |
ANOMALY_FAILED_LOGIN_THRESHOLD |
10 |
Failed logins before flagging |
ANOMALY_OFF_HOURS_START |
22 |
Off-hours start (24h) |
ANOMALY_OFF_HOURS_END |
6 |
Off-hours end (24h) |
π‘οΈ ZTNA
| Variable | Default | Description |
|---|---|---|
ZTNA_ENABLED |
false |
Enable Zero Trust enforcement |
ZTNA_REQUIRE_DEVICE_ID |
false |
Require device identity header |
ZTNA_GEO_ALLOWLIST |
"" |
Comma-separated country codes |
ZTNA_RISK_SCORE_THRESHOLD |
70 |
Block if risk score β₯ this value |
π Rotation & Certificates
| Variable | Default | Description |
|---|---|---|
ROTATION_CHECK_INTERVAL |
3600 |
Health check interval (seconds) |
CERT_EXPIRY_WARNING_DAYS |
7 |
Days before cert expiry to warn |
SECRET_MAX_AGE_DAYS |
90 |
Max secret age before rotation alert |
CERT_VALIDITY_DAYS |
30 |
Sensor certificate validity period |
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m 'feat: add my feature' - Push to the branch:
git push origin feature/my-feature - Open a Pull Request
Important
All contributions must include tests. Run the full test suite before submitting a PR.
This project is licensed under the MIT License β see the LICENSE file for details.
Built with security-first principles β’ Every layer verified β’ Zero trust by default