Skip to content

Post Deployment

Eric Fitzgerald edited this page Nov 12, 2025 · 1 revision

Post-Deployment

This guide covers verification, testing, and next steps after deploying TMI.

Overview

After deploying all TMI components, you should:

  1. Verify all services are running
  2. Perform smoke tests
  3. Test critical user flows
  4. Set up monitoring and alerts
  5. Document your deployment
  6. Train users (optional)

Deployment Verification

Check All Services

Verify each component is running and accessible.

Web Application

# Check if web app is accessible
curl -I https://tmi.example.com

# Expected: HTTP/2 200 OK

# Verify static assets load
curl -I https://tmi.example.com/main.js

# Expected: HTTP/2 200 OK with Cache-Control headers

In browser:

  1. Navigate to https://tmi.example.com
  2. Verify page loads without errors
  3. Open DevTools Console - should have no errors
  4. Check Network tab - all resources should load (200 OK)

API Server

# Health check
curl https://api.tmi.example.com/version

# Expected response:
{
  "version": "1.0.0",
  "build": "2025-11-12",
  "go_version": "1.24"
}

# Check OAuth providers
curl https://api.tmi.example.com/oauth2/providers

# Expected response with configured providers

PostgreSQL

# Connection test
psql -h postgres-host -U tmi_user -d tmi -c "SELECT version();"

# Check tables exist
psql -h postgres-host -U tmi_user -d tmi -c "\dt"

# Expected: List of TMI tables (users, threat_models, diagrams, etc.)

# Check for data
psql -h postgres-host -U tmi_user -d tmi -c "SELECT count(*) FROM users;"

Redis

# Connection test
redis-cli -h redis-host -p 6379 -a password ping

# Expected: PONG

# Check memory usage
redis-cli -h redis-host -a password info memory | grep used_memory_human

# Check if keys exist
redis-cli -h redis-host -a password DBSIZE

Smoke Tests

Perform basic functionality tests to ensure system works.

Test 1: User Registration via OAuth

  1. Navigate to app: https://tmi.example.com
  2. Click "Login" or appropriate login button
  3. Select OAuth provider (Google, GitHub, or Microsoft)
  4. Authenticate with provider
  5. Verify redirect back to application
  6. Check authentication state:
    • User should be logged in
    • User name/email should display
    • No console errors

Expected Result: User successfully logs in and sees authenticated view.

Test 2: Create Threat Model

After logging in:

  1. Click "New Threat Model" or similar button
  2. Fill in details:
    • Name: "Test Threat Model"
    • Description: "Smoke test"
    • Framework: STRIDE (or other)
  3. Submit
  4. Verify creation:
    • Threat model appears in list
    • Can navigate to threat model detail page
    • No errors in console

Expected Result: Threat model is created and accessible.

Test 3: Create Data Flow Diagram

From threat model detail page:

  1. Click "New Diagram" or similar
  2. Name: "Test Diagram"
  3. Open diagram editor
  4. Add a few shapes:
    • External entity
    • Process
    • Data store
  5. Save
  6. Verify:
    • Diagram appears in list
    • Can reopen diagram
    • Shapes are persisted

Expected Result: Diagram is created and editable.

Test 4: Real-Time Collaboration

Test WebSocket functionality (requires two browsers/users):

User 1:

  1. Open threat model
  2. Open diagram in edit mode
  3. Add a shape

User 2:

  1. Open same diagram
  2. Verify shape appears in real-time

Expected Result: Changes appear instantly for both users.

Test 5: Create Threat

From threat model page:

  1. Click "Add Threat"
  2. Fill in details:
    • Title: "Test Threat"
    • Description: "Testing threat creation"
    • Category: Spoofing (or other)
    • Severity: High
  3. Save
  4. Verify:
    • Threat appears in list
    • Can view threat details
    • Can edit threat

Expected Result: Threat is created and manageable.

Integration Tests

Test integration between components.

OAuth Token Exchange

# This test simulates the OAuth flow programmatically

# Step 1: Get OAuth authorization URL
curl https://api.tmi.example.com/oauth2/providers

