How to Set Up Authentication in MongoDB with mongosh

Enable MongoDB authentication: create an admin and a least-privilege app user with mongosh, turn on authorization, connect, recover a lockout, add a keyfile.

In this guide we will learn how to set up authentication for MongoDB: an admin user, an application user that can only touch its own database, authorization switched on in mongod.conf, and the errors you will hit along the way. Every command and output below was run against MongoDB 9.0 with mongosh 2.14. The same steps work on any supported release, since createUser and security.authorization have not changed in years.

The default installation of MongoDB doesn’t have authentication enabled. Anyone who can reach port 27017 can read, change or drop every database. When you connect you will see this warning: Access control is not enabled for the database.

MongoDB is a cross-platform document-oriented NoSQL database program that uses JSON-like documents with optional schemas. MongoDB is developed by MongoDB Inc. and licensed under the Server Side Public License. Instead of storing data in tables of rows or columns like SQL databases, each record in a MongoDB database is a document described in BSON, a binary representation of the data. Applications can then retrieve this information in a JSON format.

Related Content

Prerequisites

To follow along this guide, you need:

  • A running MongoDB service on a Linux server
  • Root access to the server so you can make the configuration change
  • The MongoDB shell, mongosh. The legacy mongo shell was removed in MongoDB 6.0; if mongosh is missing, install the mongodb-mongosh package from the MongoDB repository.

Connecting to MongoDB and Creating admin user

Connect to the MongoDB service using mongosh:

mongosh --port 27017
Current Mongosh Log ID:	6af2d3eecbd9372f45d0f113
Connecting to:		mongodb://127.0.0.1:27017/?directConnection=true&serverSelectionTimeoutMS=2000&appName=mongosh+2.14.0
Using MongoDB:		9.0.4
Using Mongosh:		2.14.0

For mongosh info see: https://www.mongodb.com/docs/mongodb-shell/

------
   The server generated these startup warnings when booting
   2026-11-10T08:20:56.013+00:00: Access control is not enabled for the database. Read and write access to data and configuration is unrestricted
------

test>

Once connected, let us create our admin user. Users live in the database you create them in, and that database becomes their authentication database. Admin users belong in admin, so switch to it first. We are going to create a user dbadmin with the root role. passwordPrompt() asks for the password instead of leaving it in your shell history:

use admin
db.createUser(
  {
    user: "dbadmin",
    pwd: passwordPrompt(),
    roles: [ { role: "root", db: "admin" } ]
  }
)
Enter password
*************{ ok: 1 }

root can do anything, which is what you want for the person administering the server and nothing else. If you would rather have an admin that manages users but cannot read application data, use userAdminAnyDatabase instead.

Creating an application user with least privilege

Your application should not connect as dbadmin. Give it a user that can read and write its own database and nothing more. Here the app’s database is appdb, and the user is created in appdb too:

use appdb
db.createUser(
  {
    user: "appuser",
    pwd: passwordPrompt(),
    roles: [ { role: "readWrite", db: "appdb" } ]
  }
)
{ ok: 1 }

Use read instead of readWrite for reporting or backup jobs that never write. You can list the users in the current database with db.getUsers().

Updating MongoDB Configuration file

Next, let’s enable authentication in the global MongoDB config file located at /etc/mongod.conf.

Open the file with vim:

sudo vim /etc/mongod.conf

Then update the security section as follows. The key is indented two spaces under security:, and the file is YAML, so use spaces, never tabs:

security:
  authorization: enabled

To apply the changes, restart the MongoDB service:

sudo systemctl restart mongod

If the service fails to start, the config file usually has a YAML error. Check sudo journalctl -u mongod -n 50.

Testing MongoDB connection with Authentication in place

First, confirm that an unauthenticated connection can no longer read anything. mongosh still connects, but every command is refused:

mongosh --quiet --eval 'db.adminCommand({ listDatabases: 1 })'
MongoServerError: Command listDatabases requires authentication

Now log in as the admin. Note --authenticationDatabase admin: it must name the database the user was created in:

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

Enter the password when prompted. Confirm who you are logged in as:

db.runCommand({ connectionStatus: 1 }).authInfo
{
  authenticatedUsers: [ { user: 'dbadmin', db: 'admin' } ],
  authenticatedUserRoles: [ { role: 'root', db: 'admin' } ]
}

Connecting with a connection string

Applications and drivers use a connection string instead of flags. For the app user, the database in the path is also its authentication database, so nothing else is needed:

mongodb://appuser:<password>@127.0.0.1:27017/appdb

