Skip to main content

Runbooks

Common operational procedures for managing ThreatWeaver in both local development and production environments.

Restart the Backend​

Local​

# Find and kill the running process
lsof -ti:4005 | xargs kill

# Restart
cd backend && npm run dev

Production (Render)​

  1. Go to the Render dashboard
  2. Navigate to the threatweaver-backend service
  3. Click Manual Deploy > Deploy latest commit
  4. Monitor the deploy log for errors

For EC2 deployments (legacy):

ssh ubuntu@<ec2-host>
pm2 restart threatweaver-backend
pm2 logs threatweaver-backend --lines 50

Run Database Migrations​

Local​

cd backend
npm run migrate:local # synchronize schema + seed data

Development / UAT​

cd backend
npm run migrate:dev # multi-tenant aware, cloud DB

Production​

cd backend
npm run migrate:production # transaction-safe, validated

Check Migration Status​

cd backend
npm run migrate:status # shows applied vs pending migrations

Access the Database​

Local (Docker)​

docker-compose exec -T postgres psql -U tenable -d tenable_dashboard

Production (Supabase)​

Use the Supabase dashboard SQL editor, or connect via psql:

psql "postgresql://user:password@host:5432/database?sslmode=require"

Useful Queries​

-- Count findings by status
SELECT status, count(*) FROM pentest_findings GROUP BY status;

-- Check sync status
SELECT * FROM sync_logs ORDER BY created_at DESC LIMIT 5;

-- View active assessments
SELECT id, status, target_url, created_at
FROM pentest_assessments
WHERE status IN ('running', 'pending')
ORDER BY created_at DESC;

-- Check user count per tenant
SELECT tenant_id, count(*) FROM users GROUP BY tenant_id;

Trigger an AppSec Scan​

Via API​

# Authenticate
TOKEN=$(curl -s -X POST http://localhost:4005/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@company.com","password":"Admin123@same!"}' \
| jq -r '.token')

# Create assessment and trigger scan
curl -X POST http://localhost:4005/api/appsec/assessments \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"targetUrl":"http://target:8080","scanType":"graybox"}'

Via UI​

  1. Navigate to AppSec > Assessments
  2. Click New Assessment
  3. Configure target URL, scan type (black/gray/white box), and authentication
  4. Click Start Scan

Pre-Scan Checklist​

  • Archive previous findings before rescanning the same target
  • Verify target is reachable from the backend
  • Confirm authentication credentials are valid (for gray/white box)

Check Logs​

Backend Logs (Local)​

The backend logs to stdout in development. Check the terminal running npm run dev.

Backend Logs (Render)​

  1. Go to Render dashboard > threatweaver-backend
  2. Click Logs tab
  3. Filter by timeframe or search for specific terms

Frontend Logs​

Check the browser developer console (F12 > Console).

Roll Back a Deployment​

Backend (Render)​

  1. Go to Render dashboard > threatweaver-backend > Events
  2. Find the last successful deployment
  3. Click Redeploy on that commit
  4. Verify health: curl https://your-backend-url/api/auth/health

Frontend (Vercel)​

  1. Go to Vercel dashboard > project > Deployments
  2. Find the last stable deployment
  3. Click the three-dot menu > Promote to Production
  4. Verify by loading the frontend URL

Database Rollback​

Migrations are forward-only. To reverse a migration:

  1. Write a new migration that undoes the problematic changes
  2. Test locally: npm run migrate:local
  3. Deploy through the normal pipeline

Clear Redis Cache​

Redis is used only in production (Upstash). It is not available in local development.

Via Backend API​

curl -X POST http://localhost:4005/api/admin/cache/clear \
-H "Authorization: Bearer $TOKEN"

Direct (Upstash)​

Use the Upstash console to flush the cache, or use the Redis CLI:

redis-cli -u $REDIS_URL FLUSHDB

Emergency Admin Reset​

If the admin account is locked out:

cd backend
npm run admin:emergency-reset

This resets the admin password and unlocks the account.

Archive Findings Before Rescan​

Before triggering a rescan on any target, archive the existing findings:

# Via API
curl -X POST http://localhost:4005/api/appsec/assessments/<assessment-id>/archive \
-H "Authorization: Bearer $TOKEN"

Or from the UI: AppSec > Assessments > select assessment > Archive.

This prevents duplicate findings from accumulating across scan rounds.