Least-privilege users and roles
TeselaDB
TeselaDB team
25 minIntermediate
Create a role that reads and writes one collection without deleting from it and give it to an application's user.
An application that only creates and updates orders does not need to delete them or to read other collections. With a custom role you give it only those actions on that collection, so if its password leaks, whoever uses it cannot do more than the application could.
What you will build
An ordersWriter role with the find, insert and update actions on the shop.orders collection, and a
shop-orders user that only has that role.
Requirements
- A TeselaDB cluster and
mongosh. - A user allowed to create roles and users, such as
root.
1. Create the role
Each privilege joins a resource, here a collection, with the actions allowed on it:
db.getSiblingDB("admin").createRole({
role: "ordersWriter",
privileges: [{ resource: { db: "shop", collection: "orders" }, actions: ["find", "insert", "update"] }],
roles: [],
});2. Create the user
The user has only the ordersWriter role. passwordPrompt() asks for the password without leaving it in
the mongosh history:
db.getSiblingDB("admin").createUser({ user: "shop-orders", pwd: passwordPrompt(), roles: ["ordersWriter"] });Try it
Connected as shop-orders, try an insert and a delete on shop.orders, knowing that the role carries the insert
action but none that deletes documents, so only the first of the two writes below can work:
const shop = db.getSiblingDB("shop");
shop.orders.insertOne({ total: 30 });
shop.orders.deleteOne({});The insert works and the delete fails with Unauthorized, the same error you get if you try to read another
collection of shop.
Clean up
If it was a test, drop the user and the role while connected as root:
db.getSiblingDB("admin").dropUser("shop-orders");
db.getSiblingDB("admin").dropRole("ordersWriter");Next steps
- Users and roles, with the built-in roles and the privileges that each of them carries.
- Privilege actions, with every action a role can carry.