Skip to content

fix: Warn at login when the OAuth grant is narrower than requested - #1090

Open
gewenyu99 wants to merge 12 commits into
mainfrom
posthog/warn-on-narrowed-oauth-grant
Open

fix: Warn at login when the OAuth grant is narrower than requested#1090
gewenyu99 wants to merge 12 commits into
mainfrom
posthog/warn-on-narrowed-oauth-grant

Conversation

@gewenyu99

@gewenyu99 gewenyu99 commented Aug 14, 2026

Copy link
Copy Markdown
Collaborator
Screenshot 2026-08-14 at 8 35 59 PM

We let people deny permissions, which is good. Their run will fail, which is bad. So this just tells them: hey you can't run without this.

…requested

A token can come back with fewer scopes than the wizard asked for — the
consent screen lets users deselect any non-required scope, and
out-of-ceiling scopes are clamped silently. Neither path errors, so the
wizard only discovered the gap when a run step 403'd minutes later and
failed the whole run.

Diff granted vs requested right after token exchange: log it, warn the
user which permissions are missing and how to re-grant them, and emit
`wizard: oauth grant narrowed` so narrowed runs are countable. Also
correct the WIZARD_OAUTH_SCOPES comment and README, which claimed an
out-of-ceiling scope fails the whole authorize with invalid_scope — the
server narrows silently instead.

Generated-By: PostHog Desktop
Task-Id: ab2b43f1-966e-4486-b0d0-d187a2c59021
@github-actions

Copy link
Copy Markdown

🧙 Wizard CI

Run the Wizard CI and test your changes against wizard-workbench example apps by replying with a GitHub comment using one of the following commands:

Test all apps:

  • /wizard-ci all

Test all apps in a directory:

  • /wizard-ci ai-observability
  • /wizard-ci basic-integration
  • /wizard-ci mcp-analytics
  • /wizard-ci revenue
  • /wizard-ci self-driving

Test an individual app:

  • /wizard-ci ai-observability/anthropic
  • /wizard-ci ai-observability/groq
  • /wizard-ci ai-observability/manual-capture
Show more apps
  • /wizard-ci ai-observability/openai
  • /wizard-ci ai-observability/openai-agents
  • /wizard-ci ai-observability/vercel-ai
  • /wizard-ci basic-integration/android
  • /wizard-ci basic-integration/angular
  • /wizard-ci basic-integration/astro
  • /wizard-ci basic-integration/django
  • /wizard-ci basic-integration/fastapi
  • /wizard-ci basic-integration/flask
  • /wizard-ci basic-integration/javascript-node
  • /wizard-ci basic-integration/javascript-web
  • /wizard-ci basic-integration/laravel
  • /wizard-ci basic-integration/next-js
  • /wizard-ci basic-integration/nuxt
  • /wizard-ci basic-integration/python
  • /wizard-ci basic-integration/rails
  • /wizard-ci basic-integration/react-native
  • /wizard-ci basic-integration/react-router
  • /wizard-ci basic-integration/sveltekit
  • /wizard-ci basic-integration/swift
  • /wizard-ci basic-integration/tanstack-router
  • /wizard-ci basic-integration/tanstack-start
  • /wizard-ci basic-integration/vue
  • /wizard-ci mcp-analytics/custom-dispatcher
  • /wizard-ci mcp-analytics/typescript-sdk
  • /wizard-ci revenue/stripe
  • /wizard-ci self-driving/astro
  • /wizard-ci self-driving/fastapi
  • /wizard-ci self-driving/nuxt
  • /wizard-ci self-driving/react-router
  • /wizard-ci self-driving/sveltekit

Results will be posted here when complete.

