kveton proposes backend-mediated auth and LLM key encryption across the full stack

kveton/mike describes a security hardening PR that moves sensitive Supabase table access behind backend service-role APIs, encrypts LLM API keys at rest, validates uploaded file bytes before storage, and tightens authorization across document access, project scoping, and direct-share edits. The PR was closed without merging on 2026-05-10.

securityinfrastructure

The core move is taking the browser out of direct contact with sensitive Supabase tables like user_profiles. All reads and writes go through backend profile APIs, with the service role key staying server-side. User LLM API keys (for Anthropic, OpenAI, Gemini, etc.) get encrypted at rest using a new USER_API_KEYS_ENCRYPTION_SECRET, and the frontend only ever sees has_*_api_key booleans - it can tell whether a key is configured but can't read the value. A corresponding DOWNLOAD_SIGNING_SECRET formalizes the backend's control over file download access.

File validation runs before anything hits storage or the conversion pipeline: uploaded PDFs, DOC, and DOCX files get byte-level inspection, with DOCX specifically checked for valid ZIP structure before LibreOffice touches it. This closes a class of malformed-file risks that could otherwise cause conversion failures or worse.

Authorization tightening covers tabular-review document access, project-review scoping, direct-share edit behavior, and chat project membership checks. Raw LLM and document logging were stripped out along with unused frontend server-secret utilities that had no remaining purpose.

Verification included backend tests, builds on both sides, a clean npm audit, and a local smoke test confirming protected routes return 401 without auth. Authenticated Supabase and R2 flows weren't tested because the workspace only had example env files. No diff is available for inspection - the ORIGIN is the PR description only.

So what Worth examining if you're thinking through the browser-to-Supabase trust boundary or need encrypted API key storage. The two-secret pattern (`DOWNLOAD_SIGNING_SECRET`, `USER_API_KEYS_ENCRYPTION_SECRET`) and the lazy-reveal boolean approach for LLM keys are concrete design decisions you could adopt independently. The file validation logic (DOCX zip-structure check before LibreOffice) is a practical hardening step. Since the PR was closed without merging and no commit diffs are available, evaluating the actual implementation requires looking at the PR diff directly in the kushbavaria or kveton fork.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?