Skip to content

feat(auth): opt-in SSO domain verification — DNS-TXT proof + resultDialog UI (ADR-0024 ②)#2410

Merged
os-zhuang merged 2 commits into
mainfrom
adr-0024-sso-domain-verify
Jun 28, 2026
Merged

feat(auth): opt-in SSO domain verification — DNS-TXT proof + resultDialog UI (ADR-0024 ②)#2410
os-zhuang merged 2 commits into
mainfrom
adr-0024-sso-domain-verify

Conversation

@os-zhuang

Copy link
Copy Markdown
Contributor

What

Adds DNS-TXT domain-ownership verification for external SSO providers — the remaining ② item of the ADR-0024 Unified-Identity V1 plan (per-env external IdP). Gated behind a new OS_SSO_DOMAIN_VERIFICATION flag (off by default).

When off (default): today's behavior is unchanged — register → login immediately.
When on: @better-auth/sso mounts /sso/request-domain-verification + /sso/verify-domain and enforces a hard login gate — a provider whose email domain is not DNS-verified rejects logins (Provider domain has not been verified). These two are coupled in @better-auth/sso (the endpoints only register when domainVerification.enabled), so one flag governs both. This prevents an org admin from registering a provider for a domain they don't control.

Changes

  • auth-manager.ts — new ssoDomainVerification enabled-flag (readBooleanEnv, accepts true/1/yes/on) → passes domainVerification: { enabled: true } to sso(); public isSsoDomainVerificationEnabled() helper.
  • register-sso-provider.tsrunRequestDomainVerification / runVerifyDomain bridges: re-dispatch through the gated better-auth endpoints (so the per-provider admin gate runs) and reshape the response into the { success, data } envelope the action resultDialog reads — request returns the ready-to-paste DNS TXT record ({ dnsRecordName, dnsRecordValue }); verify returns a clear success/error. A bare 404 from the inner endpoint is surfaced as "not enabled for this environment".
  • auth-plugin.ts — mount the two bridges as rawApp routes (/admin/sso/{request-domain-verification,verify-domain}).
  • sys_sso_providerdomain_verified field + list column + Request Domain Verification / Verify Domain actions (request uses resultDialog to one-shot-reveal the DNS record); domainVerified documented in AUTH_SSO_PROVIDER_SCHEMA.

Verification (local prod-like stack, OS_SSO_DOMAIN_VERIFICATION=true)

  • request-domain-verification200 with the exact DNS record (_better-auth-token-<id>.<domain> = _better-auth-token-<id>=<token>); rendered in the action's resultDialog (revealed values match byte-for-byte).
  • verify-domain (no DNS) → 502 + friendly "DNS TXT record not found yet…".
  • Provider org-scoped (organizationId set), domainVerified:false.
  • Hard login gate: sign-in/sso for the unverified domain → 401 Provider domain has not been verified.
  • List shows the Domain Verified column; both row actions appear.
  • The DNS-success path (TXT present → domain_verified:true) is inherently un-testable locally (needs a real domain + DNS TXT) — verified up to that boundary.

The cloud env-runtime mount (AuthProxyPlugin) + .framework-sha bump land in a companion cloud PR.

🤖 Generated with Claude Code

…alog UI (ADR-0024 ②)

OS_SSO_DOMAIN_VERIFICATION (off by default) mounts @better-auth/sso's
/sso/{request-domain-verification,verify-domain} and enforces DNS domain
ownership before an external IdP may sign users in. Adds the request/verify
bridges (envelope-reshaped for the action resultDialog → ready-to-paste DNS TXT
record), the rawApp routes, and the sys_sso_provider domain_verified
field/column + Request/Verify actions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 28, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 28, 2026 2:27am

Request Review

@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tooling and removed size/m labels Jun 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/platform-objects, @objectstack/plugin-auth.

