Skip to content

Add custom OAuth consent security guide#3413

Open
jescalan wants to merge 2 commits into
rob/oauth-consent-docsfrom
je/docs-oauth-custom-consent-page-stack
Open

Add custom OAuth consent security guide#3413
jescalan wants to merge 2 commits into
rob/oauth-consent-docsfrom
je/docs-oauth-custom-consent-page-stack

Conversation

@jescalan

@jescalan jescalan commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Stacks on #3315. Adds a security-focused guide for configuring a custom OAuth consent page, with a strong recommendation to use the Account Portal or the prebuilt <OAuthConsent /> component instead of a fully custom flow.

The guide covers consent phishing risk, required consent-screen content, redirect URI presentation, route configuration, safer appearance-based customization, and low-level custom-flow responsibilities.

Changes in this repo

  • Adds Customize the OAuth consent page to the OAuth guide section.
  • Adds tabbed prebuilt <OAuthConsent /> examples for Next.js, React, React Router, TanStack React Start, Astro, Vue, and Nuxt.
  • Adds low-level custom-flow examples for React-based SDKs, with warnings about redirect URI presentation and organization selection.
  • Cross-links the new guide from existing OAuth docs.
  • Updates the OAuth consent component and hook references from Add OAuthConsent and useOAuthConsent docs #3315 to point to the guide and fixes a few snippet accuracy issues.

Preview links

New pages:

Changed sections:

Parent PR

Validation

  • rtk pnpm -C clerk-docs build
  • rtk pnpm -C clerk-docs lint
  • rtk git -C clerk-docs diff --check

@vercel

vercel Bot commented Jun 1, 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 9, 2026 10:01pm

Request Review

@jescalan jescalan marked this pull request as ready for review June 1, 2026 23:39
@jescalan jescalan requested a review from a team as a code owner June 1, 2026 23:39

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6ae5e884d1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/_partials/components/oauth-consent-examples.mdx
Comment thread docs/_partials/components/oauth-consent-custom-flow-examples.mdx
Comment thread docs/_partials/components/oauth-consent-custom-flow-examples.mdx Outdated

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7beb713efd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/_partials/components/oauth-consent-custom-flow-examples.mdx Outdated
@jescalan jescalan requested review from jfoshee and wobsoriano June 2, 2026 15:44

@wobsoriano wobsoriano left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this looks good on my end 👍🏼

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0bf3843f32

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/reference/components/authentication/oauth-consent.mdx
@jescalan

jescalan commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@jescalan

jescalan commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Already looking forward to the next diff.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread docs/_partials/components/oauth-consent-custom-flow-examples.mdx

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Love how simple these are. We have a separate issue to investigate alleviating the need for setting the referrer. We will circle back to these docs when we figure that out.

Comment thread docs/guides/configure/auth-strategies/oauth/custom-consent-page.mdx

These examples display the full redirect hostname and an expandable full URL. For a production custom flow, use a public-suffix-aware approach for root-domain summaries, handle IP addresses and localhost explicitly, and test long redirect URIs to make sure the real destination remains visible.

These examples also do not implement organization selection. If an OAuth application can request `user:org:read`, use `<OAuthConsent />` or add an organization selector that submits the selected `organization_id` with the allow action.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

How can we remember to update this bit when <OrgSelect /> is made generally available? 🤔

Comment thread docs/guides/configure/auth-strategies/oauth/custom-consent-page.mdx
Comment thread docs/guides/configure/auth-strategies/oauth/custom-consent-page.mdx
@jfoshee

jfoshee commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

I was just testing these docs with an agent and it failed to hide the navbar. We definitely need some language to remind implementors that the consent dialog should be the only thing on the page-- no other nav like sign-in/out or user button. Any other navigation will break the OAuth flow. @jescalan

@jescalan

jescalan commented Jun 8, 2026

Copy link
Copy Markdown
Contributor Author

I was just testing these docs with an agent and it failed to hide the navbar. We definitely need some language to remind implementors that the consent dialog should be the only thing on the page-- no other nav like sign-in/out or user button. Any other navigation will break the OAuth flow. @jescalan

Good call. Revised the skill a little bit - should fix this

</If>

<If sdk="vue">
```vue {{ filename: 'oauth-consent.vue' }}

@SarahSoutoul SarahSoutoul Jun 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Was the src/pages added for any reason here? From looking at the docs, the standard is to call the vue files as such (see screenshots).

Image Image

@jescalan @jfoshee

```vue {{ filename: 'pages/oauth-consent.vue' }}
<script setup lang="ts">
// Components are automatically imported
import { OAuthConsent } from '@clerk/nuxt/components'

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

So the component doesn't get automatically imported like other components in Nuxt? @jescalan @jfoshee

Comment on lines +103 to +119
<Tab>
```vue {{ filename: 'src/pages/OAuthConsentPage.vue' }}
<script setup lang="ts">
import { OAuthConsent, Show } from '@clerk/vue'
</script>

<template>
<Show when="signed-in">
<OAuthConsent />
</Show>
</template>
```

```html {{ filename: 'index.html' }}
<meta name="referrer" content="strict-origin-when-cross-origin" />
```
</Tab>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@jescalan @jfoshee Why is this example not using the same setup than what we have in the Vue example of <OAuthConsent /> component page? This example uses an index.html but the one in the component page uses a useHead hook?

Image

> [!IMPORTANT]
> Enabling the consent screen for all OAuth apps is **strongly recommended**. Without a consent screen, any logged-in user who visits an OAuth authorization URL automatically grants access to any requested scopes. The consent screen acts as a critical security checkpoint, preventing malicious apps from silently gaining access to user accounts.
>
> If you need to host the consent page on your own application domain, see [Customize the OAuth consent page](/docs/guides/configure/auth-strategies/oauth/custom-consent-page). Clerk strongly recommends using the default [Account Portal](/docs/guides/account-portal/overview) consent page unless you have a specific product requirement that it cannot satisfy.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We have slightly different wording for the scoped-access page -> If you need to host the consent page on your own application domain VS If you need to host the consent page yourself

Image

Is that on purpose? If not, think it would be good to make the wording consistent across those two places. @jescalan @jfoshee

@SarahSoutoul SarahSoutoul self-assigned this Jun 9, 2026
```tsx {{ filename: 'app/oauth-consent/page.tsx' }}
import { OAuthConsent, Show } from '@clerk/nextjs'

export const metadata = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do we not use the Metada from next here like we did in the component page Next.js code example? @jescalan @jfoshee

Image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Got an overall question on the code examples in this file. They all use the <Show> component to display the <OAuthConsent /> component when signed in. This is not the case for all the code examples in the component page - why? @jescalan @jfoshee

@@ -0,0 +1,154 @@
---
title: Customize the OAuth consent page

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I have a slight preference for Set up a custom OAuth consent page as the title. I think it matches the content a bit better, since this guide is about creating and configuring a custom consent route and flow, not just visually customizing an existing page. Customize the OAuth consent page reads a little more like appearance/styling, while Set up... feels closer to the actual task the guide walks through. @jescalan @jfoshee

@SarahSoutoul

Copy link
Copy Markdown
Contributor

@jescalan @jfoshee have left a bunch of comments and questions (sorry!) and pushed a minor docs review doing the following:

  • Adding a collapsible: true prop on the code examples within docs/_partials/components/oauth-consent-custom-flow-examples.mdx given their length.
  • Changed the wording of some of the instructions in the Custom consent page to align with the Dashboard UI.

I still need to test some of this so will do that while waiting for responses.

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.

4 participants