# Step 2: Manually authenticate and get authorization code
# (Done in browser, copy code from callback URL)

# Step 3: Exchange code for tokens
curl -X POST https://api.tmi.example.com/oauth2/token?idp=google \
  -H "Content-Type: application/json" \
  -d '{
    "code": "AUTHORIZATION_CODE",
    "state": "RANDOM_STATE",
    "redirect_uri": "https://tmi.example.com/oauth2/callback"
  }'

# Expected: JWT access and refresh tokens

API Authentication

# Test authenticated API call
ACCESS_TOKEN="your-access-token-from-above"

curl https://api.tmi.example.com/threat_models \
  -H "Authorization: Bearer $ACCESS_TOKEN"

# Expected: List of threat models (or empty array)

Database Connectivity

# Verify server can connect to database
# Check server logs for successful connection
journalctl -u tmi -n 100 | grep -i database

# Should show successful connection and migration status

Redis Caching

# Check if cache is working
# After using application, check Redis for cached data
redis-cli -h redis-host -a password --scan --pattern "cache:*"

# Should show various cache keys

Performance Testing

Load Test API Endpoints

Use ab (Apache Bench) or similar:

# Test version endpoint
ab -n 1000 -c 10 https://api.tmi.example.com/version

# Expected:
# - All requests succeed (200 OK)
# - Average response time < 100ms
# - No errors

Test Database Query Performance

-- Check slow queries
SELECT
    query,
    calls,
    mean_exec_time,
    max_exec_time
FROM pg_stat_statements
WHERE mean_exec_time > 10
ORDER BY mean_exec_time DESC
LIMIT 10;

-- Expected: Few or no slow queries

Test Redis Performance

# Benchmark Redis
redis-cli -h redis-host -a password --latency-history

# Expected:
# - Average latency < 1ms
# - No significant spikes

Security Verification

SSL/TLS Configuration

# Check SSL certificate
echo | openssl s_client -servername tmi.example.com \
  -connect tmi.example.com:443 2>/dev/null | \
  openssl x509 -noout -dates

# Verify:
# - Certificate is valid (not expired)
# - Valid for your domain

# Check SSL configuration
curl -I https://tmi.example.com | grep -i "strict-transport-security"

# Expected: HSTS header present

Security Headers

# Check security headers
curl -I https://tmi.example.com

# Should include:
# - Strict-Transport-Security
# - X-Frame-Options
# - X-Content-Type-Options
# - X-XSS-Protection

OAuth Security

Verify OAuth configuration:

  1. Redirect URI validation: Try using wrong redirect URI - should fail
  2. State parameter validation: Try reusing state - should fail
  3. Token expiration: Wait for token to expire, verify refresh works
  4. Logout: Verify tokens are invalidated after logout

Database Security

# Verify database is not publicly accessible
nmap -p 5432 your-public-ip

# Expected: Port 5432 should be filtered or closed

# Try connection from unauthorized host
psql -h postgres-host -U tmi_user -d tmi

# Expected: Connection should be rejected if not from allowed IP

Monitoring Setup

Application Monitoring

Set up health check monitoring:

# Create health check script
cat > /usr/local/bin/tmi-health-check.sh << 'EOF'
#!/bin/bash
ERRORS=0

# Check web app
if ! curl -f -s -o /dev/null https://tmi.example.com; then
    echo "Web app failed"
    ERRORS=$((ERRORS + 1))
fi

# Check API
if ! curl -f -s -o /dev/null https://api.tmi.example.com/version; then
    echo "API failed"
    ERRORS=$((ERRORS + 1))
fi

# Check database
if ! psql -h postgres-host -U tmi_user -d tmi -c "SELECT 1;" > /dev/null 2>&1; then
    echo "Database failed"
    ERRORS=$((ERRORS + 1))
fi

# Check Redis
if ! redis-cli -h redis-host -a password ping > /dev/null 2>&1; then
    echo "Redis failed"
    ERRORS=$((ERRORS + 1))
fi

