# Phase 1 security checklist

## Implemented in this phase

- [x] Password hashes use `password_hash()` and are checked with `password_verify()`.
- [x] Login and password-reset throttling use hashed account/IP identifiers; passwords and reset tokens are not stored in logs.
- [x] Privileged seeded roles require MFA. TOTP secrets are encrypted using AES-256-GCM and a private `APP_KEY`.
- [x] Local-only MFA bypass is opt-in (`APP_LOCAL_MFA_BYPASS=true`) and is ignored unless `APP_ENV=local`; keep it disabled for staging and production.
- [x] PHP sessions use strict mode, HTTP-only, SameSite=Lax cookies and session ID renewal after authentication/MFA.
- [x] Database sessions have server-side expiration and revocation.
- [x] State-changing session-authenticated web/API routes require a CSRF token; bearer-authenticated API routes require a valid Authorization token.
- [x] Database access uses PDO prepared statements with native parameter binding.
- [x] Role permission checks are enforced server-side. User-level denies override role grants. Pro-Vost is not seeded with administrative write permissions.
- [x] Dynamic template values use HTML escaping.
- [x] The front controller sets CSP, anti-framing, content-type, referrer and permission headers; HTTPS enforcement is configurable.
- [x] Password reset tokens are random, hashed at rest, short-lived, single-use and revoke active sessions.
- [x] Student API bearer tokens are random, stored only as SHA-256 hashes, expire after 90 days, are audited on issue/revoke, and are revoked on password reset.
- [x] Security-sensitive setup, login, logout, MFA and password-reset actions create audit entries where an actor exists.
- [x] Private configuration, source code, logs and documents are kept outside the production web root; Apache blocks private local paths.
- [x] Logs are private and structured. Audit records are only appended by application code.
- [x] Initial administrator provisioning is transactionally limited to one user and requires a private setup secret.

## Required before production sign-off

- [ ] Keep `.env`, `APP_KEY`, setup secret, database password and backups outside `public_html`; set least-privilege filesystem/database permissions.
- [ ] Configure production `APP_FORCE_HTTPS=true` only after SSL works; confirm secure cookies, canonical URL and redirects.
- [ ] Rotate/remove `APP_SETUP_KEY` after initial account creation.
- [ ] Verify `APP_KEY` backup and recovery; changing it invalidates encrypted MFA secrets.
- [ ] Configure and test PHP mail delivery, SPF/DKIM and password recovery.
- [ ] Restrict the application's database account from `UPDATE`/`DELETE` on `audit_logs`; reserve DDL and migrations for an administrator account.
- [ ] Test cPanel resource limits, PHP extensions, Cron Jobs, backups, restore procedures and private storage access.
- [ ] Complete an independent penetration/security review before personal or financial records are loaded.
- [ ] Add record-level authorization, secure uploads, MFA recovery procedures and module-specific audit events before implementing those modules.
- [ ] Review Ghana Data Protection Act, 2012 (Act 843) obligations with the institution's privacy/legal lead.

This foundation is not a security certification and has not been tested on a live GoDaddy plan.