11 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/concepts/implementation-status.mdx (via @objectstack/plugin-auth)
  • content/docs/concepts/packages.mdx (via @objectstack/platform-objects, @objectstack/plugin-auth)
  • content/docs/concepts/setup-app.mdx (via @objectstack/platform-objects)
  • content/docs/getting-started/cli.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/auth-sso.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/authentication.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/kernel-services.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/packages.mdx (via @objectstack/platform-objects, @objectstack/plugin-auth)
  • content/docs/guides/plugins.mdx (via @objectstack/plugin-auth)
  • content/docs/guides/production-readiness.mdx (via @objectstack/plugin-auth)
  • content/docs/releases/v9.mdx (via @objectstack/plugin-auth)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Comment thread packages/plugins/plugin-auth/src/register-sso-provider.ts Fixed
…odeQL js/polynomial-redos)

bareHostname's fallback used a regex on request-controlled input → high-sev
ReDoS alert. Replace with indexOf-based truncation (URL() fast-path kept).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@os-zhuang
os-zhuang merged commit cbc8c02 into main Jun 28, 2026
16 checks passed
@os-zhuang
os-zhuang deleted the adr-0024-sso-domain-verify branch June 28, 2026 02:30
xuyushun441-sys pushed a commit that referenced this pull request Jul 17, 2026
…ole coverage

The previous revision under-covered the line in three ways, now fixed:

1. 15.0.0 was missing everything outside the ADR-0095 theme from the
   14.8.0..15.0.0 range: the strict view/page schema BREAKING change
   (ADR-0089 D3a, #2943) with its migration, the per-row import automation
   chain + skipAutomations + runAutomations-default-ON behavior change
   (#2922), the sys_position/sys_capability system-row write guardrail
   (#2930), the bidirectional visibility lint (#2931), and the explain
   posture-label alignment (#2949).

2. 15.0.0 had NO Console section at all, despite bundling the objectui 14.0
   major (13.2.0→14.0.0, ~73 commits — first release-page disclosure since
   much of it rode unversioned in the 14.8.0 pin): the ADR-0057 ChatDock
   consolidation (including its breaking cleanup #2475), the Gantt batch,
   lists/forms/auth/Studio/i18n enhancements, two security fixes
   (#2485/#2410), and the six early-14.1 commits the 15.0.0 pin picked up.

3. The 15.1.0 sections were over-compressed; every domain is now expanded to
   its full changeset detail, and the Console 14.1 section covers all eight
   areas of the 94-commit range instead of seven bullets.

465 → ~1000 lines; structure mirrors v14.mdx (per-minor annotations inside
one major page, per docs/releases-maintenance.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
os-zhuang added a commit that referenced this pull request Jul 17, 2026
…ole coverage (#3082)

* docs(releases): expand v15 page to full 14.8→15.0→15.1 backend + Console coverage

The previous revision under-covered the line in three ways, now fixed:

1. 15.0.0 was missing everything outside the ADR-0095 theme from the
   14.8.0..15.0.0 range: the strict view/page schema BREAKING change
   (ADR-0089 D3a, #2943) with its migration, the per-row import automation
   chain + skipAutomations + runAutomations-default-ON behavior change
   (#2922), the sys_position/sys_capability system-row write guardrail
   (#2930), the bidirectional visibility lint (#2931), and the explain
   posture-label alignment (#2949).

2. 15.0.0 had NO Console section at all, despite bundling the objectui 14.0
   major (13.2.0→14.0.0, ~73 commits — first release-page disclosure since
   much of it rode unversioned in the 14.8.0 pin): the ADR-0057 ChatDock
   consolidation (including its breaking cleanup #2475), the Gantt batch,
   lists/forms/auth/Studio/i18n enhancements, two security fixes
   (#2485/#2410), and the six early-14.1 commits the 15.0.0 pin picked up.

3. The 15.1.0 sections were over-compressed; every domain is now expanded to
   its full changeset detail, and the Console 14.1 section covers all eight
   areas of the 94-commit range instead of seven bullets.

465 → ~1000 lines; structure mirrors v14.mdx (per-minor annotations inside
one major page, per docs/releases-maintenance.md).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(releases): note post-14.1 fixes carried by the final Console pin (#2615/#2617/#2619/#2620/#2621/#2623)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs(releases): add v15 to the releases index; mark v14 line final at 14.8.0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants