Databases

Create MongoDB Users and Assign Roles

Create MongoDB users with db.createUser, give them built-in or custom roles scoped to one database, and confirm each login with mongosh.

BeginnerLinux server5 min read

You will create MongoDB users, assign them only the roles they need, and confirm each login works. Once authorization is enabled, MongoDB denies everything by default, so a correctly scoped user is how your application reaches its own database and nothing else.

Before you start

You need:

  • A Linux VPS with MongoDB installed and running. If you have not done that yet, follow install MongoDB on Ubuntu and secure it.
  • The mongosh shell available on the server. Check with mongosh --version.
  • sudo or root access to edit /etc/mongod.conf and restart the service.
  • Either an existing administrative user, or a MongoDB instance with no users at all (the localhost exception lets you create the first one).

Note: Creating a user inside a database that does not exist yet also creates that database. That is normal and expected.

Connect to the MongoDB shell

Open a shell on the server and connect to the local instance:

Bash
mongosh --host 127.0.0.1 --port 27017

You will land on a prompt such as test>. If your instance already has users and authorization enabled, connect as the admin user instead:

Bash
mongosh "mongodb://siteAdmin@127.0.0.1:27017/admin?authSource=admin"

Create an administrative user

Administrative accounts belong in the admin database. Create one that can manage users and roles, plus read and write data across databases:

Bash
use admin

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

passwordPrompt asks for the password interactively so it never lands in your shell history. A successful call returns { ok: 1 }.

Tip: Keep administrative accounts for humans and maintenance only. Applications should never connect as siteAdmin.

Turn on authorization

User accounts do nothing until authorization is enabled. Edit /etc/mongod.conf and add the security block:

YAML
security:
  authorization: enabled

Warning: Restarting MongoDB disconnects every client, including running applications. Schedule this and warn anyone using the server.

Bash
sudo systemctl restart mongod
sudo systemctl status mongod

If you enabled authorization before creating any user, you can still create the first one through the localhost exception, but only while connected from the same machine and only while the instance has no users.

Create a database-scoped user

This is the account your application uses. It is created inside the application's own database, which means that database is also its authentication database:

Bash
use appdb

db.createUser({
  user: "deploy",
  pwd: passwordPrompt(),
  roles: [ { role: "readWrite", db: "appdb" } ]
})

Common built-in roles you can assign:

  • read — query data only.
  • readWrite — query and modify data.
  • dbAdmin — indexes, statistics and collection maintenance, no data reads.
  • dbOwner — combines readWrite, dbAdmin and userAdmin for that database.
  • clusterMonitor — read-only server and replica set statistics.

Grant, revoke and inspect roles

Roles are additive and can be changed without recreating the user:

Bash
db.grantRolesToUser("deploy", [ { role: "read", db: "reporting" } ])
db.revokeRolesFromUser("deploy", [ { role: "readWrite", db: "appdb" } ])
db.getUser("deploy")
db.getUsers()

If no built-in role fits, define a custom one in admin and grant it:

Bash
use admin

db.createRole({
  role: "readAppLogs",
  privileges: [
    { resource: { db: "appdb", collection: "logs" }, actions: [ "find" ] }
  ],
  roles: []
})

db.grantRolesToUser("deploy", [ { role: "readAppLogs", db: "admin" } ])

Other day-to-day tasks:

Bash
db.changeUserPassword("deploy", passwordPrompt())
db.dropUser("deploy")

Check it works

Log in as the application user. The authSource parameter must point at the database where the user was created:

Bash
mongosh "mongodb://deploy@127.0.0.1:27017/appdb?authSource=appdb"

Then confirm the identity and test a write:

Bash
db.runCommand({ connectionStatus: 1 })
db.things.insertOne({ ok: true })

The connection status should list deploy@appdb under authenticatedUsers, and the insert should return an acknowledged: true result. Finally, prove the boundary holds by trying to read a different database — you should get an authorization error rather than data.

Troubleshooting

  • Authentication failed — the connection string is missing authSource, or it points at the wrong database. Users created in appdb authenticate against appdb; admin users authenticate against admin.
  • not authorized on appdb to execute command — the role is missing or too narrow. Run db.getUser("deploy") as an admin and grant the role the operation needs, such as readWrite or dbAdmin.
  • command createUser requires authentication — the localhost exception no longer applies because at least one user exists, or you are connecting from a remote host. Connect locally as an admin user instead.
  • mongosh: command not found — the shell is not installed on this server. Install the mongosh package from MongoDB's repository, or use the legacy mongo shell on older releases.
  • The app connects but sees no collections — it authenticated against the wrong database or the role is scoped to another one. Check authSource and the roles array in db.getUser.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.