AlphaLedger uses layered controls so a PA outage, duplicate event, employee account, or database-only disclosure cannot silently alter financial records.
Application controls
- PHP sessions use random cookie identifiers whose SHA-256 hashes are stored in MySQL.
- Session IDs rotate at login and TOTP enrollment. Idle expiry defaults to 15 minutes; absolute expiry is eight hours or seven days for remember-me.
- Session cookies are HttpOnly and SameSite=Strict. They are Secure for every non-loopback deployment; loopback-only HTTP development is the sole permitted exception.
- Symfony CSRF tokens protect every browser mutation.
- Login attempts are rate-limited by hashed IP/identifier bucket. Username/email and password are verified before a separate, five-minute TOTP challenge.
- Optional email reset codes are keyed-hash protected, single-use, limited to five attempts, and expire after five minutes. Public responses do not reveal whether an email exists.
- Docker operator recovery generates a one-time temporary password, revokes sessions, forces a password change, and is audited. There is no permanent recovery administrator.
- Administrators require TOTP. Integration enablement requires password plus TOTP reauthentication.
- Role and ownership checks protect timer, break, report, project, approval, identity, and integration operations.
- AES-256-GCM encrypts PA credentials with a separately persisted 256-bit key.
- The recovery key is shown once and included in verified backup archives.
- Webhooks use HMAC verification, replay windows, durable storage, and event-ID deduplication.
- Security headers deny framing, MIME sniffing, unneeded browser capabilities, and untrusted content sources.
- HTTPS configurations emit one-year HSTS, including subdomains.
- Web and synchronization containers run as the unprivileged
www-datauser.
Operators remain responsible for HTTPS, secret rotation, database network isolation, restore drills, and dependency updates.
Encryption-key handling
The 256-bit AES key is generated atomically in the persistent application-data volume with 0600 permissions. It is never stored in MySQL or committed with the application. The initial administrator receives it once as a recovery key, and that response is marked no-store.
Never delete or replace an existing key when encrypted TOTP or PA credentials exist. Restore the original recovery key instead.
Operator responsibilities
- Terminate TLS at a maintained reverse proxy and keep Secure cookies enabled.
- Restrict MySQL and Docker socket access to trusted operators.
- Protect backup archives as production secrets and keep a separate off-host copy of the one-time recovery key.
- Exercise restore and PA reconnect procedures on a schedule.
- Keep container bases and Composer dependencies current.
- Treat Docker access as administrator-recovery authority and review operator-recovery audit events.
