Skip to content

feat(oauth): Stop counting non-Sync Desktop sign-ins as Sync auth/Sync DAU - #20967

Open
LZoog wants to merge 1 commit into
mainfrom
FXA-14263
Open

feat(oauth): Stop counting non-Sync Desktop sign-ins as Sync auth/Sync DAU#20967
LZoog wants to merge 1 commit into
mainfrom
FXA-14263

Conversation

@LZoog

@LZoog LZoog commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Because:

  • Firefox Desktop requests the Sync scope on every browser-initiated OAuth flow, whatever service the user is signing into. So a Smart Window, Relay or VPN sign-in mints an apps/oldsync access token and writes an apps/oldsync consent row — inflating both Sync DAU and Sync authorizations, even for passwordless accounts that could never have used Sync.
  • Product confirmed entering a password is not Sync consent either: the user gets Sync keys so they can enable Sync later, but saw nothing about Sync.

This commit:

  • Adds dropUnconsentedSyncScope: on Firefox Desktop, the Sync scope counts as consented only when the resolved service is sync, or absent (very old browsers, which default to Sync).
  • Applies that one decision to both consumers. It keeps the row out of accountAuthorizations, and rides the auth code to /oauth/token — which never sees service= — so the access_token.created Glean event is tagged exclude_dau. The flag is stashed in Redis against the code's hash and expires with the code.
  • Leaves the grant and the issued tokens untouched, so Sync keeps working for these users.

Recording real consent when the user turns Sync on in the browser needs a signal Firefox does not send; FXA-14295 covers that endpoint. An underlying fix is Desktop dropping scope= for ADR 0049 resolution. When that has been in Release long enough, lib/oauth/desktop-sync-consent-bandaid.ts can be deleted.

Closes FXA-14263

  • My commit is GPG signed.
  • If applicable, I have modified or added tests which pass locally.
  • I have added necessary documentation (if appropriate).
  • I have verified that my changes render correctly in RTL (if appropriate).
  • I have manually reviewed all AI generated code.

How to review (Optional)

Check out this doc, which has some test cases + screenshots of the account auth table, and an output from a temp tool I had Claude make to make grepping through auth-server DAU logs here less painful. (Please ping me if you'd like the script, otherwise you can search auth server logs for exclude_dau and see the events)

…c DAU

Because:
- Firefox Desktop requests the Sync scope on every browser-initiated OAuth
  flow, whatever service the user is signing into. So a Smart Window, Relay or
  VPN sign-in mints an apps/oldsync access token and writes an apps/oldsync
  consent row — inflating both Sync DAU and Sync authorizations, even for
  passwordless accounts that could never have used Sync.
- Product confirmed entering a password is not Sync consent either: the user
  gets Sync keys so they can enable Sync later, but saw nothing about Sync.

This commit:
- Adds dropUnconsentedSyncScope: on Firefox Desktop, the Sync scope counts as
  consented only when the resolved service is sync, or absent (old Desktop browsers
  or Mobile, which default to Sync).
- Applies that one decision to both consumers. It keeps the row out of
  accountAuthorizations, and rides the auth code to /oauth/token — which never
  sees service= — so the access_token.created Glean event is tagged
  exclude_dau. The flag is stashed in Redis against the code's hash and expires
  with the code.
- Leaves the grant and the issued tokens untouched, so Sync keeps working for
  these users.

Recording real consent when the user turns Sync on in the browser needs a
signal Firefox does not send; FXA-14295 covers that endpoint. An underlying
fix is Desktop dropping scope= for ADR 0049 resolution. When that has been in
Release long enough, lib/oauth/desktop-sync-consent-bandaid.ts can be deleted.

Closes FXA-14263
@LZoog
LZoog requested a review from a team as a code owner August 4, 2026 21:21
Copilot AI review requested due to automatic review settings August 4, 2026 21:21

Copilot AI left a comment

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.

Pull request overview

This PR introduces a Firefox Desktop–specific “bandaid” to avoid inflating Sync authorizations and Sync DAU when Desktop requests the Sync scope for non-Sync browser services (e.g., Smart Window). It keeps OAuth grants/tokens unchanged while preventing unconsented Sync consent rows and tagging token-created telemetry as exclude_dau via an authorization-code–scoped Redis flag.

Changes:

  • Add dropUnconsentedSyncScope + excludeDauCacheKey helper module and unit tests.
  • Update /oauth/authorization to (a) drop oldsync from consent writes for non-Sync Desktop flows and (b) write an exclude-DAU flag to Redis keyed by the auth-code hash.
  • Update /oauth/token to read the Redis flag during code redemption and tag the Glean tokenCreated event accordingly; add route-level tests and a remote integration test covering real DB rows.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/fxa-auth-server/test/remote/account_consents.in.spec.ts Adds an integration test ensuring non-Sync Desktop sign-ins don’t create an oldsync consent row but still mint tokens with oldsync scope.
packages/fxa-auth-server/lib/routes/oauth/token.spec.ts Adds tests asserting /oauth/token reads the code-hash Redis flag and sets excludeDau on emitted metrics.
packages/fxa-auth-server/lib/routes/oauth/token.js Reads the exclude-DAU Redis flag during authorization-code redemption and merges server-side/client-provided exclude_dau.
packages/fxa-auth-server/lib/routes/oauth/index.js Wires authServerCacheRedis into the authorization route constructor.
packages/fxa-auth-server/lib/routes/oauth/authorization.spec.ts Adds tests for dropping oldsync from consent writes and for writing the exclude-DAU flag to Redis with code TTL.
packages/fxa-auth-server/lib/routes/oauth/authorization.js Implements service resolution helper, drops unconsented oldsync from ledger, sets grant.excludeDau, and writes the decision to Redis for /oauth/token to consume.
packages/fxa-auth-server/lib/oauth/desktop-sync-dau-authorization-bandaid.ts New shared logic for dropping unconsented oldsync and generating the Redis cache key.
packages/fxa-auth-server/lib/oauth/desktop-sync-dau-authorization-bandaid.spec.ts Unit tests for the new bandaid helper behaviors and cache key format.

Comment on lines +240 to +256
function shouldExcludeSyncDau(req, grant) {
const clientIdHex = hex(grant.clientId);
// Cheapest gate first. dropUnconsentedSyncScope checks this too, but
// short-circuit here if we can.
if (clientIdHex !== OAuthNativeClients.FirefoxDesktop) {
return false;
}
const requestedScopes = grant.scope.getScopeValues();
if (requestedScopes.length === 0) {
return false;
}
return dropUnconsentedSyncScope({
scopes: requestedScopes,
serviceValue: resolveServiceValue(req, requestedScopes),
clientIdHex: hex(grant.clientId),
}).droppedSyncScope;
}
});

// The bandaid must touch the consent ledger and nothing else.
// Graned refresh and access token scopes should be untouched.
Comment on lines +96 to +101
} catch (err) {
statsd?.increment('accountAuthorization.exclude_dau_write_failed');
log.warn('accountAuthorization.exclude_dau_write_failed', {
err: err.message,
});
}
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.

2 participants