Skip to content
Commitpedia
Log in Join & edit

Turn on MongoDB authentication and create least-privilege users

A fresh MongoDB install accepts connections without a password. Create a user administrator, enable authorization, then give each application and backup job its own user with only the roles it needs.

Not checked by a trusted editor yet Last edited Outdated?

Edit history of Turn on MongoDB authentication and create least-privilege users: 1 recorded edit
Edit history · 1 edit
Type
Article
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Reading
3 min

Out of the box, mongod runs without access control: anyone who can reach the port can read and change everything. The default bindIp of 127.0.0.1 limits that to the local machine, but as soon as you open the port to other hosts you need authentication. This guide covers a single self-managed server using SCRAM, the default username and password mechanism.

Replica sets and sharded clusters also need internal authentication between members (a keyfile or X.509 certificates). Follow MongoDB’s keyfile tutorial for those; the user steps below are the same.

1. Create the user administrator

MongoDB has a localhost exception: while no users exist, a client connected from the same host may create the first user. Use it to create an administrator in the admin database.

  1. Connect locally: mongosh --port 27017.
  2. Switch to the admin database and create the user. passwordPrompt() asks for the password, so it does not end up in your shell history.
use admin
db.createUser({
  user: "admin",
  pwd: passwordPrompt(),
  roles: [
    { role: "userAdminAnyDatabase", db: "admin" },
    { role: "readWriteAnyDatabase", db: "admin" }
  ]
})

userAdminAnyDatabase lets this account manage users on every database. Treat it like root: anyone with it can grant themselves any role.

2. Enable authorization

Edit the configuration file (/etc/mongod.conf for the Linux packages) and add a security section. YAML is indentation-sensitive: use spaces, not tabs.

security:
  authorization: enabled

Check before you run this

  • Runs with administrator rights. Make sure you understand every line.
sudo systemctl restart mongod
sudo systemctl status mongod
sudo tail -n 50 /var/log/mongodb/mongod.log

If you started mongod by hand instead of as a service, the command-line equivalent is mongod --auth.

3. Log in as the administrator

mongosh --port 27017 --authenticationDatabase admin -u admin -p

With -p and no value, mongosh prompts for the password. --authenticationDatabase names the database where the user was created. Getting it wrong is the most common reason a correct password is rejected.

Check who you are and what you may do:

db.runCommand({ connectionStatus: 1 })

4. Create users for applications and jobs

Give every application, script and person its own user, with roles limited to what they need. Built-in roles cover most cases:

  • read and readWrite: read, or read and write, the non-system collections of one database.
  • dbAdmin: indexes, statistics and schema tasks on one database, without user management.
  • backup and restore: the minimal privileges for mongodump and mongorestore. They are defined in the admin database.
  • clusterMonitor: read-only access for monitoring tools.
  • root: everything. Keep it for emergencies.
use admin
db.createUser({
  user: "appuser",
  pwd: passwordPrompt(),
  roles: [ { role: "readWrite", db: "shop" } ]
})

db.createUser({
  user: "backup",
  pwd: passwordPrompt(),
  roles: [ { role: "backup", db: "admin" } ]
})

db.createUser({
  user: "reporting",
  pwd: passwordPrompt(),
  roles: [ { role: "read", db: "shop" } ]
})

These users are created in admin, so admin is their authentication database. The roles still apply only to the databases named in them. Clients must pass the authentication database too, for example with authSource in the connection string:

mongodb://appuser:[email protected]:27017/shop?authSource=admin

Keep that string in your application’s secret store or environment, not in source control. If the password contains characters such as @, : or /, percent-encode them in the URI.

5. Review and maintain users

use admin
db.getUsers()                                              // list users in this database
db.grantRolesToUser("reporting", [ { role: "read", db: "analytics" } ])
db.revokeRolesFromUser("reporting", [ { role: "read", db: "analytics" } ])
db.changeUserPassword("appuser", passwordPrompt())

Removing a user is permanent and breaks every client that uses it. Check with db.getUser("olduser") and your application configuration first, then run db.dropUser("olduser").

Before you open the port

  • Authentication is on and you tested a login with each new user.
  • net.bindIp lists only the interfaces clients need, never a public address without a firewall in front.
  • A host firewall allows port 27017 only from application servers and admin hosts.
  • TLS is configured if traffic crosses an untrusted network, so passwords and data are not sent in clear text.

Official documentation

See also

Repos in the wild

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. Commitpedia +4,782 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?