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:
- User enters their email
- A 6-digit OTP is sent to the email (via Brevo SMTP)
- OTP is verified and a Flask session is created
- Session expires after 23 hours
There are no passwords stored in the database. An attacker who steals the database gets no usable credentials.
Guest Download Links¶
Every Lenzeye File Transfer generates a unique download link:
- Token —
secrets.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:
- The Lenzeye server generates a presigned URL — a time-limited, cryptographically signed URL
- The URL includes an HMAC signature from Wasabi — any modification invalidates it
- The browser downloads directly from Wasabi using this URL
- 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_idand a 4-digitlab_pinby 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_portalflag 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) |