# Security operations ## Secrets Rotate `JWT_SECRET`, `PII_ENCRYPTION_KEY`, `PII_PEPPER`, Mongo, SendGrid, Google, and AWS keys after any suspected leak. Do not commit `.env`. Production refuses the default `JWT_SECRET` and `SEED_ADMIN_PASSWORD=Admin@123`. ## PII encryption keys `PII_ENCRYPTION_KEY` is 32 bytes, base64-encoded. `PII_KEY_ID` is stored on each ciphertext (`kid`). To rotate: 1. Generate a new key and a new `PII_KEY_ID`. 2. Keep the old key available until `node scripts/migrate-pii.js` has rewritten every document. 3. Point `PII_ENCRYPTION_KEY` / `PII_KEY_ID` at the new values, then re-run the migration (dual-read still decrypts leftover plaintext). `PII_PEPPER` is used only for `nameHash` / `mobileHash`. Changing it requires recomputing hashes. ## AWS S3 - Block public access on the bucket. - IAM: `s3:PutObject`, `s3:GetObject`, `s3:DeleteObject` on `onboarding/*` only. - Screenshots use SSE-S3. The API issues a GET URL that expires in `S3_PRESIGN_TTL_SEC` (default 10 minutes). - To revoke a leaked URL before expiry, delete or replace the object (new key). Then run `node scripts/migrate-s3.js` for leftover local files. ## Sessions Access JWT lives in the `vpr_access` httpOnly cookie (~15 minutes). Refresh token lives in `vpr_refresh` (7 days) and is hashed in Mongo. Logout and user disable revoke refresh sessions. ## Retention Settings → “Delete rejected/unpaid after (days)” (default 365). A daily job at 03:15 (`APP_TIMEZONE`) deletes matching onboarded rows and their S3 objects. Confirmed patients are never auto-deleted. ## Audit Super Admin → Audit log. Events: login success/failure, screenshot view, onboarding confirm/reject, report export, user disable. No patient names or mobiles are stored. ## Legal Treat onboarded records as personal + health data under the DPDP Act. Keep a DPA with AWS. Limit who may export reports.