bmersereau ↗ analysis ↗ GitHub bmersereau/mike
A security-minded Mike fork focused on safer document handling, access controls, and more dependable legal-AI workflows.
bmersereau's Mike fork is currently aligned with Mike itself, but its surrounding work points to a clear product agenda: make a legal-document workspace safer to operate, easier to share reliably, and less fragile under real-world use.
The focus is practical hardening rather than a rebrand or a new niche. @bmersereau has concentrated on safer authentication and secret handling, protected uploads and downloads, privacy-conscious logging, and guardrails for chat, file storage, and bulk exports. Curious readers can follow the GitHub link for the implementation detail.
What's in it
- Stronger access boundaries A sustained focus on explicit authentication failures, isolated secrets, and database-level access protections.
- Safer document handling Proposed safeguards validate uploaded legal documents and put sensible limits around bulk downloads.
- Privacy-conscious operations The work targets unnecessary identity and document references in operational logs.
- More reliable legal-AI chat Chat histories are bounded and streamed responses are given a clear timeout rather than hanging indefinitely.
- Dependable collaboration Shared-project access is being made less sensitive to harmless differences in email capitalization.
Direction
securityinfrastructureworkflow
Activity
bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub Show 26 more
bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub bmersereau ↗ analysis ↗ GitHub Threads of work (detailed view)
bmersereau gives Mike's interface a much-needed accessibility floor
This is not a redesign, but it should make everyday legal work in Mike feel more consistent and less error-prone.
bmersereau makes Mike's interface kit easier to inspect
A browsable visual catalog could make the product's shared interface patterns clearer to anyone shaping legal workflows.
bmersereau tried to turn Mike's frontend habits into a system
The proposal aimed to make the product more consistent and easier to use without redesigning its look.
bmersereau adds a second lock to Mike's database
A defense-in-depth rewrite so that one careless permission can't quietly expose a table to the outside world.
CONTRIBUTING.md proposed: bug/PR workflow, migration conventions, security disclosure path
bmersereau opened a PR proposing a `CONTRIBUTING.md` for the upstream repo, framed as a first draft for maintainer review. It codifies conventions that already exist in practice and adds a few explicit requirements - notably test coverage and structured migration scripts. The PR is open.
Convert user_id columns from text to uuid with FK constraints
Nine tables in the Mike backend carry `user_id` as plain text, with no referential link to the auth layer. bmersereau's PR converts all of them to the `uuid` type and adds proper foreign keys against `auth.users(id)`, wrapped in a single transaction so the change is all-or-nothing.
Add 180-second timeout to SSE chat streams via Promise.race
bmersereau proposed wrapping the streaming LLM call in both chat routes with a `Promise.race` against a 180-second deadline. Stalled connections now emit a structured SSE error and close cleanly instead of hanging. The PR is open.
Cap bulk zip downloads at 50 documents to prevent in-memory exhaustion
bmersereau proposed a hard ceiling on the bulk zip download route: requests for more than 50 documents get a 400, preventing an authenticated user from triggering simultaneous in-memory loading of an unbounded file set. The PR is open.
Paginate GET /chat with limit and before-cursor parameters
The `GET /chat` endpoint returns an unbounded list of a user's chats. bmersereau adds a `limit` parameter (default 50, cap 200) and a `before` ISO timestamp cursor, letting callers walk back through chat history one page at a time.
Hoist R2 S3Client to a module-level singleton
The Mike backend was allocating a fresh `S3Client` on every R2 operation. bmersereau's PR hoists it to a module-level singleton with lazy initialization, so the HTTP layer can reuse keep-alive connections instead of reopening sockets per request.
Remove JWT-secret fallback from user API key encryption (closed without merge)
bmersereau proposed removing a fallback in the user-API-key encryption helper that would silently reuse the Supabase JWT verification secret when no dedicated encryption secret was configured. The PR closed after two days without merging.
Fix timingSafeEqStr to run the comparison before checking length
The `timingSafeEqStr` helper guarding download tokens was short-circuiting on length mismatch before invoking the constant-time comparison underneath. That early return undermines the whole contract: an attacker with timing access could distinguish a length mismatch from a content mismatch.
Strip user and document IDs from edit-resolution INFO logs
bmersereau opens a PR against upstream to remove INFO-level log lines in the edit-resolution handler that were emitting user identifiers, document identifiers, and edit identifiers alongside internal handler state - all going to whatever log aggregator the deployment uses.
Normalize shared_with email casing across all project access paths
Project sharing in Mike was silently failing for users whose stored email casing didn't match the lookup. bmersereau traces the root cause to three different normalization rules scattered across four endpoints, extracts them into a single access module, and routes every project route through it.
Harden document uploads against XSS and tighten CSP
bmersereau's PR closes three separate security issues at once: stored XSS via malicious uploads, missing Content-Security-Policy headers, and unpatched `@xmldom/xmldom` CVEs. The core fix is magic-byte validation on both upload paths before a file is accepted.
Add expiry to HMAC-signed download tokens, with 30-day default TTL
bmersereau proposed adding an `exp` Unix timestamp to every HMAC-signed download token and rejecting tokens past their expiry on verification. Legacy tokens without `exp` remain valid, so nothing breaks on deploy. The PR is open against upstream.
Replace SHA-256 key derivation with HKDF and per-row salt for stored API keys
Every stored user API key in the Mike backend is currently encrypted with the same derived key - one SHA-256 hash of the master secret. bmersereau replaces that with HKDF (RFC 5869) and a random 16-byte salt per row, so each encryption is independent.
Make per-purpose secrets mandatory and enforce isolation at boot
bmersereau removes the silent fallbacks that let the download token signing secret and the user API key encryption secret quietly reuse the Supabase service key. Both secrets are now required, must be set explicitly, and must be distinct from each other and from the Supabase key - enforced at startup before the server accepts any traffic.
Remove the dev auth bypass that accepted any Bearer token on misconfigured deployments
bmersereau proposed closing a fail-open auth path in the Supabase server helpers: missing env vars previously treated the deployment as a dev environment and accepted any Bearer token as a valid user ID. The PR was closed without merge, so the bypass stayed in upstream.
Pull requests (detailed view)
🟢 Open (2)
bmersereau · opened 2mo ago bmersereau · opened 2mo ago ✅ Merged (2)
bmersereau · opened 2mo ago · merged 2mo ago by willchen96 bmersereau · opened 2mo ago · merged 2mo ago by willchen96 ⛔ Closed without merge (19)
bmersereau · opened 2mo ago · closed 2mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago Show 9 more closed
bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 3mo ago bmersereau · opened 5mo ago · closed 4mo ago bmersereau · opened 5mo ago · closed 5mo ago bmersereau · opened 5mo ago · closed 5mo ago bmersereau · opened 5mo ago · closed 5mo ago bmersereau · opened 5mo ago · closed 5mo ago