Page MenuHomePhabricator

Set a JWT cookie for OAuth 1 requests and OAuth 2 owner-only requests
Closed, ResolvedPublic

Description

Due to limitations of how much we can control access tokens, we have decided in T394012: Decide how to expose session information outside of MediaWiki not to emit session information for OAuth 1 requests, and to accept emitting stale session information for OAuth 2 owner-only requests. To reduce the impact of this, we can emit a JWT session cookie for such requests. OAuth clients might ignore Set-Cookie headers, but some might not, and there's no harm in trying.

Unfortunately we'll probably not be able to fully reuse the mechanism created in T415007: Login with `action=login` and bot password does not create a JWT session cookie as cookies are normally set during persist(), calling that also saves the session to the session store, OAuth sessions are usually not persisted (the access token includes all necessary information, so the session store is only needed if something in the application needs to store its own session data, and almost nothing needs that), and we want to keep it that way as otherwise we'd do a session write on every request from clients which ignore cookies. We'll need to directly set/unset the cookie instead of using the needRefresh mechanism. We don't have a great place for doing that, currently. Maybe we'll need a callback that tells the session provider that it now owns the session.

One potential concern is cookie conflict - we probably want to use the same cookie name for all session types, to keep the Envoy logic simple. But that means that for a client using multiple session types (e.g. a browser that does normal cookie-based sessions but also OAuth), the various session handlers will write the same cookie. I think that won't be a problem as long as they use the same user, as the JWT contents will be roughly the same. In any case, using OAuth in the browser doesn't really make sense for OAuth 1 nor for owner-only consumers.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript
daniel triaged this task as High priority.Feb 21 2026, 9:38 AM
daniel subscribed.

Bumping priority to high, since this blocks the rollout of stage two of the REST API rate limits. It's not sufficient to have this by the rollout date, we need it beforehand so we have visibility of how many clients that use OAuth we would hit with rate limits.

Change #1252719 had a related patch set uploaded (by Gergő Tisza; author: Gergő Tisza):

[mediawiki/core@master] session: Add a callback for attaching a SessionInfo to a WebRequest

https://gerrit.wikimedia.org/r/1252719

Change #1252731 had a related patch set uploaded (by Gergő Tisza; author: Gergő Tisza):

[mediawiki/extensions/OAuth@master] [WIP] Set a JWT cookie for OAuth 1 and OAuth 2 owner-only requests

https://gerrit.wikimedia.org/r/1252731

Change #1252719 merged by jenkins-bot:

[mediawiki/core@master] session: Add a callback for attaching a SessionInfo to a WebRequest

https://gerrit.wikimedia.org/r/1252719

Change #1259059 had a related patch set uploaded (by D3r1ck01; author: Derick Alangi):

[mediawiki/extensions/OAuth@master] tests: OAuth1 and OAuth2 owner-only JWT support

https://gerrit.wikimedia.org/r/1259059

Change #1260005 had a related patch set uploaded (by D3r1ck01; author: Derick Alangi):

[mediawiki/extensions/WikimediaCustomizations@master] RateLimit: Do not ignore OAuth2 owner-only consumers

https://gerrit.wikimedia.org/r/1260005

Change #1260006 had a related patch set uploaded (by D3r1ck01; author: Derick Alangi):

[operations/mediawiki-config@master] Enable JWTs for OAuth1 consumers and OAuth2 owner-only consumers

https://gerrit.wikimedia.org/r/1260006

Change #1260005 abandoned by D3r1ck01:

[mediawiki/extensions/WikimediaCustomizations@master] RateLimit: Do not ignore OAuth2 owner-only consumers

https://gerrit.wikimedia.org/r/1260005

Change #1264663 had a related patch set uploaded (by D3r1ck01; author: Derick Alangi):

[mediawiki/extensions/OAuth@master] tests: Add test for asserting JWT cookie not set for OAuth2 consumers

https://gerrit.wikimedia.org/r/1264663

