Skip to content

feat: await Bouncer signup admission before account creation - #7265

Merged
iscekic merged 4 commits into
mainfrom
feat/bouncer-signup-admission
Oct 8, 2026
Merged

iscekic merged 4 commits into
mainfrom
feat/bouncer-signup-admission

Conversation

@iscekic

@iscekic iscekic commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Stack

The ownership cutover is #7267, stacked on this branch.
Merge and deploy this PR before the IP history import and cutover.

Change

  • Await Bouncer signup admission before Stripe customer creation and the new-user transaction.
  • Send optional JA4 from the original x-vercel-ja4-digest header. Normalize valid values and omit malformed values whole.
  • Accept strict merged IP/JA4 signup verdicts with at most five internal flags.
  • Keep existing-user sign-in and provider linking outside signup admission.
  • Preserve the Cloud 100/24h and 150/30d limiter for this first rollout.
  • Fail open after 500 ms, service errors, or invalid verdicts. Return SIGNUP-RATE-LIMITED on enforced rejection.
  • Send the actual authenticated user ID on every signed-in inference route, including organization-paid requests.
  • Keep internal flags in server logs. Update ENVIRONMENT.md with limits, exemptions, counter behavior, and rollout guidance.

Bouncer prerequisite

Bouncer #1 adds a JA4 quota of 10 admissions per rolling 720 hours across IPs.
The IP defaults remain 3 per rolling 30 days and 3 per 24 hours.
enforcement.signup governs IPs. enforcement.signupJa4 governs JA4. The global switch gates both.
Limits and windows change through the Bouncer admin panel without a deployment.
JA4 enforcement ships off. No production enforcement switch changes.
A shared JA4 can represent unrelated users. Evaluate shadow data before enabling JA4 enforcement.
IP exemptions bypass both signup counters. The retained Cloud limiter still applies in this PR.
IP admission remains counted if JA4 or a later creation step rejects. No refund protocol is added.

Verification

  • Related signup selection: 70 Jest tests passed on a Google Cloud VM.
  • The complete changed Bouncer client file passed all 63 tests.
  • Actual Cloud signup reached the Worker and PostgreSQL. JA4 rejection prevented user/provider insertion; sign-in, exemptions, malformed JA4, and shadow behavior passed.
  • A real same-IP creation still failed at Cloud's retained 100-account daily limit.
  • Cloud web typecheck and modified-file lint/format checks passed.
  • Consumer tests prove JA4 and merged-five-flag rejection prevent Stripe and database creation.
  • Consumer tests cover missing/malformed JA4, oversized verdicts, fail-open behavior, and sign-in/linking exclusion.
  • Read-only correctness review found no defects.
  • Earlier VM verification covers user creation, deduplicated retries, sign-in, linking, fail-open behavior, the retained Cloud limiter, and actor exemptions.

Stripe calls use the existing development skip switch. No real Stripe operation or production history import ran.

Rollout

  1. Deploy the Bouncer JA4 service changes without changing enforcement.
  2. Merge and deploy this PR fully.
  3. Import IP history and catch up from refactor: move signup limit ownership to Bouncer #7267. Historical signup JA4 is unavailable; JA4 coverage starts with live reports.
  4. Only Igor enables the independent signup enforcement switches.
  5. Verify live rejection before merging the ownership cutover.

@kilo-code-bot

kilo-code-bot Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Only the incremental commit b26465bd6 was reviewed: it removes a request-body assertion and its now-unused fetchMock binding from the signup-rejection test while keeping the side-effect assertions that prove Stripe and database creation are skipped; no new issues found.

Files Reviewed (1 file)
  • apps/web/src/lib/user/index.test.ts - test-only cleanup, 0 issues
Previous Review Summaries (3 snapshots, latest commit 7aa0c93)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 7aa0c93)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The increment adds optional JA4 reporting: the original x-vercel-ja4-digest header is trimmed, lowercased, and bounded, invalid values are omitted whole so IP admission still runs, and the signup verdict schema accepts the merged five-flag IP/JA4 shape; no new issues found.

Files Reviewed (5 files)
  • ENVIRONMENT.md
  • apps/web/src/lib/user/index.test.ts
  • apps/web/src/lib/user/index.ts
  • packages/web-shared/src/lib/bouncer/client.test.ts
  • packages/web-shared/src/lib/bouncer/client.ts

Previous review (commit d47364c)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change adds the import 'server-only' guard to packages/web-shared/src/lib/bouncer/signup.ts, resolving the previous finding; no new issues were introduced.

Files Reviewed (1 file)
  • packages/web-shared/src/lib/bouncer/signup.ts

Previous review (commit abb3eef)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The Bouncer signup-admission flow is correctly ordered before Stripe and the user transaction and fails open as documented; the only finding is a missing server-only guard in the new shared signup identity module.

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
packages/web-shared/src/lib/bouncer/signup.ts 1 crypto import lacks the folder's import 'server-only' guard
Files Reviewed (16 files)
  • ENVIRONMENT.md - 0 issues
  • apps/web/src/lib/user/index.test.ts - 0 issues
  • apps/web/src/lib/user/index.ts - 0 issues
  • packages/web-shared/src/lib/ai-gateway/handlers/audio-transcriptions.ts - 0 issues
  • packages/web-shared/src/lib/ai-gateway/handlers/edit-completions.ts - 0 issues
  • packages/web-shared/src/lib/ai-gateway/handlers/embeddings.ts - 0 issues
  • packages/web-shared/src/lib/ai-gateway/handlers/fim-completions.ts - 0 issues
  • packages/web-shared/src/lib/ai-gateway/handlers/llm-proxy.test.ts - 0 issues
  • packages/web-shared/src/lib/ai-gateway/handlers/llm-proxy.ts - 0 issues
  • packages/web-shared/src/lib/ai-gateway/typesafe/handler.test.ts - 0 issues
  • packages/web-shared/src/lib/ai-gateway/typesafe/handler.ts - 0 issues
  • packages/web-shared/src/lib/bouncer/client.test.ts - 0 issues
  • packages/web-shared/src/lib/bouncer/client.ts - 0 issues
  • packages/web-shared/src/lib/bouncer/inference.ts - 0 issues
  • packages/web-shared/src/lib/bouncer/signup.ts - 1 issue
  • packages/web-shared/src/lib/config.server.ts - 0 issues

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 33.1K · Output: 2.4K · Cached: 205.4K

Review guidance: REVIEW.md from base branch main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants