- Add super admin role system (SUPER_ADMIN_SECRET env var)
- requireSuperAuth middleware for sensitive routes
- isSuperAdminWeb() helper for template access
- Role badge in header (Super Admin / Admin)
- Seed Viewer nav item visible only to super admins
- Add seed phrase viewer with QR code generation
- GET /wallets/seed/:walletId — JSON seed phrase (super admin only)
- GET /wallets/seed-qr/:walletId — QR PNG image (super admin only)
- Modal UI with reveal-on-click, 60s auto-hide countdown
- Copy-to-clipboard and download QR as PNG
- Audit logging for every seed phrase access
- Disable CSRF completely for Tor/onion compatibility
- csrfMiddleware no longer sets _csrf cookie
- validateCsrf and validateCsrfFromBody are no-ops
- res.locals.csrfToken set to empty string (prevents template errors)
- .env.example: document SUPER_ADMIN_SECRET variable
- Removed privileged: true from docker-compose.yml
- Removed SYS_MODULE cap_add (kept NET_ADMIN for WireGuard)
- Removed source code bind mounts (./src, package.json)
- Removed wg0.conf and resolv.conf bind mounts (now generated from env)
- Added resource limits: mem_limit 512m, cpus 1.0
- Added healthcheck with curl
- Added non-root user appuser:appgroup in Dockerfile
- wg0.conf now generated from env vars at container startup (WG_PRIVATE_KEY, etc.)
- resolv.conf generated from WG_DNS env var
- Rotated wg0.conf — private key removed from file
- Added WG_ALLOWED_IPS to .env.example
SECURITY: Rotate WireGuard keys on server if previously used in production