Wikimedia Developer Support

What's the right way to create a new system user?



Extensions often need to do things as users, and so create “system users” for this purpose. There seems to be a few different ways of doing this. Most start by creating a new user:

$user = User::newSystemUser( 'CoolExtension sys user', [ 'steal' => true ] );

And then often add it to the bot group:

$user->addGroup( 'bot' );

Or give it some new rights directly, without giving it a group:

$user->mRights = array_merge( $user->getRights(), [ 'upload' ] );

Or they might validate its email:

$user->saveSettings(); // Even if it's already confirmed?

Are these examples correct form? What’s the right way to do this stuff? Are all system users also called bots (and should therefore be in the bots group)? What’s the expected behaviour of one of these users (as far as sysops changing their names, permissions, etc.)?


So, the correct way is indeed to use User::newSystemUser().

Depending on what exactly you are doing you may also want to reserve the username in $wgReservedUsernames.
Extensions can use the UserGetReservedNames hook to add to this array.

Groups and rights really depend on what sort of things you are doing with the user I guess. If you are working on a low level within MediaWiki making changes many permission checks etc. can be skipped.
If you do use code that has a permission check then you might need to add a right or a group to the user.

As for the confirming email and re saving settings, I have no idea, again this might be required by whatever code that particular system user is triggering.

Are all system users also called bots

I don’t believe so. There doesn’t seem to be any code of documentation to suggest this.

What’s the expected behaviour of one of these users (as far as sysops changing their names, permissions, etc.)?

I see no reason changing permissions would break anything, however I also see no reason to change the permissions.

Changing their username will just end up in a bit of a mess, if a system user (which probably has a reserved name) has edits, then renaming it would result in the edit being reassigned. However, the code for the system user most probably has a hardcoded username, and when User::newSystemUser is called again, it will simply get created again, but the older edits would remain with the renamed user.


System users are no different from normal users except that 1) they don’t go through the normal registration callbacks (so e.g. if you use CentralAuth no global user will be created) and 2) all their authentication methods are deliberately broken (so a human user can never log into a system user account, not even if they steal the password DB or whatever). That includes not having an email address (which can be used for password reset), so creating a system user and then adding a confirmed email seems a bit pointless.

Other than that they can be normally renamed or blocked or whatever (although if you rename then the newSystemUser call will just recreate them).

Adding system users to groups with social significance (bot, admin etc) might be annoying or confusing to users so if you do need them to have specific rights then messing with mRights is better. (We really should have a method for doing that, to make it “official”.)


Yeah, the thing about creating a system user and then giving them a valid email address seems a bit wrong to me too. It came up in a discussion about the GraphViz extension, for which we were looking at creating a system user to upload graphs for users who don’t have upload permissions (i.e. can edit the graph text in a page, but because the graph image is saved as an uploaded file they can’t render it). The problem came when $wgEmailConfirmToEdit was enabled, because the system user then couldn’t upload either.


Probably a sign that you should use lower-level methods. LocalFile::upload does not care about user permissions.