Skip to content

improvement(auth): bump better-auth to 1.6.23 and add trusted-proxy client IP resolution#5857

Merged
waleedlatif1 merged 3 commits into
stagingfrom
worktree-better-auth-1624-upgrade
Jul 22, 2026
Merged

improvement(auth): bump better-auth to 1.6.23 and add trusted-proxy client IP resolution#5857
waleedlatif1 merged 3 commits into
stagingfrom
worktree-better-auth-1624-upgrade

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Bump better-auth, @better-auth/sso, and @better-auth/stripe from 1.6.13 to 1.6.23 (1.6.24 was published today and is blocked by our 7-day minimumReleaseAge supply-chain gate; the only change it adds is an emailOTP origin-validation fix we can pick up later)
  • Wire up advanced.ipAddress.trustedProxies (added upstream in 1.6.21) behind a new optional AUTH_TRUSTED_PROXIES env var — comma-separated proxy IPs/CIDRs; the forwarded-IP chain is walked right to left, trusted hops are skipped, and the first untrusted address becomes the client IP
  • This closes the x-forwarded-for spoofing hole in Better Auth's client IP resolution and is the foundation for upcoming org-level security policies (IP allowlisting, session policies, MFA enforcement)

Backwards-compat audit

Three-way audit performed: full release-notes + PR review for all 10 releases, field-by-field DB schema diff (programmatic cross-check of 1.6.23's getAuthTables output for our exact plugin set against @sim/db/schema), and a call-site cross-check of every auth.api.*/client usage against the installed 1.6.23 dist source.

Clean:

  • No DB migrations needed — zero schema changes for our plugin set; the only new column (ssoProvider.domainVerified) is gated behind domainVerification.enabled, which we don't set, and writes to it are dropped by the adapter's schema-field filter
  • Rolling deploy + rollback safe — cookie-cache HMAC/envelope/chunking byte-identical in both versions; 1.6.13 cookies validate under 1.6.23 and vice versa; one-time tokens are format-identical so app/realtime version skew during the deploy window is safe both directions
  • No code changes required — no Sim call site uses /update-session (org activation goes through setActive), no admin call passes role/ban via data, socket reconnects mint fresh one-time tokens (atomic-consume fix is a no-op for us), customSession/databaseHooks/session-config semantics unchanged
  • Bonus fix: invalid cookie-cache now falls through to a DB read instead of returning null (likely resolves the stale-cookie impersonation blank-loader bug)
  • 1.6.23 is the correct landing version — the postgres-js affected-row-count fix (#10257) is required by 1.6.17+'s atomic state transitions; do not stop at 1.6.17–1.6.22

Pre-deploy actions:

  1. SSO account-linking regression (1.6.16): SSO sign-in trust is no longer granted via accountLinking.trustedProviders — our SSO_TRUSTED_PROVIDERS/SSO_TRUSTED_PROVIDER_IDS lists are now inert for SSO. Auto-linking an SSO login to an existing same-email account now requires the IdP to assert a verified email (OIDC email_verified — strictly boolean true/"true" now — or a SAML emailVerified attribute mapping). Audit sso_provider rows before deploy: confirm each tenant's IdP asserts verified email, or affected users get "account not linked" on sign-in
  2. AUTH_TRUSTED_PROXIES MUST be set in cloud prod as part of this deploy — hard requirement, not hygiene. Better Auth'''s built-in rate limiter is on by default in production (sign-in/sign-up: 3 req / 10 s per key, keyed by IP). On 1.6.23, a multi-entry XFF chain with no trustedProxies resolves the client IP to null, and all null-IP requests collapse into one shared no-trusted-ip bucket per path — i.e. the entire user base would share 3 sign-ins per 10 seconds. An attacker can force this on any topology by sending a forged XFF header (LB appends the real IP → multi-entry → null), so blank is also a sign-in DoS vector. Set it to the LB/VPC CIDR (+ CDN egress ranges if one fronts the app). Self-hosters: blank remains functional for single-proxy setups; the var is exposed in docker-compose.prod.yml and the Helm chart

Staging verification list:

  • SAML sign-in per live tenant: assertions missing AudienceRestriction/bearer SubjectConfirmationData are now rejected; audience/recipient must match SP entityID/ACS (per-provider samlConfig.audience is the escape hatch)
  • SSO OIDC sign-in: token/userinfo/jwks endpoints resolving to private addresses are now rejected unless the IdP origin is in TRUSTED_ORIGINS — needs a self-hoster release note
  • genericOAuth smoke pass (sign-in + connector token refresh): token-exchange fetches now refuse 3xx responses; any provider whose tokenUrl redirects (www/apex, region) fails
  • Stripe: billing-portal/checkout returnUrl now validated against trustedOrigins; cancel/restore 400s on subscription rows lacking stripeSubscriptionId (check manually provisioned enterprise rows)
  • Email sign-in/up from non-browser callers: Origin/Referer, when present, is now validated against trustedOrigins even without cookies
  • Watch 429 rates post-deploy (rate limiting is now concurrency-safe and runs before plugin handlers)
  • Support note: email-OTP sign-in by a never-verified password user now deletes their password credential and revokes sessions first (anti-pre-hijack, #10239)

Type of Change

  • Improvement

Testing

  • Typecheck clean
  • 235 auth tests + 1098 organization/billing/SSO/EE tests pass
  • Realtime suite: identical pre-existing failures on staging baseline (env-dependent, unrelated)

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@waleedlatif1
waleedlatif1 requested a review from a team as a code owner July 22, 2026 20:32
@vercel

vercel Bot commented Jul 22, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Jul 22, 2026 9:08pm

Request Review

@cursor

cursor Bot commented Jul 22, 2026

Copy link
Copy Markdown

PR Summary

High Risk
Bumps a security-critical auth stack with upstream behavior changes (forwarded-IP handling, SSO linking, origin checks, rate limiting); production should set AUTH_TRUSTED_PROXIES behind proxies and validate SSO/SAML flows after deploy.

Overview
Upgrades better-auth and the @better-auth/sso / @better-auth/stripe packages from 1.6.13 to 1.6.23 (lockfile included in apps/sim and packages/auth).

Adds optional AUTH_TRUSTED_PROXIES (comma-separated proxy IPs/CIDRs) in env schema, .env.example, docker-compose.prod, and Helm values/schema. When set, auth.ts passes advanced.ipAddress.trustedProxies so Better Auth resolves the real client IP from X-Forwarded-For without trusting spoofed hops.

Updates a billing authorization comment to reference @better-auth/stripe 1.6.23 (no logic change).

Reviewed by Cursor Bugbot for commit eba2cd0. Configure here.

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR upgrades Better Auth and adds trusted-proxy client IP resolution. The main changes are:

  • Bump Better Auth, SSO, and Stripe packages to 1.6.23.
  • Configure trusted proxy IPs and CIDRs through AUTH_TRUSTED_PROXIES.
  • Expose the new setting in local, Docker Compose, and Helm configuration.
  • Record checkout-scope compatibility with the upgraded Stripe plugin.

Confidence Score: 5/5

This looks safe to merge.

  • The checkout-scope update documents compatibility with Stripe plugin 1.6.23 without changing classifier behavior.
  • No distinct production bug remains within the reviewed follow-up changes.

Important Files Changed

Filename Overview
apps/sim/lib/auth/auth.ts Parses the trusted-proxy list and passes it to Better Auth's client IP configuration.
apps/sim/lib/billing/authorization.ts Updates checkout-classifier documentation to record compatibility with Stripe plugin 1.6.23.
apps/sim/lib/core/config/env.ts Adds the optional trusted-proxy environment variable to server configuration.
apps/sim/package.json Upgrades Better Auth and its SSO and Stripe plugins to 1.6.23.
packages/auth/package.json Aligns the shared authentication package with Better Auth 1.6.23.
docker-compose.prod.yml Forwards the trusted-proxy setting into the production container.
helm/sim/values.yaml Adds the trusted-proxy deployment value and usage guidance.
helm/sim/values.schema.json Adds schema validation for the trusted-proxy deployment value.

Reviews (3): Last reviewed commit: "chore(deploy): expose AUTH_TRUSTED_PROXI..." | Re-trigger Greptile

Comment thread apps/sim/package.json
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/lib/core/config/env.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit eba2cd0. Configure here.

@waleedlatif1
waleedlatif1 merged commit c083be9 into staging Jul 22, 2026
21 checks passed
@waleedlatif1
waleedlatif1 deleted the worktree-better-auth-1624-upgrade branch July 22, 2026 21:41
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.

1 participant