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)
- macOS with Safari as the default browser;
- Notion desktop app installed;
- 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);
- 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
- Sign in to Notion once in Safari (so
identity.notion.com holds a session);
- Clear cookies for the
app.notion.com domain only (keep the identity domain's);
- Open any public integration's OAuth authorization URL;
- 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.
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/sessionSyncis 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)
identity.notion.combut no session onapp.notion.com(typical origins: the user completed desktop-app login through the browser, or theapp.notion.comcookie expired while the identity session survived);api.notion.com/v1/oauth/authorizeor MCPmcp.notion.com/authorize— both land on the same consent page).Steps to reproduce
identity.notion.comholds a session);app.notion.comdomain only (keep the identity domain's);install-integrationand 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.
What we verified (all independently replayable)
① Redirect chain (curl, no session needed):
② AASA audit (
https://app.notion.com/.well-known/apple-app-site-association;www.notion.soserves identical content):LBQJ96FQ8D.notion.iddeclares a catch-all:{"/": "*", "comment": "Match all other paths"};/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/sessionSyncis absent. We pattern-matched it against all 211 wildcard excludes — none covers it. There is no/api/*-level exclusion either (only/api-betaand/api-beta/*).③ Desktop app side: the macOS Notion.app entitlements contain
applinks:app.notion.comandapplinks:www.notion.so(verifiable viacodesign -d --entitlements).④ Counter-evidence — anonymous users are unaffected: in a zero-cookie browser,
install-integrationroutes client-side to/login(an excluded path) with zero sessionSync requests (verified via the Performance API:redirectCount: 0, and a full network capture).⑤ No
sessionSyncreference exists inapp.notion.com's client bundles (all 177 JS chunks actually loaded by the page were searched, case-insensitively). The login page embeds anidentity.notion.com/authSynciframe 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/sessionSyncto the AASA exclude lists of bothapp.notion.comandwww.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.