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
- How to install and configure MongoDB 6 on Ubuntu 22.04
- How to install and configure MongoDB 6 on Rocky Linux/Alma Linux 9
- How to run Mongodb with Docker and Docker-Compose
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 legacymongoshell was removed in MongoDB 6.0; ifmongoshis missing, install themongodb-mongoshpackage 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.
Comment out the
securityblock in/etc/mongod.conf, and setbindIp: 127.0.0.1undernetso that nothing else can connect while the database is open:net: port: 27017 bindIp: 127.0.0.1 #security: # authorization: enabledRestart and reset the password (or create a new admin):
sudo systemctl restart mongod mongosh admin --eval 'db.changeUserPassword("dbadmin", passwordPrompt())'Restore the original
securityandnetsettings, then stop and start the service again withsudo systemctl restart mongod. Always let MongoDB shut down cleanly here (nokill -9): a hard kill straight after the change can lose it.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.