Change #1252731 merged by jenkins-bot:

[mediawiki/extensions/OAuth@master] Set a JWT cookie for OAuth 1 and OAuth 2 owner-only requests

https://gerrit.wikimedia.org/r/1252731

Change #1259059 merged by jenkins-bot:

[mediawiki/extensions/OAuth@master] tests: OAuth1 and OAuth2 owner-only JWT support

https://gerrit.wikimedia.org/r/1259059

Change #1264663 merged by jenkins-bot:

[mediawiki/extensions/OAuth@master] tests: Add test for asserting JWT cookie not set for OAuth2 consumers

https://gerrit.wikimedia.org/r/1264663

Change #1265367 had a related patch set uploaded (by D3r1ck01; author: Gergő Tisza):

[mediawiki/extensions/OAuth@wmf/1.46.0-wmf.22] Set a JWT cookie for OAuth 1 and OAuth 2 owner-only requests

https://gerrit.wikimedia.org/r/1265367

Change #1265368 had a related patch set uploaded (by D3r1ck01; author: Derick Alangi):

[mediawiki/extensions/OAuth@wmf/1.46.0-wmf.22] tests: OAuth1 and OAuth2 owner-only JWT support

https://gerrit.wikimedia.org/r/1265368

Change #1265369 had a related patch set uploaded (by D3r1ck01; author: Derick Alangi):

[mediawiki/extensions/OAuth@wmf/1.46.0-wmf.22] tests: Add test for asserting JWT cookie not set for OAuth2 consumers

https://gerrit.wikimedia.org/r/1265369

Change #1265367 merged by jenkins-bot:

[mediawiki/extensions/OAuth@wmf/1.46.0-wmf.22] Set a JWT cookie for OAuth 1 and OAuth 2 owner-only requests

https://gerrit.wikimedia.org/r/1265367

Change #1265368 merged by jenkins-bot:

[mediawiki/extensions/OAuth@wmf/1.46.0-wmf.22] tests: OAuth1 and OAuth2 owner-only JWT support

https://gerrit.wikimedia.org/r/1265368

Change #1265369 merged by jenkins-bot:

[mediawiki/extensions/OAuth@wmf/1.46.0-wmf.22] tests: Add test for asserting JWT cookie not set for OAuth2 consumers

https://gerrit.wikimedia.org/r/1265369

Change #1260006 merged by jenkins-bot:

[operations/mediawiki-config@master] Enable JWTs for OAuth1 consumers and OAuth2 owner-only consumers

https://gerrit.wikimedia.org/r/1260006

