# Security & Deployment Checklist

**Do not deploy this initial source as-is with real salaries, bank numbers or identity documents.** Complete the controls below and review the deployment with qualified staff.

- [ ] Generate unique secrets (`JWT_SECRET`, `BANK_ENCRYPTION_KEY`) and store them in a real secrets manager, never Git.
- [ ] Use HTTPS/TLS through a trusted reverse proxy, secure headers, network firewall and database TLS if remote.
- [ ] Provision a least-privilege MySQL account; do not run Node as database root.
- [ ] Switch from manually initialized schema to versioned migrations and audited rollback strategy.
- [ ] Add a robust account/session strategy (refresh token rotation, account lockout, logout revocation, recovery with identity verification, MFA for Admin).
- [ ] Rate-limit all sensitive endpoints, including uploads and admin changes, and apply an audit trail.
- [ ] Use row/ownership permissions for every newly introduced endpoint. Do not rely on frontend role labels or hidden buttons.
- [ ] Never log passwords, bank details, documents or JWTs. Review request/exception logging.
- [ ] Keep uploaded files in a non-public private store; validate content, scan for malware, backup encrypted, define retention and safe deletion.
- [ ] Encrypt sensitive fields at rest, document encryption key rotation, limit access by role and apply privacy retention policies.
- [ ] Use authenticated SMTP provider; align SPF/DKIM/DMARC and implement an idempotent, retryable worker queue.
- [ ] Set up encrypted backups, restore drills and monitoring/alerting.
- [ ] Load test and perform independent security testing. Add integration tests against real MySQL.
- [ ] Validate Sri Lankan salary, EPF/ETF, withholding and company law with qualified accountants/legal specialists.

## Caveats about the current implementation

- Login returns a short-lived signed JWT, validated on each request against current account status and password reset time. There is **no session revocation table**.
- Bank account digits are AES-256-GCM encrypted at application layer, returning only the last four digits. Key rotation is not implemented.
- Documents are stored locally and kept private from static routes, but malware detection, file lifetime and encrypted-at-rest volume management are not included.
- SMTP email queue delivery is optional; without configured SMTP and worker, notifications will remain pending. Failures are marked `failed`; an operator must examine and retry them.
- App’s current CORS allowlist allows a configured frontend; CORS is not a replacement for authentication.
- Default example `.env` contains placeholders; there are no default passwords or test user accounts in the database.
