What the sign-in gate on this demonstration actually enforces, stated exactly.
Enforced here, now
- Access is enforced at the network edge: server-side middleware authenticates every request,
every method, every path, before any page, script or data is served. There is no
client-side-only gate anywhere.
- One named user account exists; there are no shared or generic logins (the 21 CFR 11.300(a)
pattern).
- The password is stored only as a salted PBKDF2-HMAC-SHA256 hash (100,000 iterations, the
platform's cap, stated rather than padded) in an encrypted platform secret. It appears in no
source code, repository or log, and nothing served to a browser can be used to derive it.
- The session is a signed, browser-bound cookie (HMAC-SHA256): 15 minutes idle, 12 hours
absolute, both enforced at the edge from the signed timestamps, bound to the browser that
signed in, HttpOnly and Secure so scripts cannot read it. (The v4 build uses server-side
revocable session records; the trade is stated below.)
- Sign-in is rate limited per source address (5 failed attempts, then a 15 minute lock that
doubles) with a global backstop, an identical response for every failure cause so nothing
can be learned from the error, and a constant delay on every failure. All comparisons are
constant-time. A Cloudflare Turnstile human challenge is wired in and enforced server-side;
once it is switched on it appears on the form and an automated flood is stopped before any
password check runs.
- Sign-in is two steps: the password, then a 6-digit time-based code (real RFC 6238 TOTP,
the same algorithm Google Authenticator uses). The password alone does not grant access;
it hands out a 5-minute half-session that can reach only the code page, and only the
correct current code mints the full session.
- Every sign-in attempt, lockout, sign-out and expiry is recorded in an append-only log with
UTC time, source address and outcome (the 11.300(d) pattern), viewable signed-in at
/security-log. The application itself cannot write to that log.
- Authenticated responses are never cached (Cache-Control: no-store) and carry a strict
Content-Security-Policy, frame denial and transport security headers.
Stated limits, because a reviewer will find them anyway
- The gate controls who gets in, not what leaves afterwards: the demo is one page whose
fictional data lives in the signed-in viewer's browser.
- The failed-attempt counters use edge storage that cannot count a burst of simultaneous
attempts perfectly, so the lock is a strong brake on serial guessing rather than a hard cap
on parallel guessing. Guessing is held infeasible by the password's own strength, the slow
hash and the constant delay; the Turnstile human challenge, once enabled, removes the
automated-flood case entirely.
- The two-step verification is SIMULATED: a mock authenticator is shown on screen and it
displays the code you enter. Real two-step verification would take the code from your own
device, which never appears on screen. The algorithm and the checking are genuine; the
on-screen phone is the pretend part.
- This build keeps its sessions in a signed, browser-bound cookie rather than a server
record, so the demo works even when the platform's daily write budget is spent. The trade
is that signing out clears the cookie rather than deleting a server-side record; the v4
build (the security showcase) uses server-side revocable sessions.
- The in-app role selector demonstrates an access-model design; it is not a security control,
and the application says so itself.
- This demonstration is not a validated GxP system and claims no Part 11 or Annex 11
compliance. The patterns above are genuinely implemented; certification words are not used.