Mentioned in SAL (#wikimedia-operations) [2026-03-31T13:10:02Z] <derick@deploy1003> Started scap sync-world: Backport for [[gerrit:1265367|Set a JWT cookie for OAuth 1 and OAuth 2 owner-only requests (T417833)]], [[gerrit:1265368|tests: OAuth1 and OAuth2 owner-only JWT support (T417833 T415281)]], [[gerrit:1265369|tests: Add test for asserting JWT cookie not set for OAuth2 consumers (T417833 T415281)]], [[gerrit:1260006|Enable JWTs for OAuth1 consumers and OAuth2 owner-only consume

Mentioned in SAL (#wikimedia-operations) [2026-03-31T13:28:37Z] <derick@deploy1003> derick, d3r1ck01: Backport for [[gerrit:1265367|Set a JWT cookie for OAuth 1 and OAuth 2 owner-only requests (T417833)]], [[gerrit:1265368|tests: OAuth1 and OAuth2 owner-only JWT support (T417833 T415281)]], [[gerrit:1265369|tests: Add test for asserting JWT cookie not set for OAuth2 consumers (T417833 T415281)]], [[gerrit:1260006|Enable JWTs for OAuth1 consumers and OAuth2 owner-only consumers (T41

Mentioned in SAL (#wikimedia-operations) [2026-03-31T13:43:43Z] <derick@deploy1003> Finished scap sync-world: Backport for [[gerrit:1265367|Set a JWT cookie for OAuth 1 and OAuth 2 owner-only requests (T417833)]], [[gerrit:1265368|tests: OAuth1 and OAuth2 owner-only JWT support (T417833 T415281)]], [[gerrit:1265369|tests: Add test for asserting JWT cookie not set for OAuth2 consumers (T417833 T415281)]], [[gerrit:1260006|Enable JWTs for OAuth1 consumers and OAuth2 owner-only consum

Bumping priority to high, since this blocks the rollout of stage two of the REST API rate limits. It's not sufficient to have this by the rollout date, we need it beforehand so we have visibility of how many clients that use OAuth we would hit with rate limits.

[update] We deployed backports for this today and enabled it as the train goes out. By Thursday, if everything goes smoothly, it should be live for all wikis.

@daniel, On test wiki + PWB, I got the following response headers with a sessionJwt cookie.

(pyvenv) ☁  pywikibot [master] python pwb.py watchlist

{
  "date": "Wed, 01 Apr 2026 22:47:23 GMT",
  "server": "<redacted>",
  "x-content-type-options": "nosniff",
  "x-experiment-enrollments": "attribution-research-short-baseline-run=treatment;",
  "content-security-policy": "default-src 'self'; script-src 'none'; object-src 'none'",
  "x-frame-options": "DENY",
  "content-disposition": "inline; filename=api-result.json",
  "cache-control": "private, max-age=0, s-maxage=0",
  "set-cookie": "sessionJwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJS<redacted-portion>; expires=Thu, 02 Apr 2026 02:47:23 GMT; Max-Age=14400; path=/; secure; HttpOnly, WMF-Last-Access=01-Apr-2026;Path=/;HttpOnly;secure;Expires=Sun, 03 May 2026 12:00:00 GMT, WMF-Last-Access-Global=01-Apr-2026;Path=/;Domain=.wikipedia.org;HttpOnly;secure;Expires=Sun, 03 May 2026 12:00:00 GMT, GeoIP=<redacted>; Path=/; secure; Domain=.wikipedia.org, NetworkProbeLimit=0.001;Path=/;Secure;SameSite=None;Max-Age=3600, WMF-Uniq=<redacted>;Domain=.wikipedia.org;Path=/;HttpOnly;secure;SameSite=None;Expires=Thu, 01 Apr 2027 00:00:00 GMT",
  "content-type": "application/json; charset=utf-8",
  "content-encoding": "gzip",
  "age": "0",
  "x-cache": "cp6013 pass, cp6012 pass",
  "x-cache-status": "pass",
  "server-timing": "cache;desc=\"pass\", host;desc=\"cp6012\", WMF-Uniq;desc=\"attribution-research-short-baseline-run=treatment;\"",
  "strict-transport-security": "max-age=106384710; includeSubDomains; preload",
  "report-to": {
    "group": "wm_nel",
    "max_age": 604800,
    "endpoints": [
      {
        "url": "<redacted>
      }
    ]
  },
  "nel": {
    "report_to": "wm_nel",
    "max_age": 604800,
    "failure_fraction": 0.05,
    "success_fraction": 0
  },
  "x-client-ip": "<redacted>",
  "vary": "Accept-Encoding,User-Agent",
  "content-length": "624",
  "x-request-id": "c712d656-96da-4f99-8f8e-cb5db3c2c779",
  "x-analytics": ""
}

...

User:DAlangi (WMF)
User talk:DAlangi (WMF)

Execution time: 14 seconds

Consumer: https://meta.wikimedia.org/wiki/Special:OAuthListConsumers/view/11952828eb05af2eaadfd95a734231ec

Everything seems to be fine. I've been monitoring sessions and OAuth-related dashboards and haven't observed anything unusual. OAuth clients also seem to be working as expected after the rollout. Tomorrow, the feature hits group2 wikis.

Seems to be working, excellent!