Production Checklist
Production Checklist
Section titled “Production Checklist”Use this checklist to verify your Mantis deployment is ready for production.
Security
Section titled “Security”Authentication
Section titled “Authentication”- Changed default admin password
- JWT secret is cryptographically random (32+ characters)
- JWT private key is secured (file permissions 400)
- Session tokens have appropriate expiry
TLS/mTLS
Section titled “TLS/mTLS”- Valid TLS certificates installed (not self-signed)
- mTLS enabled for client authentication
- Registration tokens created with
auto_approvedisabled (new clients reviewed before approval) - Certificate expiration monitoring configured
- CA private key stored securely (HSM or secrets manager)
Encryption
Section titled “Encryption”-
MANTIS_ENCRYPTION_KEYis a secure 32-byte base64 value - Encryption key stored in secrets manager (not in .env)
- Key rotation procedure documented
Access Control
Section titled “Access Control”- RBAC roles configured appropriately
- Principle of least privilege applied
- Admin accounts limited and audited
- SSO/OIDC configured (if applicable)
Configuration
Section titled “Configuration”Environment
Section titled “Environment”- Log level set to
infofor all services (not debug/trace):RUST_LOG=infofor Mandible,MANTIS_LOG_LEVEL=infofor Thorax,TARSUS__LOG_LEVEL=infofor Tarsus - Lens production build served (no dev server, source maps disabled)
- CORS origins restricted to actual domains
- All default passwords changed
Database
Section titled “Database”- External/managed PostgreSQL 16
- Migration role can
CREATE ROLEand owns the audit tables — migrations create themantis_audit_*roles and applyFORCE ROW LEVEL SECURITY, and fail outright on a managed instance that grants neither - Connection pooling configured appropriately (
database.max_connectionsdefaults to 10 per Mandible replica) - SSL/TLS enabled for database connections
- Database credentials in secrets manager
Message Queue
Section titled “Message Queue”RabbitMQ is off by default — Mantis falls back to database polling. Skip this
section unless you set queue.enabled = true.
- External/managed RabbitMQ (not containerized)
- TLS enabled for all connections (port 5671)
- Queue credentials secured
- External/managed Redis (not containerized)
- AUTH password configured
- TLS enabled (if supported)
Infrastructure
Section titled “Infrastructure”Network
Section titled “Network”- Only Lens, Mandible, and Thorax exposed externally
- Database/RabbitMQ/Redis on internal network only
- Firewall rules configured
- Rate limiting enabled
Reverse Proxy
Section titled “Reverse Proxy”- TLS termination configured
- X-Forwarded headers passed correctly
- DDoS protection enabled
- Request size limits configured
Scaling
Section titled “Scaling”- Multiple Thorax instances for HA (if needed)
- Load balancer configured
- Health checks configured
Operations
Section titled “Operations”Monitoring
Section titled “Monitoring”- Health endpoints monitored
- Prometheus metrics collected — Thorax only. It exposes
/metricsonTHORAX_METRICS_BIND_ADDR(default0.0.0.0:9090); Mandible collects metrics in-process but exposes no endpoint, and Tarsus exports none - Alerting configured for critical issues
- Certificate expiration alerts
Logging
Section titled “Logging”- Centralized logging configured
- Deployment-log retention configured at
PUT /api/v1/admin/log-retention— off by default, so logs accumulate indefinitely until it is set - If archiving deployment-log output, a destination is configured and
POST /api/v1/admin/log-retention/verify-archivesreturns every archive intact - Audit logs enabled and monitored
- No sensitive data in logs
Backup
Section titled “Backup”- Database backup schedule configured
- Backup restoration tested
- CA certificate/key backed up securely
- Disaster recovery plan documented
Compliance
Section titled “Compliance”- Audit logging enabled
- Audit retention is never automatic — there is no schedule or purge job. Entries are immutable and the triggers block row deletion; ageing data out means archiving a completed quarterly partition and dropping it, which an administrator invokes deliberately. The chain is verified and the archive read back first, and the operation refuses if either fails
- Audit chain verification run periodically, and its recorded history reviewed at
GET /api/v1/audit/integrity/{tenant_id}/history
Documentation
Section titled “Documentation”- Runbooks for common operations
- Incident response procedures
- Contact information documented
Final Verification
Section titled “Final Verification”./docker.sh health is a local docker-compose helper: it runs pg_isready and
rabbitmq-diagnostics inside compose containers, so it cannot reach the
external PostgreSQL and RabbitMQ this checklist mandates, and it checks neither
Thorax, Tarsus nor Redis. Verify the services individually instead:
# Mandible: database connectivity only -- this endpoint performs no# security checks, despite the name suggesting otherwisecurl -s https://your-domain/api/v1/health | jq
# Readiness and the gRPC dependencycurl -s https://your-domain/api/v1/health/ready | jqcurl -s https://your-domain/api/v1/health/grpc | jq
# Thoraxcurl -s http://thorax-host:9090/metrics | head