ROADMAP — Chatbot Auth Gating and Subscription Readiness
Status: 🟠Planned
Updated: May 2026
Goals
- Work without OAuth in local and private embed environments.
- Enforce secure auth only where needed (main product site).
- Be ready for a later PRO paywall without re-architecting the chatbot.
- Support script-tag embedding on CORS-allowed sites (for example docs domains).
- Ship with explicit test coverage for auth, origin policy, and fallback behavior.
Context and Constraints
- The chatbot client runs as public browser JavaScript and cannot be trusted for security decisions.
- Secure gating must be enforced in the server entrypoint: Netlify function
chatbot-proxy. - Embed hosts (docs) may not have Supabase OAuth, so forcing account login there would break UX.
- Main app host should be the only host that requires authenticated access to Gemini.
Target Policy (Origin-Based)
| Origin / Host class | MCP search cards | Gemini answer | Auth required |
|---|---|---|---|
Main app (patttterns.com) | Allowed | Allowed | Yes |
Docs/embed hosts (docs.patttterns.com, optional docs.patttterns.net) | Allowed | Allowed (free mode) | No |
Localhost/private preview (localhost, 127.0.0.1) | Allowed | Allowed | No by default (dev mode) |
| Unknown/no origin | Deny by default | Deny | N/A |
Notes:
- This keeps docs embedding useful while protecting paid AI usage on the main app.
- Later, docs hosts can be moved to auth-required by config only.
Security Model
Server-side enforcement (required)
In netlify/functions/chatbot-proxy.mts:
- Parse and classify
Origin. - Decide route policy from env-configured origin classes.
- If policy requires auth:
- Read bearer token from
Authorization. - Validate Supabase JWT server-side.
- Reject with
401if missing/invalid/expired.
- Read bearer token from
- Only after auth pass, execute Gemini flow.
Client-side UX gate (optional but recommended)
In public/chatbot.js:
- On main app host, check local auth session before fetch.
- If unauthenticated, preserve user query and show login CTA.
- Resume automatically after login callback.
Important:
- Client checks improve UX only.
- Proxy validation remains the security control.
Implementation Phases and Estimates
Phase 0 — Policy and Config Contract
Scope:
- Add explicit env variables for origin policy and auth mode.
Deliverables:
CHAT_AUTH_REQUIRED_ORIGINS(CSV or regex map)CHAT_AUTH_OPTIONAL_ORIGINSCHAT_AUTH_DEV_BYPASS(truefor localhost/private by default)CHAT_PRO_REQUIRED(future switch, defaultfalse)
Estimate:
- 0.5 day
Exit criteria:
- Proxy logs show deterministic origin classification for each request.
Phase 1 — Secure Proxy Auth Gate
Scope:
- Implement mandatory server auth validation for protected origins.
Deliverables:
- Token extraction from
Authorization: Bearer <jwt> - Supabase token verification server-side
- Structured 401/403 responses with stable error codes:
auth_requiredauth_invalidpro_required(reserved for Phase 3)
Estimate:
- 1 to 1.5 days
Exit criteria:
- Unauthenticated calls to protected origin are blocked before Gemini execution.
Phase 2 — Chat UX: Login Prompt + Resume Pending Query
Scope:
- Preserve user intent when auth is missing on protected hosts.
Deliverables:
- Store pending query in
sessionStorage - Trigger login flow on protected hosts only
- On callback, auto-open chatbot and replay pending query
- Handle expired session by retrying once after refresh/login
Estimate:
- 1 day
Exit criteria:
- User submits once, logs in, and receives response without retyping.
Phase 3 — PRO Subscription Readiness (No Billing Yet)
Scope:
- Add entitlement checks and response paths without enabling paid plans yet.
Deliverables:
isProclaim source decision:- Supabase JWT claim, or
- profile lookup by user id
- Authorization branch in proxy:
- free users: optional limited mode
- pro users: full Gemini access
- Stable error contract for client rendering (
pro_required)
Estimate:
- 1 to 2 days
Exit criteria:
- Feature can be switched from auth-only to auth+pro via env/config, no client rewrite.
Phase 4 — Embed and CORS Hardening
Scope:
- Make embedding predictable across docs and future partner hosts.
Deliverables:
- Maintain strict CORS allowlist
- Keep auth policy separate from CORS policy
- Add host-specific rate limits (at least app host vs docs host)
- Audit no-origin behavior (default deny)
Estimate:
- 0.5 to 1 day
Exit criteria:
- Docs embed works anonymously; app host remains protected.
Phase 5 — Observability and Abuse Controls
Scope:
- Add monitoring needed before paywall rollout.
Deliverables:
- Logs: origin class, auth result, user id hash, model calls, status code
- Metrics dashboard for 401/403 rates and token failures
- Basic rate limiting and burst protection
Estimate:
- 1 day
Exit criteria:
- Team can detect auth bypass attempts and abnormal Gemini usage quickly.
Testing Plan
A. Unit Tests (Proxy policy and auth)
- Origin classification
- app origin classified as
auth_required - docs origin classified as
auth_optional - localhost classified as
dev_optional - unknown/no origin classified as
deny
- app origin classified as
- Auth guard behavior
- missing bearer token on required origin returns
401 auth_required - invalid token returns
401 auth_invalid - valid token reaches Gemini path
- missing bearer token on required origin returns
- Future PRO branch
- valid token + non-pro claim returns
403 pro_requiredwhenCHAT_PRO_REQUIRED=true - valid token + pro claim returns
200
- valid token + non-pro claim returns
B. Integration Tests (Client + proxy)
- Main app protected flow
- signed out user submits query
- login prompt displayed
- pending query stored
- after login callback, query auto-replayed
- Main app signed-in flow
- bearer token attached
- Gemini call succeeds
- retry behavior works on token-expired path
- Docs/embed flow
- no Supabase session present
- query submits without login prompt
- Gemini call succeeds within docs policy
- Localhost/private flow
- with dev bypass enabled, chat works without OAuth
- with dev bypass disabled, same behavior as protected host
C. E2E and Security Tests
- Direct request abuse test
- send POST to proxy without token for app origin -> blocked
- CORS contract test
- disallowed origin blocked by CORS policy
- Regression tests
- resume conversation still works
- new chat and resume buttons still work
- dark mode sync unaffected
D. Manual QA Checklist
- Protected host: login required before first Gemini call
- Docs host: no forced login
- Pending query replay works after auth
- Error messages are user-readable and non-technical
- No API key or sensitive auth details exposed in client logs
Rollout Strategy
- Deploy Phase 1 behind feature flag.
- Enable for internal users on app host only.
- Enable Phase 2 resume UX.
- Validate metrics for 48 to 72 hours.
- Roll out to all app users.
- Enable Phase 3 entitlement check when subscriptions are ready.
Rollback:
- Disable auth enforcement via env flag while keeping CORS unchanged.
- Keep docs/embed behavior unchanged during rollback.
Risks and Mitigations
- Risk: origin-policy confusion between CORS and auth.
- Mitigation: separate config keys and explicit logs for both decisions.
- Risk: token validation latency increases response time.
- Mitigation: local JWT verification preferred over per-request remote lookup.
- Risk: broken UX if callback replay fails.
- Mitigation: fallback to restoring pending query into input field with one-click resend.
- Risk: docs domain changes (
.comvs.net) cause outages.- Mitigation: centralize allowed embed origins in env config, not hardcoded regex only.
Rough Timeline (Sequential)
- Phase 0: 0.5 day
- Phase 1: 1 to 1.5 days
- Phase 2: 1 day
- Phase 3: 1 to 2 days
- Phase 4: 0.5 to 1 day
- Phase 5: 1 day
Total:
- Auth gate MVP (Phases 0 to 2): about 2.5 to 3 days
- Paywall-ready architecture (Phases 0 to 5): about 5 to 7 days