if [ $ERRORS -gt 0 ]; then
    exit 1
else
    echo "All services healthy"
    exit 0
fi
EOF

chmod +x /usr/local/bin/tmi-health-check.sh

Schedule with cron:

# Add to crontab - run every 5 minutes
*/5 * * * * /usr/local/bin/tmi-health-check.sh || mail -s "TMI Health Check Failed" admin@example.com

Log Aggregation

Set up log collection:

# Check logs are being generated
sudo tail -f /var/log/nginx/access.log
sudo journalctl -u tmi -f

# Consider setting up centralized logging:
# - ELK Stack (Elasticsearch, Logstash, Kibana)
# - Loki + Grafana
# - Splunk
# - Datadog

Metrics Collection

Consider deploying metrics collection:

  1. Prometheus: Collect metrics from TMI server
  2. Grafana: Visualize metrics with dashboards
  3. Node Exporter: System metrics
  4. PostgreSQL Exporter: Database metrics
  5. Redis Exporter: Cache metrics

Alerting

Set up alerts for critical events:

  • API server down
  • Database connection failed
  • Redis unavailable
  • High error rate
  • Slow response times
  • Certificate expiring soon
  • Disk space low

Backup Verification

Test Database Backups

# Perform manual backup
pg_dump -h postgres-host -U tmi_user -d tmi -Fc \
  -f /backup/tmi_test_$(date +%Y%m%d).dump

# Verify backup file exists and has content
ls -lh /backup/tmi_test_*.dump

# Test restore to temporary database
createdb -h postgres-host -U postgres tmi_test_restore
pg_restore -h postgres-host -U tmi_user \
  -d tmi_test_restore /backup/tmi_test_*.dump

# Verify data
psql -h postgres-host -U tmi_user -d tmi_test_restore \
  -c "SELECT count(*) FROM threat_models;"

# Clean up
dropdb -h postgres-host -U postgres tmi_test_restore

Test Redis Backups

# Trigger Redis save
redis-cli -h redis-host -a password BGSAVE

# Check RDB file exists
ls -lh /var/lib/redis/dump.rdb

# Verify AOF if enabled
ls -lh /var/lib/redis/appendonly.aof

Documentation

Document your deployment for future reference and team members.

Deployment Documentation

Create /opt/tmi/DEPLOYMENT_INFO.md:

# TMI Deployment Information

**Deployment Date**: 2025-11-12
**Deployed By**: Your Name
**Environment**: Production

## URLs
- Web Application: https://tmi.example.com
- API Server: https://api.tmi.example.com
- Admin Contact: admin@example.com

## Infrastructure
- Web Server: nginx on server1.example.com (203.0.113.10)
- API Server: TMI v1.0.0 on server2.example.com (203.0.113.11)
- Database: PostgreSQL 15 on db.example.com (internal)
- Cache: Redis 7 on cache.example.com (internal)

## Configuration
- Config Files: /etc/tmi/config-production.yml
- Environment: Production
- OAuth Providers: Google, GitHub
- JWT Expiration: 1 hour

## Backups
- Database: Daily at 2 AM to /backup/postgresql/
- Retention: 7 days
- Redis: RDB + AOF persistence enabled

## Monitoring
- Health Checks: Every 5 minutes via cron
- Logs: /var/log/nginx/, journalctl -u tmi
- Alerts: Email to admin@example.com

## Maintenance
- SSL Certificates: Auto-renewal via Let's Encrypt
- Updates: Manual, test in staging first
- Contact: admin@example.com for issues

Runbook

Create operational runbook for common tasks:

# TMI Operations Runbook

## Starting Services

### Web Application (nginx)
sudo systemctl start nginx

### API Server
sudo systemctl start tmi

### Database
sudo systemctl start postgresql

### Redis
sudo systemctl start redis

## Stopping Services
(Reverse order of starting)

## Restarting After Configuration Change
1. Edit config: /etc/tmi/config-production.yml
2. Validate: ./tmiserver --config=/etc/tmi/config-production.yml --validate
3. Restart: sudo systemctl restart tmi
4. Verify: curl https://api.tmi.example.com/version

