Skip to content

OAuth authorization window goes blank in macOS Safari when the Notion desktop app is installed — /api/v3/sessionSync appears to be missing from the AASA exclude list #345

Description

@c99w99

Summary

When a third-party integration starts an OAuth flow (including MCP authorization via mcp.notion.com/authorize), macOS Safari users in a specific — but common — session state hit a blank authorization window and the flow dies.

The root cause points strongly to a missing entry in the Universal Links association file (apple-app-site-association, "AASA") of app.notion.com: the file uses a catch-all "*" match plus 537 excluded paths, and while every other auth/callback-style path is excluded, the session-restore endpoint /api/v3/sessionSync is not. That navigation therefore gets handed off to the Notion desktop app by Universal Links, leaving the browser-side OAuth flow stranded.

Preconditions (all four required)

  1. macOS with Safari as the default browser;
  2. Notion desktop app installed;
  3. Safari has a valid session on identity.notion.com but no session on app.notion.com (typical origins: the user completed desktop-app login through the browser, or the app.notion.com cookie expired while the identity session survived);
  4. Open any public integration's OAuth authorization URL (standard api.notion.com/v1/oauth/authorize or MCP mcp.notion.com/authorize — both land on the same consent page).

Steps to reproduce

  1. Sign in to Notion once in Safari (so identity.notion.com holds a session);
  2. Clear cookies for the app.notion.com domain only (keep the identity domain's);
  3. Open any public integration's OAuth authorization URL;
  4. Observe: when the flow reaches install-integration and triggers the session-restore redirect, the navigation is handed to the Notion desktop app; the Safari window is left blank and authorization cannot complete.

Expected: the whole flow stays in the browser; after session restore the consent page renders.

⚠️ Note for triage: an anonymous browser will NOT reproduce this — with no session at all, install-integration client-side routes to /login, which is excluded from Universal Links. The partial-session state above is required.

What we verified (all independently replayable)

① Redirect chain (curl, no session needed):

GET https://mcp.notion.com/authorize?...       → 302
GET https://api.notion.com/v1/oauth/authorize  → 302
GET https://app.notion.com/install-integration → 200 (SPA shell)

② AASA audit (https://app.notion.com/.well-known/apple-app-site-association; www.notion.so serves identical content):

  • appID LBQJ96FQ8D.notion.id declares a catch-all: {"/": "*", "comment": "Match all other paths"};
  • 537 exclude entries, including /login, /oauth2callback, /install-integration, /googlepopupredirect, /desktopwithbrowserlogin(callback), /browser-session-handoff-to-desktop(/callback), /oauth2/postlogin, and even the API-shaped /oauth2/api/v3/getSkilljarProfile;
  • /api/v3/sessionSync is absent. We pattern-matched it against all 211 wildcard excludes — none covers it. There is no /api/*-level exclusion either (only /api-beta and /api-beta/*).

③ Desktop app side: the macOS Notion.app entitlements contain applinks:app.notion.com and applinks:www.notion.so (verifiable via codesign -d --entitlements).

④ Counter-evidence — anonymous users are unaffected: in a zero-cookie browser, install-integration routes client-side to /login (an excluded path) with zero sessionSync requests (verified via the Performance API: redirectCount: 0, and a full network capture).

No sessionSync reference exists in app.notion.com's client bundles (all 177 JS chunks actually loaded by the page were searched, case-insensitively). The login page embeds an identity.notion.com/authSync iframe for cross-domain session detection — the sessionSync hop appears to be issued dynamically by the session-restore flow. That is consistent with Safari ITP requiring a top-level navigation for the cross-domain cookie handoff — and top-level navigations are exactly what Universal Links intercept.

Suggested fix

Add /api/v3/sessionSync to the AASA exclude lists of both app.notion.com and www.notion.so. This matches how every other navigational auth/session-handoff endpoint is already treated (see ② for precedents) and should be zero-impact for the desktop app.

Impact

The affected population is "Mac + Safari users who primarily use the desktop app" — squarely the Notion power-user profile. It applies to the OAuth flow of every public integration, not any single one. The user-visible symptom (a blank authorization window) carries no diagnostic signal, so it is almost never reported accurately; the real occurrence rate is likely much higher than the feedback rate.

We can provide a HAR capture from an affected environment on request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions