Page MenuHomePhabricator

Groups requiring 2FA via $wgOATHRequiredForGroups do not clearly warn users without 2FA that their permissions were truncated
Open, Needs TriagePublic

Description

Earlier today (almost six hours ago), I made myself an interface administrator on Beta Commons (intending to test changes related to the ACDC gadget and T381537) – see the log entry and SAL entry. However, I remain unable to edit MediaWiki:Gadget-ACDC.js:

… but you do not have permission to create this page.
You do not have permission to edit this JavaScript page because it may affect all visitors. [sitejsprotected message]

Special:UserRights/Lucas Werkmeister shows both the log entry and the group (“Member of: Interface administrators, Administrators”); in the API, list=allusers reports me as a member of interface-admin while meta=userinfo does not. (However, the rights lists in both modules agree that I don’t have the editsitejs right.)

I don’t know what’s going on here. It’s similar to T244019, but not the same (for instance, back then, Special:UserRights didn’t show the group).

I already tried logging out and back in and it seems to have had no effect.

Event Timeline

Here’s my output for that API link (I realized that the meta=userinfo part is obviously going to be useless for anyone else following that link :D):

{
  "batchcomplete": true,
  "query": {
    "allusers": [
      {
        "userid": 2169,
        "name": "Lucas Werkmeister",
        "groups": [
          "*",
          "user",
          "autoconfirmed",
          "interface-admin",
          "sysop"
        ],
        "rights": [
          "changetags",
          "templateeditor",
          "editautopatrolprotected",
          "suppressredirect",
          "noratelimit",
          "deleterevision",
          "deletelogentry",
          "editcontentmodel",
          "checkuser-temporary-account-auto-reveal",
          "block",
          "createaccount",
          "delete",
          "deletedhistory",
          "deletedtext",
          "undelete",
          "editinterface",
          "editsitejson",
          "edituserjson",
          "import",
          "move",
          "move-subpages",
          "move-rootuserpages",
          "move-categorypages",
          "patrol",
          "autopatrol",
          "protect",
          "editprotected",
          "rollback",
          "upload",
          "reupload",
          "reupload-shared",
          "unwatchedpages",
          "autoconfirmed",
          "editsemiprotected",
          "ipblock-exempt",
          "blockemail",
          "markbotedits",
          "apihighlimits",
          "browsearchive",
          "movefile",
          "mergehistory",
          "managechangetags",
          "deletechangetags",
          "pagelang",
          "ipinfo",
          "ipinfo-view-full",
          "tboverride",
          "titleblacklistlog",
          "transcode-reset",
          "transcode-status",
          "urlshortener-create-url",
          "globalblock-whitelist",
          "nuke",
          "skipcaptcha",
          "override-antispoof",
          "centralauth-createlocal",
          "abusefilter-log-detail",
          "abusefilter-view-private",
          "abusefilter-log-private",
          "abusefilter-modify",
          "abusefilter-modify-restricted",
          "abusefilter-modify-blocked-external-domains",
          "abusefilter-access-protected-vars",
          "massmessage",
          "upwizcampaigns",
          "mass-upload",
          "flow-lock",
          "flow-delete",
          "flow-edit-post",
          "flow-edit-title",
          "newsletter-create",
          "newsletter-delete",
          "newsletter-manage",
          "newsletter-restore",
          "campaignevents-enable-registration",
          "campaignevents-organize-events",
          "campaignevents-email-participants",
          "campaignevents-delete-registration",
          "campaignevents-view-private-participants",
          "sfsblock-bypass",
          "read",
          "edit",
          "createpage",
          "createtalk",
          "viewmyprivateinfo",
          "editmyprivateinfo",
          "editmyoptions",
          "translate",
          "centralauth-merge",
          "abusefilter-view",
          "abusefilter-log",
          "vipsscaler-test",
          "flow-hide",
          "item-term",
          "property-term",
          "item-merge",
          "item-redirect",
          "property-create",
          "mediainfo-term",
          "upload_by_url",
          "reupload-own",
          "minoredit",
          "editmyusercss",
          "editmyuserjson",
          "editmyuserjs",
          "sendemail",
          "applychangetags",
          "viewmywatchlist",
          "editmywatchlist",
          "translate-messagereview",
          "translate-groupreview",
          "spamblacklistlog",
          "mwoauthmanagemygrants",
          "oathauth-enable",
          "reportincident",
          "unfuzzy",
          "collectionsaveasuserpage",
          "collectionsaveascommunitypage"
        ]
      }
    ],
    "userinfo": {
      "id": 2169,
      "name": "Lucas Werkmeister",
      "groups": [
        "sysop",
        "*",
        "user",
        "autoconfirmed"
      ],
      "rights": [
        "changetags",
        "templateeditor",
        "editautopatrolprotected",
        "suppressredirect",
        "noratelimit",
        "deleterevision",
        "deletelogentry",
        "editcontentmodel",
        "checkuser-temporary-account-auto-reveal",
        "block",
        "createaccount",
        "delete",
        "deletedhistory",
        "deletedtext",
        "undelete",
        "editinterface",
        "editsitejson",
        "edituserjson",
        "import",
        "move",
        "move-subpages",
        "move-rootuserpages",
        "move-categorypages",
        "patrol",
        "autopatrol",
        "protect",
        "editprotected",
        "rollback",
        "upload",
        "reupload",
        "reupload-shared",
        "unwatchedpages",
        "autoconfirmed",
        "editsemiprotected",
        "ipblock-exempt",
        "blockemail",
        "markbotedits",
        "apihighlimits",
        "browsearchive",
        "movefile",
        "mergehistory",
        "managechangetags",
        "deletechangetags",
        "pagelang",
        "ipinfo",
        "ipinfo-view-full",
        "tboverride",
        "titleblacklistlog",
        "transcode-reset",
        "transcode-status",
        "urlshortener-create-url",
        "globalblock-whitelist",
        "nuke",
        "skipcaptcha",
        "override-antispoof",
        "centralauth-createlocal",
        "abusefilter-log-detail",
        "abusefilter-view-private",
        "abusefilter-log-private",
        "abusefilter-modify",
        "abusefilter-modify-restricted",
        "abusefilter-modify-blocked-external-domains",
        "abusefilter-access-protected-vars",
        "massmessage",
        "upwizcampaigns",
        "mass-upload",
        "flow-lock",
        "flow-delete",
        "flow-edit-post",
        "flow-edit-title",
        "newsletter-create",
        "newsletter-delete",
        "newsletter-manage",
        "newsletter-restore",
        "campaignevents-enable-registration",
        "campaignevents-organize-events",
        "campaignevents-email-participants",
        "campaignevents-delete-registration",
        "campaignevents-view-private-participants",
        "sfsblock-bypass",
        "read",
        "edit",
        "createpage",
        "createtalk",
        "viewmyprivateinfo",
        "editmyprivateinfo",
        "editmyoptions",
        "translate",
        "centralauth-merge",
        "abusefilter-view",
        "abusefilter-log",
        "vipsscaler-test",
        "flow-hide",
        "item-term",
        "property-term",
        "item-merge",
        "item-redirect",
        "property-create",
        "mediainfo-term",
        "upload_by_url",
        "reupload-own",
        "minoredit",
        "editmyusercss",
        "editmyuserjson",
        "editmyuserjs",
        "sendemail",
        "applychangetags",
        "viewmywatchlist",
        "editmywatchlist",
        "translate-messagereview",
        "translate-groupreview",
        "spamblacklistlog",
        "mwoauthmanagemygrants",
        "oathauth-enable",
        "reportincident",
        "unfuzzy",
        "collectionsaveasuserpage",
        "collectionsaveascommunitypage"
      ]
    }
  }
}

