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-domainand 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

vercelBot commented Jun 28, 2026

Copy link
Copy Markdown

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

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 28, 2026 2:27am

Request Review

@github-actionsgithub-actionsBot 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 threadpackages/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 mainJun 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 freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@os-zhuang@github-advanced-security