For a user stored in another database, such as dbadmin, add authSource:

mongodb://dbadmin:<password>@127.0.0.1:27017/?authSource=admin

If the password contains @, :, /, ?, # or %, percent-encode those characters (for example @ becomes %40), or the driver will misread the string.

The app user can work in appdb:

mongosh "mongodb://appuser:<password>@127.0.0.1:27017/appdb" \
  --eval 'db.orders.insertOne({ item: "book", qty: 1 })'
{
  acknowledged: true,
  insertedId: ObjectId('6af2d42b3fb0d69fc8dec3fd')
}

but is refused everywhere else, which is exactly the point:

MongoServerError: not authorized on otherdb to execute command { insert: "orders", ... }

The localhost exception

If you enable authorization before creating any user, you are not locked out. MongoDB’s localhost exception lets a client connected over 127.0.0.1 (or the Unix socket) create the first user, and only that. On a fresh database with authorization: enabled, the first createUser from localhost succeeds:

{ ok: 1 }

and the very next one, without logging in, is refused:

MongoServerError: Command createUser requires authentication

So make that first user an admin (root or userAdminAnyDatabase) in the admin database, then log in as it to create everyone else. The exception does not apply to remote connections, so you have to do this on the server itself.

Troubleshooting

Command find requires authentication (or listDatabases, insert, …): you connected without credentials. Pass -u, -p and --authenticationDatabase, or a full connection string.

not authorized on <db> to execute command: you are logged in, but your user’s roles do not cover that database or action. Grant a role with db.grantRolesToUser() as an admin, or connect as the right user.

Authentication failed.: wrong username or password, or, most often, the wrong authentication database. A user created in appdb fails when you pass --authenticationDatabase admin:

mongosh -u appuser -p --authenticationDatabase admin
MongoServerError: Authentication failed.

Check where the user lives with db.getSiblingDB("admin").system.users.find({}, { user: 1, db: 1 }) as an admin. The server log (/var/log/mongodb/mongod.log) records each failed attempt with the user and mechanism.

Recovering from a lockout

If you lose the admin password, or enabled authorization without an admin and the localhost exception no longer applies, restart MongoDB with authorization switched off, fix the user, and switch it back on.

  1. Comment out the security block in /etc/mongod.conf, and set bindIp: 127.0.0.1 under net so that nothing else can connect while the database is open:

    net:
      port: 27017
      bindIp: 127.0.0.1
    #security:
    #  authorization: enabled
    
  2. Restart and reset the password (or create a new admin):

    sudo systemctl restart mongod
    mongosh admin --eval 'db.changeUserPassword("dbadmin", passwordPrompt())'
    
  3. Restore the original security and net settings, then stop and start the service again with sudo systemctl restart mongod. Always let MongoDB shut down cleanly here (no kill -9): a hard kill straight after the change can lose it.

  4. Log in with the new password to confirm.

Replica sets: add a keyfile

On a replica set, the members also have to authenticate to each other. The simplest way is a shared keyfile. The commands below use the Debian/Ubuntu mongodb user; on RHEL-family systems it is mongod. Setting security.keyFile turns on authorization too.

Generate the keyfile once, then copy the same file to every member:

sudo install -d -m 700 -o mongodb -g mongodb /etc/mongodb
openssl rand -base64 756 | sudo tee /etc/mongodb/keyfile > /dev/null
sudo chown mongodb:mongodb /etc/mongodb/keyfile
sudo chmod 400 /etc/mongodb/keyfile

The service user is mongodb on Debian and Ubuntu, and mongod on RHEL, Rocky and Alma Linux. Then on each member:

security:
  authorization: enabled
  keyFile: /etc/mongodb/keyfile
replication:
  replSetName: rs0

Restart each member, then initiate the set and create the first admin through the localhost exception on the primary, exactly as above. If the permissions are too loose, mongod refuses to start and logs:

"Read security file failed","attr":{"error":{"code":30,"codeName":"InvalidPath","errmsg":"permissions on /etc/mongodb/keyfile are too open"}

Keyfiles are fine for a private network. For production clusters that cross untrusted networks, MongoDB recommends x.509 certificates for member authentication, together with TLS.

Conclusion

Congratulations for following this guide to the end. We now have authentication enabled on our MongoDB service, an admin user for us, a least-privilege user for the application, and a way back in if the admin password is ever lost.

Last updated on Nov 10, 2026 12:49 +0300
comments powered by Disqus
Citizix Ltd
Built with Hugo
Theme Stack designed by Jimmy