From 18e1835b6eceb1694d3b3ec697f96ccc33670d69 Mon Sep 17 00:00:00 2001 From: tfrere Date: Wed, 6 May 2026 12:51:09 +0200 Subject: [PATCH] fix(hf-auth): force OAuth consent prompt to expose org grants Pass `prompt=consent` on the HuggingFace authorization URL so the consent screen is displayed on every login, even when the app has already been authorized. This is needed because HF lets the user pick which organizations to grant `read-repos` to during the consent step. A user who skipped that step the first time (or who joined an org *after* the initial login) had no in-app way to fix it: the only options were to manually revoke the app at https://huggingface.co/settings/connected-applications or edit the OAuth grants by hand. With this change, "Sign out + Sign in" is enough to re-open the org checkbox list, which is the common path users hit when private apps from organizations like `pollen-robotics` fail to appear in the app catalog. The OAuth scopes are unchanged: `read-repos` already covers org repos when the user has explicitly granted org-level access. No additional scope is required. Co-authored-by: Cursor --- src/reachy_mini/apps/sources/hf_auth.py | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/reachy_mini/apps/sources/hf_auth.py b/src/reachy_mini/apps/sources/hf_auth.py index 0d999d026..f80fd76c8 100644 --- a/src/reachy_mini/apps/sources/hf_auth.py +++ b/src/reachy_mini/apps/sources/hf_auth.py @@ -122,9 +122,7 @@ def _cleanup_expired_sessions() -> None: del _oauth_sessions[sid] -def get_oauth_redirect_uri( - wireless_version: bool, use_localhost: bool = False -) -> str: +def get_oauth_redirect_uri(wireless_version: bool, use_localhost: bool = False) -> str: """Get the appropriate OAuth redirect URI based on robot type. Args: @@ -181,7 +179,17 @@ def create_oauth_session( ) _oauth_sessions[state] = session - # Build HuggingFace OAuth authorization URL with PKCE + # Build HuggingFace OAuth authorization URL with PKCE. + # + # `prompt=consent` forces HuggingFace to re-display the consent screen on + # every login, even when the app has already been authorized. This matters + # for organization access: HF lets the user pick which orgs to grant the + # `read-repos` scope to during consent, and a user who skipped that step + # the first time has no in-app way to fix it without going to + # https://huggingface.co/settings/connected-applications and revoking the + # app manually. Forcing consent makes "Logout + Login" enough to (re-)opt + # an org in or out, which is what we want for users who joined an org + # after their first login (e.g. private apps from `pollen-robotics`). from urllib.parse import urlencode params = { @@ -192,6 +200,7 @@ def create_oauth_session( "state": state, "code_challenge": code_challenge, "code_challenge_method": "S256", + "prompt": "consent", } auth_url = f"https://huggingface.co/oauth/authorize?{urlencode(params)}" @@ -247,7 +256,9 @@ async def exchange_code_for_token( session.error_message = "OAuth not configured" return {"status": "error", "message": "OAuth not configured"} - redirect_uri = get_oauth_redirect_uri(session.wireless_version, session.use_localhost) + redirect_uri = get_oauth_redirect_uri( + session.wireless_version, session.use_localhost + ) # Exchange code for token using PKCE token_url = "https://huggingface.co/oauth/token"