Skip to content

Access Control

Every access point has a gate. No file is accessible without explicit authorization.


Access Control Summary

What How It's Protected
Dashboard login Email OTP verification
File downloads Presigned URL (time-limited) + HMAC verification
Guest download links token (256-bit random) + OTP
Lab Portal Lab ID + 4-digit PIN
Admin panel OTP-based admin authentication
Website data 64-char access token per studio
S3 storage Private bucket — no public access without presigned URL

User Authentication

Lenzeye uses email OTP authentication — no passwords:

  1. User enters their email
  2. A 6-digit OTP is sent to the email (via Brevo SMTP)
  3. OTP is verified and a Flask session is created
  4. Session expires after 23 hours

There are no passwords stored in the database. An attacker who steals the database gets no usable credentials.


Every Lenzeye File Transfer generates a unique download link:

  • Tokensecrets.token_urlsafe(32) — 256-bit cryptographically random, URL-safe
  • OTP — a one-time code generated at link creation time, bound to the token
  • Both are required to access the download manager
  • The token is stored in the database; the OTP is returned to the sender only at creation time

Presigned URLs (File Downloads)

Files in Wasabi S3 are stored in a private bucket — they are not publicly accessible via any URL. To download a file:

  1. The Lenzeye server generates a presigned URL — a time-limited, cryptographically signed URL
  2. The URL includes an HMAC signature from Wasabi — any modification invalidates it
  3. The browser downloads directly from Wasabi using this URL
  4. The URL expires — an old link cannot be reused

This means no permanent credentials are ever shared with a browser.


Lab Portal Access

  • Labs are assigned a unique lab_id and a 4-digit lab_pin by admin
  • The PIN is simple by design — labs are a controlled user group, not the public
  • Lab access is gated by admin assignment (enable_lab_portal flag per user)

File Namespace Isolation

Every user's files are stored under their email as a prefix: {user_email}/{folder}/{filename}

Access to any file requires knowing the full S3 key path and having a valid presigned URL from the Lenzeye server. There is no way to enumerate or access another user's files from the platform.


Session Security

Property Value
Session lifetime 23 hours
SameSite policy Lax
Secure flag False (HTTP in dev, HTTPS in prod via Render)
Session backend Flask server-side session (signed cookie)