As a document-oriented NoSQL database, MongoDB offers flexibility and high performance for modern applications. However, properly securing and managing users is critical for any production database.
In this comprehensive guide, we will cover several methods for listing, viewing, and managing users in MongoDB. Whether you are a developer, DBA, or IT admin, understanding MongoDB access control is essential.
Overview of MongoDB Access Control
MongoDB manages access control at the database level. Users can be granted various privileges to read, write, and administer databases and collections. There are several built-in and custom roles for simplifying permission management.
To list and manage users, MongoDB provides the following database commands in the mongo shell:
db.getUsers()
– Returns information on all users for the current dbdb.dropUser()
– Deletes specified user accountdb.updateUser()
– Updates specific fields like password for a userdb.createUser()
– Creates new user account for the dbshow users
– Lists summary information for all users
In MongoDB Enterprise, additional tools like LDAP integration and auditing are also available. ACL rules can also be configured for more advanced user access control.
Next we will look at some practical examples of using these user management commands.
Listing All Users with db.getUsers()
The simplest way to output information on database users is the db.getUsers()
method. This prints detailed information on each user to the mongo shell.
By default, user credentials including the password hash are hidden. Let‘s use db.getUsers()
without any options:
> use accounts
switched to db accounts
> db.getUsers()
[
{
"_id" : "accounts.admin",
"userId" : UUID("108a77c0-8543-40ee-92bc-bd0aa9fa177a"),
"user" : "admin",
"db" : "accounts",
"roles" : [
{
"role" : "readWrite",
"db" : "accounts"
}
]
}
]
This prints information on a single ‘admin‘ user that has read-write access to the accounts database.
Each user document includes the autogenerated user ID, username, associated database, and assigned roles. Roles define a set of access privileges.
The output only showed one user. What if we want to display credentials like the password hash?
Viewing Password Hash with showCredentials
To view sensitive user credentials, we can pass the showCredentials
option to db.getUsers()
:
> db.getUsers({showCredentials: true})
[
{
"_id" : "accounts.admin",
"userId" : UUID("108a77c0-8543-40ee-92bc-bd0aa9fa177a"),
"user" : "admin",
"db" : "accounts",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "1gQyh1hoPD6QNfSEvF5hMg==",
"storedKey" : "wdJSbCdtXMrreS3c5lGFdgHWCVI=",
"serverKey" : "WqIlNhXvm8noLE5O0mnKJQVme50="
}
},
"roles" : [
{
"role" : "readWrite",
"db" : "accounts"
}
]
}
]
With showCredentials: true
, we can now see additional info like the password salt, hash iterations, and derived keys used for authentication.
Credentials are hashed securely on the server with the SCRAM-SHA-1 algorithm by default. Passwords are never exposed as plaintext.
Next let‘s look at how to delete users when they no longer need access.
Dropping Users with db.dropUser()
Over time, some users may change roles or leave your organization. Their database access should be revoked for security.
The db.dropUser()
method permanently deletes accounts:
> db.dropUser("testUser")
true
> db.getUsers()
[
{
"_id" : "accounts.admin",
"userId" : UUID("108a77c0-8543-40ee-92bc-bd0aa9fa177a"),
"user" : "admin",
"db" : "accounts",
"credentials" : {
...
},
"roles" : [
{
"role" : "readWrite",
"db" : "accounts"
}
]
}
]
After dropping "testUser", only the original "admin" user remains in db.getUsers()
output.
Dropping users instantly revokes their access but does not delete any documents they created previously.
Now let‘s look at updating passwords and other account fields instead of deleting users entirely.
Changing Passwords and User Data
Over time, passwords may expire due to corporate policy or users may switch roles or authentication mechanisms.
Rather than recreate entire user accounts, the db.updateUser()
method modifies specific fields:
> db.updateUser(
"admin",
{
customData : { employeeId: 12345 },
roles : [ { role: "dbOwner", db: "accounts" } ],
pwd: "new_password"
}
)
> db.getUsers({showCredentials: true})
[
{
"_id" : "accounts.admin",
"userId" : UUID("108a77c0-8543-40ee-92bc-bd0aa9fa177a"),
"user" : "admin",
"db" : "accounts",
"credentials" : {
"SCRAM-SHA-1" : {
"iterationCount" : 10000,
"salt" : "+rZXo5BmqSJNIuGmsz42mg==",
"storedKey" : "yS0qaWqPeCuXMbro3arXhAp7nRk=",
"serverKey" : "M6rXM++PiPeCtnObUQ36agV+bUs="
}
},
"customData" : {
"employeeId" : 12345
},
"roles" : [
{
"role" : "dbOwner",
"db" : "accounts"
}
]
}
]
Here we updated multiple properties for user "admin":
- Changed role from readWrite to dbOwner
- Added a custom employee ID field
- Reset password to a new value
The db.updateUser()
method modifies accounts in-place without deleting and recreating users like some databases require.
Now that we have covered updating existing users, let‘s look at how to create brand new user accounts.
Creating MongoDB Users with db.createUser()
Adding users via db.createUser()
establishes new accounts with specific roles and privileges. This method requires only a few key parameters:
db.createUser(
{
user: "reportsUser",
pwd: "456@user",
roles: [ "read" ]
}
)
This creates "reportsUser" with password "456@user" and read-only access.
We can also assign more advanced custom roles and add optional fields like custom data:
db.createUser(
{
user: "appUser",
pwd: "654@user",
customData: { empId: 4567 },
roles: [
{ role: "appRole",
db: "accounts",
privileges: [
{ resource: { db: "accounts", collection: "" },
actions: [ "insert", "update", "remove" ] }
],
roles: [
{ role: "read", db: "reporting" },
{ role: "read", db: "transaction" }
]
}
]
}
)
This creates "appUser" with a custom "appRole" that:
- Gets insert/update/delete access to all
accounts
collections - Read-only view access to
reporting
andtransaction
databases
Custom roles give the flexibility to define granular, database-specific privileges aligned with application requirements.
Now that we have covered the basics of managing users in the shell, let‘s look at the show users
alternative.
Listing All Users with show users
The show users
command provides a quick summary view of users for a database:
> show users
{
"_id" : "accounts.admin",
"userId" : UUID("108a77c0-8543-40ee-92bc-bd0aa9fa177a"),
"user" : "admin",
"db" : "accounts",
"customData" : {
"employeeId" : 12345
},
"roles" : [
{
"role" : "dbOwner",
"db" : "accounts"
}
]
}
{
"_id" : "accounts.reportsUser",
"userId" : UUID("956d4aa1-0903-424a-bd1c-426eeb993697"),
"user" : "reportsUser",
"db" : "accounts",
"roles" : [
{
"role" : "read",
"db" : "accounts"
}
]
}
This alternative output format containing user
, roles
, and customData
fields can be useful for quick checks or scripts versus the more verbose db.getUsers()
view.
One key limitation however is that show users
does not support the credentials option to show password hashes.
Now that we have covered the basics of managing users, let‘s discuss some best practices for MongoDB access control.
MongoDB User Access Best Practices
Properly securing MongoDB user access follows similar principles to other databases, but has some unique considerations:
-
Restrict to Necessary Privileges: When creating users and custom roles, grant the most restrictive privileges needed for the use case. Avoid overprovisioning access.
-
Enable Access Control: By default, MongoDB launches without access control for ease of development. Enforce authorization in production for security.
-
Complex Passwords: Choose sufficiently complex passwords following corporate security policy or standards like NIST 800-63B for credential strength guidance.
-
Temporary Access: Consider time-limited users with expiring passwords for temporary tasks like migrations where permanent access is not required.
-
SSL Encryption: Enable SSL/TLS data encryption to protect MongoDB connections from sniffing or man-in-the-middle attacks.
-
Auditing: MongoDB Enterprise features auditing to track user activity. Consider enabling this or using external tools to monitor database access.
By properly limiting privileges, monitoring user activity, and encrypting connections, production MongoDB deployment can ensure water-tight data security.
Conclusion
Managing users is an essential part of securing MongoDB in development and production. This guide provided several methods and best practices for creating, updating, deleting,and monitoring MongoDB users.
Key takeaways include:
db.getUsers()
lists detailed user information with the option for credentialsdb.createUser()
establishes new accounts with password and rolesdb.updateUser()
modifies passwords or account data without deleting usersdb.dropUser()
permanently revoke access when no longer needed- Enforcing the principle of least privilege and enabling auditing enhances security
Refer to the MongoDB manual for more on topics like LDAP integration, SSL, and building complex custom roles. Properly understanding and limiting MongoDB access is crucial for any administrator or developer working with sensitive data.