Comment thread src/utils/oauth.ts
* most flows survive it. The one scope the wizard cannot run without has its
* own hard check (`assertWizardCompletionScope`).
*/
function reportNarrowedGrant(

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

If we have this where people deselect stuff

gewenyu99 and others added 11 commits August 14, 2026 19:35
…requests

The "Required API Key Scopes" section still listed the 5-scope set from
an older release. The base request is now 12 scopes
(WIZARD_OAUTH_SCOPES), and the default integration flow adds
integration:read plus the external_data_source pair. List the full set
with one-line justifications, point at the source of truth, and note the
per-program additions.

Generated-By: PostHog Desktop
Task-Id: ab2b43f1-966e-4486-b0d0-d187a2c59021
Thread the granted-vs-requested scope diff from login onto the session
(credentials.missingScopes) and into every orchestrator prompt: agents
are told up front which permissions the user declined, that permission
errors on them are expected, and to skip that part — telling the user to
re-run and grant the permission during the OAuth flow — rather than
report the task failed.

When a drain still ends in failure and the grant was narrowed, the abort
message now names the missing permissions and the fix ("try again and
grant it during the OAuth authorization step") instead of only the
report-a-bug line, and the captured exception carries
missing_oauth_scopes.

Also compact the README scope list into a copyable block pointing at
WIZARD_OAUTH_SCOPES as the source of truth.

CI api-key runs carry an empty diff — a personal API key has no per-run
scope request to compare against.

Generated-By: PostHog Desktop
Task-Id: ab2b43f1-966e-4486-b0d0-d187a2c59021
…electable

The consent screen force-includes every scope in the OAuth app's
required_scopes, so the base set the wizard cannot run without belongs
there (set per region, same seed procedure as scopes). The wizard has
no client-side lever for this — the login diff and the prompt-threaded
degrade handle a narrowed grant, but only required_scopes prevents one.

Generated-By: PostHog Desktop
Task-Id: ab2b43f1-966e-4486-b0d0-d187a2c59021
…required_scopes field

required_scopes is a derived property (posthog/models/oauth.py): every
explicit obj:action entry in OAuthApplication.scopes is required and
locked at consent, while @default-covered scopes stay deselectable.
Document the actual pinning procedure — seed each region's app with
@default plus the WIZARD_OAUTH_SCOPES base set — with the exact
seed_oauth_app_scopes invocation and the keep-@default caveat.

Generated-By: PostHog Desktop
Task-Id: ab2b43f1-966e-4486-b0d0-d187a2c59021
…ug-report ask

When a run fails and the grant was narrowed at login, the abort now
reads "try again, approving all permissions on the PostHog
authorization screen" first, with the report-to-support line demoted to
the still-fails case — a permission the user unticked is theirs to fix,
and the old copy sent them straight to the support inbox. Also fix
singular/plural agreement in the login warning.

Generated-By: PostHog Desktop
Task-Id: ab2b43f1-966e-4486-b0d0-d187a2c59021
…ecific error on failure

Simplify the narrowed-grant handling to the two simple surfaces: the
login warning that names the permissions the grant came back without,
and the run-failure error that names them with the re-authorize fix
instead of the generic report-a-bug line. The per-prompt
missing-scopes notice injected into every orchestrator agent is
removed — behavior-shaping prompts are a bigger change than this needs.
The session still carries credentials.missingScopes; the abort message
is now its only consumer.

Generated-By: PostHog Desktop
Task-Id: ab2b43f1-966e-4486-b0d0-d187a2c59021
…on the auth spinner

Every login failure path (OAuth denied, missing completion scope, no
project access granted) calls wizardAbort, which renders the error
outro and then waits for its dismissal. But the router resolves the
active screen as the first incomplete sequence entry, and the auth
step only completes on credentials — which an aborted login never
sets. The walk parked on the auth screen forever: spinner up, outro
unreachable, waitForOutroDismissed deadlocked, process hung.

The run steps already complete on RunPhase.Error, which is why mid-run
aborts reach their outro; the auth step predates that convention.
Reroute in one place: when the walk lands on auth while an error outro
is pending, resolve the outro screen so the error can be read and
dismissed (which lets wizardAbort exit).

Reproduced by deselecting the event_definition:write permission on the
OAuth consent screen — assertWizardCompletionScope aborts mid-login
and the wizard froze at "Waiting for authentication...".

Generated-By: PostHog Desktop
Task-Id: ab2b43f1-966e-4486-b0d0-d187a2c59021
The three login abort paths (missing completion scope, project
mismatch, no project access) logged their reason and then called
abort() bare, so the outro — which a failed login now actually reaches
— rendered the generic "Wizard setup cancelled." Pass the message so
the screen the user reads names the real cause.

Generated-By: PostHog Desktop
Task-Id: ab2b43f1-966e-4486-b0d0-d187a2c59021
A bare abort() rendered the generic 'Wizard setup cancelled.' while the
real reason went to a log line the outro never shows. The completion-scope
message now leads with the fix and rides the outro.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
….com/PostHog/wizard into posthog/warn-on-narrowed-oauth-grant

# Conflicts:
#	src/utils/setup-utils.ts
…scope list, fix

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@gewenyu99
gewenyu99 marked this pull request as ready for review August 15, 2026 00:37
@gewenyu99
gewenyu99 requested a review from a team as a code owner August 15, 2026 00:37
@gewenyu99 gewenyu99 changed the title Warn at login when the OAuth grant is narrower than requested fix: Warn at login when the OAuth grant is narrower than requested Aug 15, 2026
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