## Viewing Logs
- Web: sudo tail -f /var/log/nginx/access.log
- API: sudo journalctl -u tmi -f
- Database: sudo tail -f /var/log/postgresql/postgresql-15-main.log
- Redis: sudo tail -f /var/log/redis/redis-server.log

## Common Issues
See Troubleshooting section below.

User Training

If deploying for a team, consider:

  1. User Documentation: Link to TMI Wiki
  2. Training Session: Walk through creating first threat model
  3. Demo Video: Record tutorial for async learning
  4. Support Channel: Set up Slack/Teams channel for questions
  5. Admin Documentation: Document admin tasks

Next Steps

After successful deployment:

Immediate (Day 1)

  • Monitor logs for errors
  • Watch for failed authentication attempts
  • Verify backups are running
  • Check health check alerts working

Short Term (Week 1)

  • Review security logs
  • Monitor performance metrics
  • Gather user feedback
  • Document any issues encountered
  • Fine-tune performance if needed

Ongoing

  • Regular security updates
  • Monitor resource usage
  • Review and rotate logs
  • Test backup restores monthly
  • Update documentation as needed
  • Plan for scaling if usage grows

Common Post-Deployment Issues

High Memory Usage

Symptom: Server running out of memory.

Solutions:

  • Check Redis memory usage: redis-cli info memory
  • Review PostgreSQL connection count
  • Check for memory leaks in TMI server logs
  • Adjust cache TTL settings
  • Scale up server resources

Slow Response Times

Symptom: Application feels sluggish.

Solutions:

  • Check database query performance
  • Review Redis cache hit rate
  • Enable query logging to find slow queries
  • Optimize database indexes
  • Consider connection pooling
  • Add more server instances

Authentication Failures

Symptom: Users can't log in.

Solutions:

  • Verify OAuth provider credentials
  • Check OAuth callback URLs match
  • Review TMI server logs for token exchange errors
  • Verify JWT secret is set correctly
  • Check OAuth provider status pages

WebSocket Disconnections

Symptom: Real-time collaboration doesn't work.

Solutions:

  • Check reverse proxy WebSocket configuration
  • Verify WebSocket timeout settings
  • Review CORS configuration
  • Check for network issues
  • Verify allowed origins configuration

Rollback Plan

If deployment has critical issues:

Rollback Steps

  1. Stop new TMI server:

    sudo systemctl stop tmi
  2. Restore previous version:

    sudo cp /opt/tmi/tmiserver.backup /opt/tmi/tmiserver
    sudo cp /etc/tmi/config-production.yml.backup /etc/tmi/config-production.yml
  3. Restore database (if schema changed):

    psql -h postgres-host -U tmi_user -d tmi < /backup/pre_deployment_backup.sql
  4. Start previous version:

    sudo systemctl start tmi
  5. Verify rollback:

    curl https://api.tmi.example.com/version
  6. Notify users of temporary issues and rollback

Success Criteria

Your deployment is successful when:

  • All services are running and accessible
  • Users can log in via OAuth
  • Users can create threat models
  • Users can create and edit diagrams
  • Real-time collaboration works
  • No errors in logs (or only expected warnings)
  • Health checks pass consistently
  • Backups are running automatically
  • Monitoring and alerts are active
  • SSL certificates are valid
  • Performance is acceptable
  • Security scan shows no critical issues

Getting Help

If you encounter issues:

  1. Check Documentation:

  2. Review Logs:

    • Application logs
    • Web server logs
    • Database logs
    • System logs
  3. Community Support:

    • GitHub Issues: tmi
    • GitHub Discussions: Share deployment experiences
  4. Professional Support:

    • Contact maintainers for enterprise support
    • Consider hiring DevOps consultant for complex deployments

Congratulations!

You've successfully deployed TMI! Your team can now:

  • Create threat models collaboratively
  • Build data flow diagrams in real-time
  • Document threats systematically
  • Integrate with issue tracking systems
  • Export and share threat models

Related Pages

Clone this wiki locally