Restricting Database Access Using Role-Based Access Control (Built-In Roles)
Common use cases for RBAC include enforcing least privileges by creating users with read-only access to the databases in a cluster, and multi-tenant application designs that enable a single user to access a given database in a cluster.
Note
All new users created before March 26, 2020 have been granted the dbAdminAnyDatabase
, readWriteAnyDatabase
, and clusterAdmin
roles. It is recommended that you reevaluate all existing users and modify the roles as necessary to enforce least privileges for your clusters.
The following are important terms and concepts related to role-based access control. For more information on Amazon DocumentDB users, see Managing Amazon DocumentDB Users.
User — An individual entity that can authenticate to the database and perform operations.
Password — A secret that is used to authenticate the user.
Role — Authorizes a user to perform actions on one or more databases.
Admin Database — The database in which users are stored and authorized against.
Database (
db
) — The namespace within clusters that contains collections for storing documents.
The following command creates a user named sample-user
.
In this example:
user: "sample-user"
— Indicates the user name.pwd: "abc123"
— Indicates the user password.role: "read", "db: "sample-database"
— Indicates that the usersample-user
will have read permissions insample-database
.
The following example shows the output after you get the user sample-user
with db.getUser(sample-user)
. In this example, the user sample-user
resides in the admin
database but has the read role for the database sample-database
.
When creating users, if you omit the db
field when specifying the role, Amazon DocumentDB will implicitly attribute the role to the database in which the connection is being issued against. For example, if your connection is issued against the database sample-database
and you run the following command, the user sample-user
will be created in the admin
database and will have readWrite
permissions to the database sample-database
.
db.createUser({user: "sample-user", pwd: "abc123", roles: ["readWrite"]})
Output from this operation looks something like the following.
{
"user" : "sample-user",
"roles" : [
{
"db" : "sample-database",
"role" : "readWrite"
}
]
}
Creating users with roles that are scoped across all databases (for example, readAnyDatabase
) require that you either be in the context of the admin
database when creating the user, or you explicitly state the database for the role when creating the user. To issue commands against the admin
database, you can use the command use admin
. For more information, see .
Getting Started with RBAC
To help you get started with role-based access control, this section walks you through an example scenario of enforcing least privilege by creating roles for three users with different job functions.
user1
is a new manager that needs to be able to view and access all databases in a cluster.user2
is a new employee that needs access to only one database,sample-database-1
, in that same cluster.user3
is an existing employee that needs to view and access a different database,sample-database-2
that they didn’t have access to before, in the same cluster.
At a point later, both user1
and user2
leave the company and so their access must be revoked.
To create users and grant roles, the user that you authenticate to the cluster with must have an associated role that can perform actions for createUser
and grantRole
. For example, the roles admin
and userAdminAnyDatabase
can both grant such abilities, for example. For actions per role, see .
Note
In Amazon DocumentDB, all user and role operations (for example, create
, get
, drop
, grant
, revoke
, etc.) are implicitly performed in the admin
database whether or not you are issuing commands against the admin
database.
First, to understand what the current users and roles are in the cluster, you can run the show users
command, as in the following example. You will see two users, serviceadmin
and the master user for the cluster. These two users always exist and cannot be deleted. For more information, see Managing Amazon DocumentDB Users.
show users
For user1
, create a role with read and write access to all databases in the entire cluster with the following command.
db.createUser({user: "user1", pwd: "abc123", roles: [{role: "readWriteAnyDatabase", db: "admin"}]})
Output from this operation looks something like the following.
{
"user" : "user1",
"roles" : [
{
"role" : "readWriteAnyDatabase",
"db" : "admin"
}
]
}
For user2
, create a role with read-only access to the database sample-database-1
with the following command.
db.createUser({user: "user2", pwd: "abc123", roles: [{role: "read", db: "sample-database-1"}]})
Output from this operation looks something like the following.
{
"user" : "user2",
"roles" : [
{
"role" : "read",
"db" : "sample-database-1"
}
]
}
To simulate the scenario that user3
is an existing user, first create the user user3
, and then assign a new role to user3
.
db.createUser({user: "user3", pwd: "abc123", roles: [{role: "readWrite", db: "sample-database-1"}]})
Output from this operation looks something like the following.
{
"user" : "user3",
"roles" : [
{
"role" : "readWrite",
"db" : "sample-database-1"
}
]
Now that the user user3
has been created, assign user3
the role read
to sample-database-2
.
db.grantRolesToUser("user3", [{role: "read", db: "sample-database-2"}])
Lastly, both user1
and user2
leave the company and need their access to the cluster revoked. You can do this by dropping the users, as follows.
db.dropUser("user1")
db.dropUser("user2")
To ensure that all users have the appropriate roles, you can list all users with the following command.
Output from this operation looks something like the following.
{
"_id" : "serviceadmin",
"user" : "serviceadmin",
"db" : "admin",
"roles" : [
{
"db" : "admin",
"role" : "root"
}
]
}
{
"_id" : "master-user",
"user" : "master-user",
"db" : "admin",
"roles" : [
{
"db" : "admin",
"role" : "root"
}
]
}
{
"_id" : "user3",
"user" : "user3",
"db" : "admin",
"roles" : [
{
"role" : "read"
},
{
"db" : "sample-database-1",
"role" : "readWrite"
}
]
}
When connecting to an Amazon DocumentDB cluster, you connect in the context of a particular database. By default, if you don’t specify a database in your connection string, you are automatically connected to the cluster in the context of the test
database. All collection level commands like insert
and find
are issued against collections in the test
database.
To see the database you are in the context of or — in other words — issuing commands against, use the db
command in the mongo shell, as follows.
Query:
db
Output:
test
Although the default connection might be in the context of the test
database, that does not necessarily mean that the user associated with the connection is authorized to perform actions on the test
database. In the preceding example scenario, if you authenticate as the user user3
, which has the readWrite
role for the sample-database-1
database, the default context of your connection is the test
database. However, if you try to insert a document into a collection on the test
database, you will receive an Authorization failure error message. This is because that user is not authorized to perform that command on that database, as shown below.
Query:
db
Output:
test
Query:
db.col.insert({x:1})
Output:
WriteCommandError({ "ok" : 0, "code" : 13, "errmsg" : "Authorization failure" })
If you change the context of your connection to the sample-database-1
database, you can write to the collection for which the user has the authorization to do so.
Query:
use sample-database-1
Output:
switched to db sample-database-1
Query:
db.col.insert({x:1})
Output:
WriteResult({ "nInserted" : 1})
When you authenticate to a cluster with a particular user, you can also specify the database in the connection string. Doing so removes the necessity to perform the use
command after the user has been authenticated to the admin
database.
The following connection string authenticates the user against the admin
database, but the context of the connection will be against the sample-database-1
database.
Common Commands
This section provides examples of common commands using role-based access control in Amazon DocumentDB. You must be in the context of the admin
database to create and modify users and roles. You can use the use admin
command to switch to the admin
database.
Note
Modifications to the users and roles will implicitly occur in the admin
database. Creating users with roles that are scoped across all databases (for example, readAnyDatabase
) requires that you are either in the context of the admin
database (that is, use admin
) when creating the user, or you explicitly state the database for the role when creating the user (as shown in Example 2 in this section).
Example 1: Create a user with read
role for the database foo
.
db.createUser({user: "readInFooBar", pwd: "abc123", roles: [{role: "read", db: "foo"}]})
Output from this operation looks something like the following.
{
"user" : "readInFooBar",
"roles" : [
{
"role" : "read",
"db" : "foo"
}
}
Example 2: Create a user with read access on all databases.
db.createUser({user: "readAllDBs", pwd: "abc123", roles: [{role: "readAnyDatabase", db: "admin"}]})
{
"user" : "readAllDBs",
"roles" : [
{
"role" : "readAnyDatabase",
"db" : "admin"
}
]
}
Example 3: Grant read
role to an existing user on a new database.
db.grantRolesToUser("readInFooBar", [{role: "read", db: "bar"}])
Example 4: Update a user’s role.
db.updateUser("readInFooBar", {roles: [{role: "read", db: "foo"}, {role: "read", db: "baz"}]})
Example 5: Revoke access to a database for a user.
db.revokeRolesFromUser("readInFooBar", [{role: "read", db: "baz"}])
Example 6: Describe a built-in role.
db.getRole("read", {showPrivileges:true})
Output from this operation looks something like the following.
{
"role" : "read",
"db" : "sample-database-1",
"isBuiltin" : true,
"roles" : [ ],
"inheritedRoles" : [ ],
"privileges" : [
{
"resource" : {
"db" : "sample-database-1",
"collection" : ""
},
"actions" : [
"changeStream",
"collStats",
"dbStats",
"find",
"killCursors",
"listCollections",
"listIndexes"
]
}
],
"inheritedPrivileges" : [
{
"resource" : {
"db" : "sample-database-1",
"collection" : ""
},
"actions" : [
"changeStream",
"collStats",
"dbStats",
"find",
"killCursors",
"listCollections",
"listIndexes"
]
}
]
}
Example 7: Drop a user from the cluster.
db.dropUser("readInFooBar")
Output from this operation looks something like the following.
true
In Amazon DocumentDB, user and role definitions are stored in the admin
database and users are authenticated against the admin
database. This functionality differs from the MongoDB Community Edition, but is consistent with MongoDB Atlas.
Amazon DocumentDB also supports change streams, which provide a time-ordered sequence of change events that occur within your cluster’s collections. The listChangeStreams
action is applied at the cluster level (that is, across all databases), and the modifyChangeStreams
action is applied at the database level.
Limits
The following table contains the limits for built-in roles in Amazon DocumentDB. Please note that Amazon DocumentDB does not currently support RBAC custom roles.
With role-based access control, you can create a user and grant it one or more roles to determine what operations that user can perform in a database or cluster.
The following is a list of built-in roles that are currently supported in Amazon DocumentDB.
Note
In Amazon DocumentDB 4.0, the ListCollection
and ListDatabase
commands can optionally use the authorizedCollections
and authorizedDatabases
parameters to list the collections and databases that the user has permission to access with requiring the listCollections
and listDatabase
roles, respectively. Also, users now have the ability to kill their own cursors without requiring the KillCursor
role.
Role Type | Role Name | Description | Actions |
---|---|---|---|
Database User | read | Grants a user read access to the specified database. |
|
readWrite | Grants the user read and write access to the specified database. | All actions from permissions.
| |
Cluster User | readAnyDatabase | Grants a user read access to all databases in the cluster. | All actions from
|
readWriteAnyDatabase | Grants a user read and write access to all databases in the cluster. | All actions from
| |
userAdminAnyDatabase | Grants a user the ability to assign and modify the roles or privileges any user has to the specified database. |
| |
dbAdminAnyDatabase | Grants a user the ability to perform database administration roles on any specified database. | All actions from
| |
Superuser | root | Grants a user access to the resources and operations of all the following roles combined: readWriteAnyDatabase , dbAdminAnyDatabase , userAdminAnyDatabase , clusterAdmin , restore , and backup . | All actions from |
Database Administration | dbAdmin | Grants a user the ability to perform administrative tasks on the specified database. |
|
dbOwner | Grants a user the ability to perform any administrative tasks on the specified database by combining the roles dbAdmin and readWrite . | All actions from | |
Cluster Administration | clusterAdmin | Grants a user the greatest cluster management access by combining the clusterManager , clusterMonitor , and hostManager roles. | All actions from
|
clusterManager | Grants a user the ability to take management and monitoring actions on the specified cluster. |
| |
clusterMonitor | Grants a user the ability to have read-only access to monitoring tools. |
| |
hostManager | Grants a user the ability to monitor and manage servers. |
| |
Backup Administration | backup | Grants a user the access needed to back up data. |
|
restore | Grants a user the access needed to restore data. |
|