@Ladsgroup informs me this is likely due to T150898, which despite the title (“Force OATHAuth (2FA) for certain user groups in Wikimedia production”) is apparently also enforced on the Beta cluster. I don’t even want to imagine what horrible things this enforcement mechanism is doing to make MediaWiki behave in this bizarre way.

Some possible remedies I can think of:

  • much better error messages, and make MediaWiki’s output in different places less confusing
  • disable this enforcement on the Beta cluster
  • I set up 2FA for my Beta account and then it’s no longer my problem

I set up 2FA for my Beta account and then it’s no longer my problem

Done, now everything works as expected.

Change #1153673 had a related patch set uploaded (by Lucas Werkmeister; author: Lucas Werkmeister):

[operations/mediawiki-config@master] beta cluster: Set $wgOATHAuthAccountPrefix

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

Change #1153674 had a related patch set uploaded (by Lucas Werkmeister; author: Lucas Werkmeister):

[operations/mediawiki-config@master] beta cluster: Disable $wgOATHRequiredForGroups

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

Change #1153673 merged by jenkins-bot:

[operations/mediawiki-config@master] beta cluster: Set $wgOATHAuthAccountPrefix

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

Mentioned in SAL (#wikimedia-operations) [2025-06-04T20:05:11Z] <cjming@deploy1003> Started scap sync-world: Backport for [[gerrit:1153673|beta cluster: Set $wgOATHAuthAccountPrefix (T396061)]]

Mentioned in SAL (#wikimedia-operations) [2025-06-04T20:07:18Z] <cjming@deploy1003> lucaswerkmeister, cjming: Backport for [[gerrit:1153673|beta cluster: Set $wgOATHAuthAccountPrefix (T396061)]] synced to the testservers (see https://wikitech.wikimedia.org/wiki/Mwdebug). Changes can now be verified there.

Mentioned in SAL (#wikimedia-operations) [2025-06-04T20:15:25Z] <cjming@deploy1003> Finished scap sync-world: Backport for [[gerrit:1153673|beta cluster: Set $wgOATHAuthAccountPrefix (T396061)]] (duration: 10m 13s)

I don’t even want to imagine what horrible things this enforcement mechanism is doing to make MediaWiki behave in this bizarre way.

It's literally just $wgOATHRequiredForGroups.

Change #1153674 abandoned by Lucas Werkmeister:

[operations/mediawiki-config@master] beta cluster: Disable $wgOATHRequiredForGroups

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

Documented the 2FA requirement on mw:Beta Cluster, maybe it helps someone in future.

Lobo77 claimed this task.
Lobo77 subscribed.
Ladsgroup removed Lobo77 as the assignee of this task.
bd808 assigned this task to LucasWerkmeister.
bd808 subscribed.

I think the docs that @LucasWerkmeister wrote were the actionable outcome here.

bd808 renamed this task from Inconsistent user permissions for users who were recently added to a new group (June 2025 edition) to Groups requiring 2FA via $wgOATHRequiredForGroups do not clearly warn users that thier permissions will not work.Jul 15 2025, 8:47 PM
Tgr subscribed.

OATHAuth removes interface-admin from your effective groups when you don't use 2FA. Some groups-related MediaWiki APIs report your effective groups (as in UserGroupManager::getUserEffectiveGroups(), others report your explicit groups (as in UserGroupManager::getUserGroups()) which don't include groups added/removed dynamically by hooks, autopromotion-based groups, implicit groups like temp... It's not great, but also not easy to fix (calculating effective groups is probably too expensive for batch APIs, and it's impossible to filter on non-explicit groups), and not specific to OATHAuth.

Because permissions are one level removed from groups, it is hard for OATHAuth to know when a failed permission check is caused by a group membership it is suppressing, so you end up with a generic error message. Special:Preferences gives you a warning about your groups being suppressed though.

I don't think this is fixable by documentation alone, but I also don't have great ideas of how to fix.

  • Maybe there should be something like an undismissable notification telling the user to enroll to 2FA. After all the goal is to make sure the user enables it; suppressing the permissions is just the mechanism to achieve that.
  • Maybe we could define all affected user rights in configuration (blehh) and use some permission hook to customize error messages for those permission checks.
  • Maybe we could use a hook like GetUserPermissionsErrors to check when the error message is "you need to be in groups X, Y or Z" where the user's explicit groups intersect with those but we are suppressing them, and then change the error message. (Requires message parsing, blehh.)
  • We could add some easy-to-access flag for "group X is being suppressed for the current user" and add Wikimedia-specific UX customizations specially for the groups we require 2FA for. (Use some edit-form-related hook to add a warning when the user is editing in the MediaWiki namespace and their ifadmin group is suppressed etc.) Sounds like a nightmare to maintain.

I think I'd go with the notification and / or overriding permission checks, if we can automatically calculate which permissions of the user are being suppressed (doesn't seem that hard).

It would also be nice to add warnings to Special:ListGroupRights but that requires some really nasty hooks, or somehow bringing the whole concept of suppressing groups to core. That seems like too much effort for something that's supposed to be a transitional enforcement mechanism that eventually won't be required because everyone will have 2FA set up and the software will verify this for new users being promoted to the relevant groups.

bd808 renamed this task from Groups requiring 2FA via $wgOATHRequiredForGroups do not clearly warn users that thier permissions will not work to Groups requiring 2FA via $wgOATHRequiredForGroups do not clearly warn users without 2FA that their permissions were truncated.Jul 15 2025, 9:43 PM
bd808 removed LucasWerkmeister as the assignee of this task.
bd808 removed a subscriber: Lobo77.

@Tgr it looks like you're moving this task to maybe work on it? I just ran into this frustration again trying to help a staff member figure out why she couldn't use CentralNotice (I should have remembered, as it bit me before). I was thinking I might make a CN-specific change to check for OATH enrollment T394321: Add text to CentralNotice admin UI when user has admin but no 2FA and add a warning, but if you're solving it for the general case I'll wait for the better fix.

@Tgr how about changing

You do not have permission to edit this JavaScript page because it may affect all visitors.

to something like

Only interface administrators can edit pages that may affect all visitors. If you are an interface administrator, you may need to enable two-factor authentication.

Saying "may" as non-WMF wikis may not require 2FA.

Saying "may" as non-WMF wikis may not require 2FA.

We could put it as an override in WikimediaMessages? That’s loaded both in prod and on the Beta cluster.

Yeah that works as a one-off solution. Would be nice to have something more systematic though. JS editing isn't the only action where we'll have this problem.

JS editing isn't the only action where we'll have this problem.

Ran into this with a new CheckUser today.