MongoDB
How to manage users and authentication in MongoDB
Introduction
Managing users and authentication are some of the most important administration tasks of managing MongoDB servers. You must ensure that the server is configured to be able to properly identify your users and applications and deny connections or operations that are unable to authenticate correctly.
To manage these requirements, you must be able to decide which the users your server requires and create those accounts. As part of this process, you can set the authentication details to allow external access using the new identity.
In this guide, we will walk through how to create, view, and remove user accounts. We will go over how to set up authentication for your accounts and how to update the credentials when you need to change your user passwords.
If you're using MongoDB, checkout Prisma's MongoDB connector! You can use the Prisma Client to manage production MongoDB databases with confidence.
To get started working with MongoDB and Prisma, checkout our getting started from scratch guide or how to add to an existing project.
Prerequisites
To follow along with this guide, you'll need an account on a MongoDB server with the appropriate privileges.
Commands and methods we will use
To create, modify, and delete users within MongoDB and configure authentication, the core methods you need are:
db.createUser
: create a new MongoDB user accountdb.updateUser
: update the details of a user accountdb.changeUserPassword
: change the password used by a user accountdb.dropUser
: delete a MongoDB user account
Additionally, the following database command is useful for finding information about users on the system:
db.runCommand('usersInfo')
: show information about one or more MongoDB user accounts
Required privileges
To execute the commands above, you need to login to MongoDB with an account with a number of different privilege actions. The specific privileges you require depend on the commands you need to use.
To get info about other users, your current user must have the following privilege action enabled:
To create new users, your current user must have the following privilege actions enabled:
To change a user's password or account details, you might need the following privileges:
changeOwnPassword
privilege action to change your own account passwordchangeOwnCustomData
privilege action to change your own account's custom datachangePassword
privilege action to change other users' passwordschangeCustomData
privilege action to change other users' custom data
We won't be covering role management in this guide, so the grantRole
and revokeRole
privilege actions are not be required.
To delete a user account, your current user must have the following privilege action enabled:
Understanding how MongoDB implements users and authentication
Before we start creating and managing accounts, it's helpful to take some time to get familiar with how MongoDB defines and stores this information.
In MongoDB, user accounts are a combination of the account username along with a specific authentication database. The authentication database is simply the database where the user is defined and does not imply a limitation on scope or rights. Authentication databases are regular databases used to manage other data and are not special, dedicated databases.
A user account name must be unique in its authentication database. However, the same username may be reused with a different authentication database to create a new, distinct user account.
As a result of this design, an account can only be accurately identified by including the username and authentication database. To authenticate to an account, one also needs to be able to provide the credentials associated with an account. This is usually a password, but can also be a certificate.
How do you create users?
Now that we've taken a look at how MongoDB conceptualizes user accounts, we can discuss how to create new users. Remember to log in to your MongoDB server with a user that has the appropriate privileges to follow along.
To create a new user, you must first switch to the database you want to use as the new user's authentication database.
First, you can get a list of the databases that are already configured on your system by typing:
show dbs
admin 0.000GBconfig 0.000GBlocal 0.000GB
Switch to the database the user will be associated with using the use
command:
use admin
switched to db admin
To create a new user, you can use either the db.createUser()
method or you can use the createUser
database command. Either way, you will need to pass the username (the user
field), password (the pwd
field), and an array of roles that the user should be added to (the roles
key) within a user
object.
To create a new user called tom
with a password set to hellothere
with an empty roles array using the db.createUser()
method, you can type:
db.createUser({user: "tom",pwd: "hellothere",roles: []})
Successfully added user: { "user" : "tom", "roles" : [ ] }
The same operation using the createUser
database command would look like this:
db.runCommand({createUser: "tom",pwd: "hellothere",roles: []})
Successfully added user: { "user" : "tom", "roles" : [ ] }
The two different options are very similar, so we'll only be showing the database methods where applicable moving forward. However, if you prefer the database command syntax, you can find each of the associated commands in the MongoDB command reference documentation.
In the above commands, we explicitly defined the password inline within the user
object. To prevent the password from being logged and retrievable, you can alternatively use the passwordPrompt()
method within the user
document to have MongoDB interactively prompt you for a password when the command is run. The password will not be visible, so your command history will be clean:
db.createUser({user: "tom",pwd: passwordPrompt(),roles: []})
Enter password:Successfully added user: { "user" : "tom", "roles" : [ ] }
Keep in mind that the password will still be sent to the server in plain text if you do not have TLS/SSL enabled.
How do you show existing users?
Next, let's take a look at how to find information about the existing users.
To return multiple users, you can use the db.getUsers()
method on to show all of the users within the current database. First, switch to the database you're interested in querying:
use admin
Next, use the db.getUsers()
method to return all of the users associated with the current database:
db.getUsers()
[{"_id" : "admin.root","userId" : UUID("f5ded238-19c9-4886-b649-711ec36993cb"),"user" : "root","db" : "admin","roles" : [{"role" : "root","db" : "admin"}],"mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"]},{"_id" : "admin.tom","userId" : UUID("e7a0abde-a9f9-412a-bfd5-eb11fda41fd3"),"user" : "tom","db" : "admin","roles" : [ ],"mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"]}]
To additionally show each user's credential information, pass an object to the method with the showCredentials
key to true
:
use admindb.getUsers({showCredentials: true})
[{"_id" : "admin.root",. . ."credentials" : {"SCRAM-SHA-1" : {"iterationCount" : 10000,"salt" : "WpB0H4f7dG8XlCDyaVzarA==","storedKey" : "b11nA1+mGo3+Tr8P//u3NEdJLHk=","serverKey" : "3xE8o663hjqySrMCQcXjSxmjmhk="},"SCRAM-SHA-256" : {"iterationCount" : 15000,"salt" : "UtsfNRedf2ek5tbWFoGs2g52U0H7Na44wV4rYA==","storedKey" : "mz9/qHnI79pNAIQm0MZTKZ0U3qFk0xhUDd2grvKtMdI=","serverKey" : "c/sA4j+I/29Ea1y07zxoMcBgHFoYTUAa6luX3Z9sToQ="}},. . .},{"_id" : "admin.tom",. . ."credentials" : {"SCRAM-SHA-1" : {"iterationCount" : 10000,"salt" : "qCbxWQSGt3QoN3S1aM5AEg==","storedKey" : "hypim5+m2wqbS1gc47o2itc7jew=","serverKey" : "h9myNoSvY2015yqvw3UldmJzZCg="},"SCRAM-SHA-256" : {"iterationCount" : 15000,"salt" : "lNtIVL79J8FF+uPaFfRMwPK079gfLEUrsQe3Qg==","storedKey" : "u8pgn3OJiZxIwEL7ryZkoAF5bnMefQEEsZDTXNDCTRY=","serverKey" : "BmmfVeikSA0DN1aZmyZP9NXi5owxGr1ZRmVX2XH8qVg="}},. . .}]
To query for users that match certain criteria, you can pass an object that defines a filter
key that defines matching condition.
For instance, to get information about all of the users in the current database that have the root
role, you could type:
use admindb.getUsers({filter: {"roles.role": "root"}})
[{"_id" : "admin.root","userId" : UUID("f5ded238-19c9-4886-b649-711ec36993cb"),"user" : "root","db" : "admin","roles" : [{"role" : "root","db" : "admin"}],"mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"]}]
To get a specific user, you can use the db.getUser()
method instead. This works like the db.getUsers()
method, but returns a single user. Instead of passing an object to the method, you pass a string containing the username you wish to retrieve:
use admindb.getUser("tom")
{"_id" : "admin.tom","userId" : UUID("e7a0abde-a9f9-412a-bfd5-eb11fda41fd3"),"user" : "tom","db" : "admin","roles" : [ ],"mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"]}
You can optionally include an extra args
object that allows you to specify additional information you'd like by setting the following keys to true
:
showCredentials
: shows credential information in addition to the regular outputshowPrivileges
: shows privilege information in addition to the regular outputshowAuthenticationRestrictions
: shows authentication restrictions on the account in addition to the regular output
For example, you can tell MongoDB to supply you will all of the above information by typing:
use admindb.getUser("tom",{showCredentials: true,showPrivileges: true,showAuthenticationRestrictions: true})
{"_id" : "admin.tom","userId" : UUID("e7a0abde-a9f9-412a-bfd5-eb11fda41fd3"),"user" : "tom","db" : "admin","mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"],"credentials" : {"SCRAM-SHA-1" : {"iterationCount" : 10000,"salt" : "qCbxWQSGt3QoN3S1aM5AEg==","storedKey" : "hypim5+m2wqbS1gc47o2itc7jew=","serverKey" : "h9myNoSvY2015yqvw3UldmJzZCg="},"SCRAM-SHA-256" : {"iterationCount" : 15000,"salt" : "lNtIVL79J8FF+uPaFfRMwPK079gfLEUrsQe3Qg==","storedKey" : "u8pgn3OJiZxIwEL7ryZkoAF5bnMefQEEsZDTXNDCTRY=","serverKey" : "BmmfVeikSA0DN1aZmyZP9NXi5owxGr1ZRmVX2XH8qVg="}},"roles" : [ ],"inheritedRoles" : [ ],"inheritedPrivileges" : [ ],"inheritedAuthenticationRestrictions" : [ ],"authenticationRestrictions" : [ ]}
How do you change the password for a MongoDB user?
To change a user's password, you can use the db.changeUserPassword()
method. Again, you must switch to the user's authentication database before executing the command.
The db.changeUserPassword()
method takes two arguments: the username of the account you wish to change and the new password for the account.
For instance, to change the password for the user tom
authenticated with the admin
database to secretpassword
, you could type:
use admindb.changeUserPassword("tom", "secretpassword")
Just as with the db.createUser()
method, you can use the passwordPrompt()
method for the second argument instead of providing a password inline. MongoDB will prompt you to enter a password when the command is executed:
use admindb.changeUserPassword("tom", passwordPrompt())
Enter password:
How do you change other user account details?
To change other information associated with a user account, you can use the db.updateUser()
method. Make sure you switch to the user's authentication database before updating their details.
The db.updateUser()
method requires you to specify the username and then provide an object containing the data you wish to update. Any field you choose to update will be completely replaced with the new information, so be sure to include the original data as well as the new data in your object if you only hope to append new information.
The object that you include in the command with the change information can contain many different fields. Let's go over them:
customData
: Any arbitrary data to be associated with the user account.roles
: The roles that the user is granted. It is often better to use thedb.grantRolesToUser()
anddb.revokeRolesFromUser()
methods to control role membership rather than updating with this key as you can append and remove roles individually.pwd
: The user's password. Using thedb.ChangeUserPassword()
method is usually easier if that is the only field that needs to be updated.authenticationRestrictions
: Specifies restrictions for the account that can limit the IP addresses users can connect from or to. The value of this key is an object or array that definesclientSource
and orserverAddress
, which contain arrays specifying the valid IP addresses or ranges. Find out more in the MongoDB docs on authentication restrictions.mechanisms
: The specific authentication mechanisms to be used for credentials. Can be set to either one or both ofSCRAM-SHA-1
orSCRAM-SHA-256
, but can only be changed to a subset of the current mechanisms if a new password isn't currently being supplied.passwordDigestor
: Specifies which component processes the user's password. Can be eitherserver
(the default) orclient
.
As an example, we can update the tom
account that authenticates against the admin
database to only be able to login from the same computer that hosts the server itself by changing the authenticationRestrictions
field:
use admindb.updateUser("tom", {authenticationRestrictions: [ {clientSource: ["127.0.0.1", "::1"],serverAddress: ["127.0.0.1", "::1"]} ]})
Now, if you ask MongoDB to show you the relevant information about the user, it will display additional restrictions for the account:
use admindb.getUser("tom", {showAuthenticationRestrictions: true})
{"_id" : "admin.tom","userId" : UUID("e7a0abde-a9f9-412a-bfd5-eb11fda41fd3"),"user" : "tom","db" : "admin","mechanisms" : ["SCRAM-SHA-1","SCRAM-SHA-256"],"roles" : [ ],"authenticationRestrictions" : [{"clientSource" : ["127.0.0.1","::1"],"serverAddress" : ["127.0.0.1","::1"]}],"inheritedRoles" : [ ],"inheritedPrivileges" : [ ],"inheritedAuthenticationRestrictions" : [ ]}
To revoke those restrictions, we can run the command again with an empty array:
use admindb.changeUser("tom", {authenticationRestrictions: []})
How do you delete MongoDB users?
To remove MongoDB user accounts, you can use the db.dropUser()
method. Be sure to connect to the user's authentication database before removing them.
To execute the db.dropUser()
method, you need to supply the name of the user you wish to remove:
db.dropUser("tom")
Upon successful deletion, MongoDB will return true
:
true
If the account did not exist in the current database, it will instead return false
.
Conclusion
MongoDB's user management and authentication configuration lets you control who can connect to your servers and what their user properties are. In a following article, we'll cover how to restrict the level of access that users have by tackling the authorization portion of user management.
If you're using MongoDB, checkout Prisma's MongoDB connector! You can use the Prisma Client to manage production MongoDB databases with confidence.
To get started working with MongoDB and Prisma, checkout our getting started from scratch guide or how to add to an existing project.
FAQ
To list existing users in MongoDB, you can use the db.getUsers()
method to show all of the users within the current database.
The syntax would look like:
use admindb.getUsers()
For more details on db.getUsers()
.
In order to create a database admin user in MongoDB, you will want to use the db.createUser()
method in the admin
database.
The following demonstrates the syntax to use for creating database admins.
use admindb.createUser({ user: "tom",pwd: "hellothere",roles:[{role: "dbAdmin" , db:"admin"}]})
To remove a MongoDB user you can use the db.dropUser()
method. This needs to be done in the admin
database, and the syntax would look like this:
use admindb.dropUser("tom")
To get a list of all existing users in MongoDB, you can use the db.getUsers()
method.
The basic syntax would look like:
use admindb.getUsers()
To query for a specific user, you can use the db.getUser()
method with the showPrivileges
arg
set to true
.
The basic syntax would look like:
use admindb.getUser("tom",{showPrivileges: true,})