9.6 KiB
Admin Security Dashboard - Setup Guide
=== ADMIN SECURITY VISUALIZER ===
This document explains how to configure and use the secure Authentication Admin Dashboard for monitoring security events.
📋 Prerequisites
- Admin User Account: A user account with
role = 'security_admin'in the database - JWT Access Token: Admin must authenticate and obtain a JWT token with admin role
- Environment Variables: Required configuration (see below)
🔧 Configuration
1. Environment Variables
Add the following to your .env file:
# Enable admin dashboard
ENABLE_ADMIN_DASHBOARD=true
# Security alerting webhook (optional but recommended)
SECURITY_ALERT_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
SECURITY_ALERT_MIN_LEVEL=HIGH_RISK
# Admin rate limiting (optional, defaults provided)
ADMIN_RATE_LIMIT_MAX=100
ADMIN_RATE_LIMIT_WINDOW=900
2. Create Admin User
Update a user's role in the database:
UPDATE users
SET role = 'security_admin'
WHERE phone_number = '+919876543210';
Note: The role column must support the value 'security_admin'. If your enum doesn't include this, you may need to update the enum type:
-- Check current enum values
SELECT unnest(enum_range(NULL::listing_role_enum));
-- If needed, add security_admin to the enum
ALTER TYPE listing_role_enum ADD VALUE 'security_admin';
3. CORS Configuration
IMPORTANT: Admin dashboard should NOT be accessible from public origins.
In production, ensure CORS_ALLOWED_ORIGINS only includes trusted domains:
# .env
CORS_ALLOWED_ORIGINS=https://admin.yourdomain.com,https://internal.yourdomain.com
Never use * for CORS when admin endpoints are enabled.
🚀 Usage
1. Obtain Admin Access Token
Admin must authenticate via the normal auth flow:
# Step 1: Request OTP
POST /auth/request-otp
{
"phone_number": "+919876543210"
}
# Step 2: Verify OTP (returns access token)
POST /auth/verify-otp
{
"phone_number": "+919876543210",
"code": "123456"
}
# Response includes:
{
"access_token": "eyJhbGc...",
"refresh_token": "..."
}
2. Access Dashboard
Option A: Browser (with token in localStorage)
- Open browser console
- Set token:
localStorage.setItem('admin_token', 'YOUR_ACCESS_TOKEN') - Navigate to:
https://yourdomain.com/admin/security-dashboard
Option B: API Direct Access
GET /admin/security-events?risk_level=HIGH_RISK&limit=50
Authorization: Bearer YOUR_ACCESS_TOKEN
3. Dashboard Features
- Real-time Event Table: View all authentication events
- Risk Level Filtering: Filter by INFO, SUSPICIOUS, HIGH_RISK
- Search: Search by User ID, Phone, or IP Address
- Statistics: 24-hour event counts by risk level
- Auto-refresh: Automatically updates every 15 seconds
- Manual Refresh: Click "Refresh" button anytime
🔒 Security Protections
✅ Implemented Security Measures
| Security Measure | Implementation |
|---|---|
| RBAC (Role-Based Access) | adminAuth middleware checks role === 'security_admin' |
| JWT Authentication | All admin routes require valid Bearer token |
| Rate Limiting | 100 requests per 15 minutes per admin user |
| Input Validation | All query parameters sanitized and validated |
| SQL Injection Prevention | Parameterized queries only |
| Output Sanitization | All DB fields sanitized before JSON response |
| XSS Prevention | Dashboard uses textContent only (NO innerHTML) |
| Clickjacking Protection | X-Frame-Options: DENY header |
| CORS Restrictions | No public origins allowed |
| Audit Logging | All admin access logged to auth_audit |
| HTTPS Enforcement | HSTS header in production |
| Feature Flag | Dashboard only enabled when ENABLE_ADMIN_DASHBOARD=true |
Security Headers
The dashboard and admin API endpoints include:
X-Frame-Options: DENY- Prevents clickjackingX-Content-Type-Options: nosniff- Prevents MIME sniffingX-XSS-Protection: 1; mode=block- XSS protectionStrict-Transport-Security- HTTPS enforcement (production)
📊 API Endpoints
GET /admin/security-events
Retrieve security audit events with filtering and pagination.
Query Parameters:
risk_level(optional):INFO,SUSPICIOUS, orHIGH_RISKsearch(optional): Search in user_id, phone, or ip_addresslimit(optional): Number of results (1-1000, default: 200)offset(optional): Pagination offset (default: 0)
Response:
{
"events": [
{
"id": "uuid",
"user_id": "uuid",
"action": "otp_verify",
"status": "failed",
"risk_level": "HIGH_RISK",
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"device_id": "device-123",
"phone": "***543210",
"meta": {},
"created_at": "2024-01-01T12:00:00Z"
}
],
"pagination": {
"total": 1000,
"limit": 200,
"offset": 0,
"has_more": true
},
"stats": {
"last_24h": {
"total": 500,
"high_risk": 10,
"suspicious": 50,
"info": 440
}
}
}
Authentication: Required (Bearer token with security_admin role)
🚨 Alerting Integration
The dashboard integrates with the existing triggerSecurityAlert() function in auditLogger.js.
When Alerts Fire
Alerts are sent to SECURITY_ALERT_WEBHOOK_URL for:
- HIGH_RISK Events: All events with
risk_level = 'HIGH_RISK' - Anomaly Detection: Events flagged by
checkAnomalies():- 5+ failed OTP attempts in 1 hour
- 3+ HIGH_RISK events from same IP in 15 minutes
Webhook Payload Format
The webhook receives a Slack-compatible JSON payload:
{
"text": "🚨 Security Alert: HIGH_RISK",
"attachments": [{
"color": "danger",
"fields": [
{"title": "Event Type", "value": "login", "short": true},
{"title": "Risk Level", "value": "HIGH_RISK (high)", "short": true},
{"title": "IP Address", "value": "192.168.1.1", "short": true}
]
}],
"metadata": {
"event_id": "uuid",
"risk_level": "HIGH_RISK",
"severity": "high",
"event_type": "login",
"ip_address": "192.168.1.1"
}
}
Setting Up Slack Webhook
- Go to https://api.slack.com/apps
- Create a new app or select existing
- Enable "Incoming Webhooks"
- Create webhook URL
- Add to
.env:SECURITY_ALERT_WEBHOOK_URL=https://hooks.slack.com/services/YOUR/WEBHOOK/URL
🛡️ Security Best Practices
1. Access Control
- Limit Admin Users: Only grant
security_adminrole to trusted personnel - Rotate Tokens: Admin tokens should be rotated regularly
- Monitor Admin Access: Review
auth_auditlogs for admin actions
2. Network Security
- HTTPS Only: Always use HTTPS in production
- VPN/Private Network: Consider restricting admin dashboard to internal networks
- IP Whitelisting: Optionally restrict admin endpoints by IP at reverse proxy level
3. Token Management
- Short Token TTL: Use shorter access token TTL for admin users (e.g., 5 minutes)
- Token Storage: Store admin tokens securely (never in localStorage for production)
- Logout: Implement proper logout to revoke tokens
4. Monitoring
- Alert on Admin Access: Set up alerts for admin dashboard access
- Review Logs: Regularly review
auth_auditfor admin actions - Anomaly Detection: Monitor for unusual admin access patterns
🐛 Troubleshooting
Dashboard Not Loading
- Check Feature Flag: Ensure
ENABLE_ADMIN_DASHBOARD=truein.env - Check Token: Verify admin token is valid and has
security_adminrole - Check CORS: Ensure your origin is in
CORS_ALLOWED_ORIGINS - Check Console: Open browser console for error messages
403 Forbidden
- User role is not
security_admin - Token is invalid or expired
- CORS origin not whitelisted
401 Unauthorized
- Missing
Authorizationheader - Invalid JWT token
- Token expired
No Events Showing
- Check database connection
- Verify
auth_audittable exists - Check filters (risk_level, search) aren't too restrictive
📝 Files Created/Modified
New Files
src/middleware/adminAuth.js- Admin role check middlewaresrc/middleware/adminRateLimit.js- Rate limiting for admin routessrc/middleware/securityHeaders.js- Security headers middlewaresrc/routes/adminRoutes.js- Admin API endpointspublic/security-dashboard.html- Admin dashboard UI
Modified Files
src/index.js- Added admin route mountingsrc/services/auditLogger.js- Already hastriggerSecurityAlert()(from previous task)
✅ Verification Checklist
ENABLE_ADMIN_DASHBOARD=truein.env- Admin user has
role = 'security_admin'in database - Admin can obtain JWT token via normal auth flow
- Dashboard accessible at
/admin/security-dashboard - API endpoint
/admin/security-eventsreturns data - Security headers present (check browser DevTools)
- Rate limiting works (test with >100 requests)
- Webhook alerts fire for HIGH_RISK events (if configured)
- CORS properly configured (no public origins)
- All admin access logged to
auth_audittable
🔗 Related Documentation
SECURITY_SCENARIOS.md- Security threat scenariosDEVICE_MANAGEMENT.md- Device management featuressrc/services/auditLogger.js- Audit logging implementation
📞 Support
For issues or questions:
- Check browser console for errors
- Review server logs
- Verify database connectivity
- Check environment variables
Last Updated: 2024-01-01 Version: 1.0.0