Skip to content

fix(enumeration): Document corner case with required password and OAuth#3368

Open
dmoerner wants to merge 6 commits into
mainfrom
daniel/update-copy-on-oauth-required-password-combo
Open

fix(enumeration): Document corner case with required password and OAuth#3368
dmoerner wants to merge 6 commits into
mainfrom
daniel/update-copy-on-oauth-required-password-combo

Conversation

@dmoerner

@dmoerner dmoerner commented May 13, 2026

Copy link
Copy Markdown
Contributor

🔎 Previews:

What does this solve? What changed?

While trying to debug an unrelated issue for Venice.ai, we realized their custom components produce a confusing flow for users who sign up with a social provider but then try to use their email to sign in.

Document a known corner case where instances with password required can still have accounts without passwords if the accounts were created from an OAuth sign up. Since we cannot reveal that an account exists without a password, users who try to sign in with the email on their OAuth account can try to enter a password, and it will be rejected as if it's a bad password. They should try another method, which our components are designed to allow.

Frankly the UX here is kind of bad no matter what, this is one of the frictions that we just need to document I think.

Deadline

No rush

Other resources

https://clerkinc.slack.com/archives/C0849EDL529/p1778700671865669

Document a known corner case where instances with password required can
still have accounts without passwords if the accounts were created from
an OAuth sign up. Since we cannot reveal that an account exists without
a password, users who try to sign in with the email on their OAuth
account can try to enter a password, and it will be rejected as if it's
a bad password. They should try another method, which our components are
designed to allow.
@dmoerner dmoerner requested a review from a team as a code owner May 13, 2026 19:56
@vercel

vercel Bot commented May 13, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
clerk-docs Ready Ready Preview Jun 12, 2026 9:18pm

Request Review

@alexisintech alexisintech self-assigned this May 13, 2026
@alexisintech

Copy link
Copy Markdown
Member

I've posted a docs review that updates the copy to make it a bit more clear on the situation that can happen, such as explicitly stating that this only occurs if the user tries signing in with the email on their OAuth account.

however, I'd like @manovotny opinion on how we should frame this!

@dmoerner

Copy link
Copy Markdown
Contributor Author

Thanks, Alexis! I'm also looking into a backend change that will allow C1s to toggle the default authentication response on the AIO component, which could help smooth this out, and which we would also want to document here.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@manovotny

Copy link
Copy Markdown
Contributor

however, I'd like @manovotny opinion on how we should frame this!

@alexisintech I like your docs review commit. Definitely heading in the right direction. I just broke up the paragraph a bit more. I also think adding a bit more context around triggers and prebuilt-components could help. I pushed those changes directly in e0141d2.

  • The trigger is password.enabled, not password.required. OAuth sign-ups produce passwordless accounts even when password is required at sign-up — there's actually an inline comment in the backend that says exactly this. The PR title's "required password" framing threw me for a second; the doc copy's "password is enabled" framing is correct. I expanded the lead to call out that this gap exists even when password is required, since that's the most surprising part.
  • Why this is strict-enumeration-specific: I dug into createAttemptor in the password sign-in path — without strict enumeration, this case returns a strategy_for_user_invalid error. The "looks like a bad password" behavior only happens because strict enumeration masks the real reason. I updated the copy to make that cause → effect explicit, which I think also answers part of your framing question.
  • "Use another method" framing. It's not a response to this specific error — the link is always rendered on the password card whenever any alternative strategy exists. I rephrased to reflect that.
  • Added custom-flow guidance. Prebuilt-component teams are mostly covered; the Venice.ai case that triggered this PR was a custom flow. I believe the right pattern is to read SignIn.supportedFirstFactors after signIn.create() and always offer the social provider as a fallback.
  • Mentioned the "Last used" badge on the sign-in start screen as a second prebuilt-component nudge, with the same-device qualifier so readers don't think it tracks account history.
  • Renamed the heading to "Password sign-in for accounts created with a social provider" — drops the "Social/OAuth" slash and describes the scenario directly.
  • Removed the opening " What is user enumeration?" heading. Not necessary. Goes straight into the description and unbolds "user enumeration" (bold is reserved for UI).
  • Plus a few styleguide cleanups (we/us, conjunction, capitalization on **Password**).

It sounds like a lot, but it's not when you view the changes. Let me know what you think.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Comment thread docs/guides/secure/user-enumeration-protection.mdx Outdated
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.

3 participants