Alerta is a scalable alert management system designed to handle alerts from multiple monitoring sources. As a central alert aggregation point with API access and integrations, Alerta requires proper security configuration to protect alert data and prevent unauthorized modifications. This guide covers security measures for production Alerta deployments.
Alerta architecture includes these security-sensitive components:
Key security concerns include API authentication, alert injection prevention, webhook security, database protection, and integration credential management.
Configure firewall rules for Alerta:
# Alerta API Server
ufw allow from 10.0.0.0/8 to any port 8080 proto tcp
# Alerta Web UI (if served separately)
ufw allow from 10.0.0.0/8 to any port 80 proto tcp
ufw allow from 10.0.0.0/8 to any port 443 proto tcp
# Database
ufw allow from 127.0.0.1 to any port 27017 proto tcp # MongoDB
ufw allow from 127.0.0.1 to any port 5432 proto tcp # PostgreSQL
# Block external access
ufw deny from any to any port 8080 proto tcp
ufw deny from any to any port 27017 proto tcp
ufw deny from any to any port 5432 proto tcp
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: alerta-network-policy
spec:
podSelector:
matchLabels:
app: alerta
ingress:
- from:
- namespaceSelector:
matchLabels:
name: monitoring
ports:
- protocol: TCP
port: 8080
Configure Alerta API binding:
# /etc/alertad.conf
# Or environment variables
export ALERTA_SVR_HOST='10.0.1.100'
export ALERTA_SVR_PORT=8080
# For localhost only (recommended with reverse proxy)
export ALERTA_SVR_HOST='127.0.0.1'
Run Alerta with specific binding:
alertad run --host 127.0.0.1 --port 8080
Configure reverse proxy:
# /etc/nginx/sites-available/alerta
server {
listen 80;
server_name alerta.company.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name alerta.company.com;
ssl_certificate /etc/nginx/certs/alerta.crt;
ssl_certificate_key /etc/nginx/certs/alerta.key;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Configure API key authentication:
# /etc/alertad.conf
AUTH_REQUIRED = True
ADMIN_USERS = ['admin', 'ops-lead']
USER_DEFAULT_SCOPES = ['read', 'write:alerts']
ADMIN_DEFAULT_SCOPES = ['read', 'write:alerts', 'write:users', 'read:users', 'write:groups']
# API keys are managed via CLI or API
alerta key create --username admin --text 'Admin API Key'
alerta key create --username monitoring --text 'Monitoring System' --scope read
Configure local user authentication:
# /etc/alertad.conf
AUTH_REQUIRED = True
ADMIN_USERS = ['admin']
ALLOWED_EMAIL_DOMAINS = ['company.com']
# Create users
alerta user create --name 'Admin User' --email 'admin@company.com' --password '${PASSWORD}' --role admin
alerta user create --name 'Operator' --email 'operator@company.com' --password '${PASSWORD}' --role user
Configure LDAP authentication:
# /etc/alertad.conf
AUTH_REQUIRED = True
ADMIN_USERS = ['admin@company.com']
ALLOWED_EMAIL_DOMAINS = ['company.com']
# LDAP settings
LDAP_URL = 'ldap://ldap.company.com'
LDAP_DOMAINS = {
'company.com': 'cn={username},ou=users,dc=company,dc=com'
}
LDAP_BIND_USERNAME = 'cn=alerta,ou=services,dc=company,dc=com'
LDAP_BIND_PASSWORD = '${LDAP_PASSWORD}'
LDAP_USER_BASEDN = 'ou=users,dc=company,dc=com'
LDAP_USER_NAME_ATTR = 'cn'
LDAP_USER_EMAIL_ATTR = 'mail'
Configure OIDC/OAuth2 authentication:
# /etc/alertad.conf
AUTH_REQUIRED = True
ADMIN_USERS = ['admin@company.com']
ALLOWED_EMAIL_DOMAINS = ['company.com']
# OIDC settings
OIDC_AUTH_URL = 'https://sso.company.com/oauth/authorize'
OIDC_TOKEN_URL = 'https://sso.company.com/oauth/token'
OIDC_USER_INFO_URL = 'https://sso.company.com/oauth/userinfo'
OIDC_CLIENT_ID = 'alerta'
OIDC_CLIENT_SECRET = '${OIDC_CLIENT_SECRET}'
OIDC_SCOPE = ['openid', 'profile', 'email']
OIDC_EMAIL_CLAIM = 'email'
OIDC_NAME_CLAIM = 'name'
OIDC_CUSTOM_CLAIMS = {
'roles': {
'admin': ['admin', 'superuser'],
'user': ['user', 'viewer']
}
}
Configure RBAC:
# /etc/alertad.conf
ADMIN_USERS = ['admin@company.com']
USER_DEFAULT_SCOPES = ['read', 'write:alerts']
ADMIN_DEFAULT_SCOPES = ['read', 'write:alerts', 'write:users', 'read:users', 'write:groups', 'read:groups', 'write:blackouts', 'read:blackouts']
# Custom roles
ALLOWED_ROLES = ['admin', 'user', 'viewer', 'operator']
# Scope definitions
# read: View alerts and data
# write:alerts: Create and modify alerts
# write:users: Manage users
# write:groups: Manage groups
# write:blackouts: Manage blackout periods
# admin: Full administrative access
Configure TLS for Alerta API (via reverse proxy):
# /etc/nginx/sites-available/alerta
server {
listen 443 ssl http2;
server_name alerta.company.com;
ssl_certificate /etc/nginx/certs/alerta.crt;
ssl_certificate_key /etc/nginx/certs/alerta.key;
ssl_trusted_certificate /etc/nginx/certs/ca-bundle.crt;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src * data:; font-src 'self' data:; connect-src 'self'" always;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Port $server_port;
}
}
Configure TLS for database connections:
MongoDB:
# /etc/alertad.conf
MONGO_URI = 'mongodb://localhost:27017/monitoring?ssl=true&ssl_ca_certs=/etc/mongodb/ca.crt&ssl_certfile=/etc/mongodb/client.crt&ssl_keyfile=/etc/mongodb/client.key'
PostgreSQL:
# /etc/alertad.conf
DATABASE_URL = 'postgresql://alerta:${DB_PASSWORD}@localhost/alerta?sslmode=require&sslrootcert=/etc/postgresql/ca.crt&sslcert=/etc/postgresql/client.crt&sslkey=/etc/postgresql/client.key'
Secure webhook endpoints:
# /etc/alertad.conf
# Require HTTPS for webhook callbacks
CORS_ORIGINS = ['https://monitoring.company.com']
# Validate webhook signatures
WEBHOOK_SIGNATURE_HEADER = 'X-Webhook-Signature'
Secure Alerta API endpoints:
| Endpoint | Risk Level | Access Control |
|---|---|---|
GET /alerts |
Low | Read scope |
GET /environments |
Low | Read scope |
POST /alert |
Medium | Write:alerts scope |
PUT /alert/{id} |
Medium | Write:alerts scope |
POST /blackout |
Medium | Write:blackouts scope |
POST /users |
High | Write:users scope |
DELETE /alert/{id} |
High | Write:alerts scope |
PUT /config |
Critical | Admin scope |
Implement API rate limiting:
# Nginx rate limiting for Alerta API
limit_req_zone $binary_remote_addr zone=alerta_api:10m rate=30r/s;
location / {
limit_req zone=alerta_api burst=50 nodelay;
proxy_pass http://127.0.0.1:8080;
}
Configure web UI security:
# /etc/alertad.conf
# Web UI settings
WEB_URL = 'https://alerta.company.com'
# Session settings
SESSION_COOKIE_SECURE = True
SESSION_COOKIE_HTTPONLY = True
SESSION_COOKIE_SAMESITE = 'Lax'
PERMANENT_SESSION_LIFETIME = 3600
Secure webhook integrations:
# /etc/alertad.conf
# Webhook authentication
AUTH_REQUIRED = True
# Validate incoming webhooks
# Use API keys for webhook sources
# alerta key create --username prometheus --text 'Prometheus Alertmanager'
# Configure Alertmanager to use API key
# In alertmanager.yml:
# receivers:
# - name: 'alerta'
# webhook_configs:
# - url: 'https://alerta.company.com/webhooks/prometheus'
# http_config:
# bearer_token: '${ALERTA_API_KEY}'
Secure blackout configuration:
# /etc/alertad.conf
# Only admins can create blackouts
ADMIN_USERS = ['admin@company.com']
# Or allow specific roles
USER_DEFAULT_SCOPES = ['read', 'write:alerts']
# Note: write:blackouts not in default scopes
Secure Alerta database:
MongoDB:
# Enable authentication
mongosh --eval "db.createUser({user: 'alerta', pwd: '${DB_PASSWORD}', roles: ['readWrite']})"
# Enable TLS
# In mongod.conf:
# net:
# tls:
# mode: requireTLS
# certificateKeyFile: /etc/mongodb/mongodb.pem
# CAFile: /etc/mongodb/ca.crt
PostgreSQL:
-- Create dedicated database user
CREATE USER alerta WITH PASSWORD '${DB_PASSWORD}';
CREATE DATABASE alerta OWNER alerta;
GRANT ALL PRIVILEGES ON DATABASE alerta TO alerta;
-- Enable SSL requirement
ALTER USER alerta WITH PASSWORD '${DB_PASSWORD}';
Enable database encryption:
MongoDB:
# Enable WiredTiger encryption
# In mongod.conf:
# security:
# encryptionKeyFile: /etc/mongodb/encryption-key
PostgreSQL:
-- Enable TDE (Enterprise Edition)
-- Or use pgcrypto for column-level encryption
CREATE EXTENSION IF NOT EXISTS pgcrypto;
Secure sensitive configuration:
# /etc/alertad.conf
# Use environment variables
SECRET_KEY = '${ALERTA_SECRET_KEY}'
DATABASE_URL = '${DATABASE_URL}'
LDAP_BIND_PASSWORD = '${LDAP_PASSWORD}'
OIDC_CLIENT_SECRET = '${OIDC_CLIENT_SECRET}'
# Or use external secrets file
# exec: source /etc/alertad.secrets
For Kubernetes:
apiVersion: v1
kind: Secret
metadata:
name: alerta-secrets
type: Opaque
data:
secret-key: <base64-encoded>
database-url: <base64-encoded>
ldap-password: <base64-encoded>
Protect sensitive alert data:
# /etc/alertad.conf
# Filter sensitive attributes
# Use plugins to redact sensitive data
# Example: Redact password fields
# plugins:
# - redact
# REDACT_FIELDS = ['password', 'secret', 'token', 'api_key']
Enable logging:
# /etc/alertad.conf
LOG_FILE = '/var/log/alerta/alertad.log'
LOG_MAX_BYTES = 10485760 # 10MB
LOG_BACKUP_COUNT = 5
LOG_LEVEL = 'INFO'
# Audit logging
AUDIT_TRAIL = ['admin'] # Log admin actions
Configure reverse proxy access logging:
# /etc/nginx/sites-available/alerta
access_log /var/log/nginx/alerta_access.log combined;
error_log /var/log/nginx/alerta_error.log warn;
Monitor Alerta for security events:
#!/bin/bash
# /usr/local/bin/check-alerta-security.sh
# Check for failed authentication
FAILED_AUTH=$(grep -c "401 Unauthorized" /var/log/alerta/alertad.log 2>/dev/null || echo 0)
if [ "$FAILED_AUTH" -gt 50 ]; then
echo "CRITICAL: Multiple authentication failures"
exit 2
fi
# Check for alert injection attempts
INJECTION=$(grep -c "POST /alert.*400" /var/log/alerta/alertad.log 2>/dev/null || echo 0)
if [ "$INJECTION" -gt 20 ]; then
echo "WARNING: Possible alert injection attempts"
exit 1
fi
Forward logs to SIEM:
# /etc/rsyslog.d/alerta.conf
:programname, isequal, "alertad" /var/log/alerta/syslog.log
:programname, isequal, "alertad" @siem.company.com:514