Resources Plans

Unlocking the Cosmos: A Guide to Azure Cosmos DB Access Control

author_profile
Maya Parizer
Tuesday, Jan 30th, 2024

Azure Cosmos DB is a globally distributed, multi-model database service provided by Microsoft. It is designed to allow developers to build highly responsive and scalable applications with low-latency data access around the world. It offers extensive support for various database engines, including NoSQL, MongoDB, Cassandra, Gremlin, Table, and PostgreSQL.

When creating an account, it defines the type of database to be used within it. Inside an account, one can virtually manage an unlimited amount of data and provisioned throughput. Each account type consists of different ways to logically organize data models. For example, in NoSQL data is organized in items that reside in containers that reside inside databases.

In this article, we will compare the different ways to authenticate and access an Azure Cosmos DB account, its data, and the network access options that are available.

Regarding accessing a Cosmos DB account, we will deepen our understanding of different types of operations that can be made regarding the data and management of an account. Afterwards we will observe each way to access an account with its specific security considerations. Regarding the network access, we will observe the differences between the options of network access and how they are represented in Azure Cosmos DB API Json objects, so we have a better understanding of the properties in the Cosmos DB account.

Cosmos DB Account Elements

When choosing an account to create, one must choose between NoSQL, Cassandra, MongoDB, Gremlin, Table, and PostgreSQL. It defines the type of database used in the account. The account type cannot be changed after the account creation.

After choosing an account type, the next is the database entity. You can choose between one or many databases.

In PostgreSQL there is only one database – its default name is ‘citus’ but can be changed at the time of configuration. In each DB account, they appear under a different name:

Azure Cosmos DB entityNoSQLApache CassandraMongoDBApache GremlinTablePostgreSQL
Azure Cosmos DB DatabaseDatabaseKeyspaceDatabaseDatabaseNADatabase

Note that Cosmos DB Table has no databases at all. In Table DB, data is saved in tables and is created and managed at account level to maintain compatibility.

Next are containers, they are entities inside a database. There can be one or more containers in each database entity. When a container is created, one needs to supply a partition key. The partition key is a property selected from one’s items to help Azure Cosmos DB distribute the data efficiently across partitions. In each DB account, the container entity appears under a different name: 

Azure Cosmos DB entityNoSQLApache CassandraMongoDBApache GremlinTablePostgreSQL
Azure Cosmos DB Container ContainerTableCollectionGraphTableTable

Next are items. In most Database Engines (except PostgreSQL and Cassandra), items within a container can have arbitrary schemas, meaning each item within the container can have its own set of fields or properties. A container can also have different entities, meaning items can represent different types of data with varying structures, if they share the same partition key. In each DB account, they appear under a different name:

Azure Cosmos DB entityNoSQLApache CassandraMongoDBApache GremlinTablePostgreSQL
Azure Cosmos DB ItemItemRowDocumentNode or edgeEntityItem

So far, we have learned of the hierarchical structure of a Cosmos DB account—account, databases, containers, and items.

Authentication Methods for Cosmos DB

Let us clarify the different ways to connect to your Cosmos DB account for each engine

Azure Cosmos DB Ways to AuthenticateNoSQLApache CassandraMongoDBApache GremlinTablePostgreSQL
Connection StringsVVVVVV
Azure Cosmos RBACV XVXXX
Resource TokenVXXXXX

We will deepen our knowledge of each way to connect your Cosmos DB account later in the article.

In this next section, we will focus on the Azure Cosmos RBAC. We will learn what it is, and the differences betweenAzure Cosmos RBAC and Azure RBAC .

Data & Management Operations in Cosmos DB

In Azure Cosmos DB, there are 2 types of operations:

  1. Management operations – Using Azure RBAC (Role Based Access Control).
  2. Data plane operations – UsingAzure Cosmos RBAC.

With Azure RBAC, you can control who can create, modify, or delete Azure Cosmos DB accounts, databases, containers, and manage settings like throughput levels.

WithAzure Cosmos RBAC, however, you can control access to read or modify the actual data stored within your containers.

Both operations use a permission model which grants different permissions to different users or identities. The permission model enables more security as it keeps the ‘least privilege’ principle, where the admin decides the amount of access each identity can have.

The following are the built-in roles for Azure RBAC (management operations):

Built-in roleDescription
DocumentDB Account ContributorCan manage Azure Cosmos DB accounts.
Cosmos DB Account ReaderCan read Azure Cosmos DB roles and role assignments, any collection, database account read only keys, metrics, resource groups.
CosmosBackupOperatorCan submit a restore request in the Azure portal for a periodic backup enabled database or a container.
Can modify the backup interval and retention in the Azure portal.
Cannot access any data or use Data Explorer.
CosmosRestoreOperatorCan perform a restore action for an Azure Cosmos DB account with continuous backup mode.
Cosmos DB OperatorCan provision Azure Cosmos DB accounts, databases, and containers. Cannot access any data or use Data Explorer.

In addition to the built-in roles, users are also able to create custom roles and apply these roles to service principals across all subscriptions within their AD tenant. The list of all possible actions for the custom roles for Azure RBAC is here.

As to data operations,Azure Cosmos RBACcurrently supports NoSQL and MongoDB only. Let us dive deep to get familiar with each database RBAC specifications.

MongoDB

In MongoDB, Azure Cosmos RBAC shares similarities with Azure RBAC, both relying on a permission model to control access to data operations by allowing or denying specific actions. However, MongoDB uses the term 'Privileges' for actions, and these privileges are grouped within 'Roles,' which represent sets of permissions.

These roles are defined within a single database inside a MongoDB account. Since MongoDB allows the creation of multiple databases, when defining a role, it is essential to specify the database to which the role pertains.

Moreover, MongoDB introduces the concept of users, representing identities identified by a username and password. Each user is associated with specific roles, dictating the set of actions they are permitted to perform within the defined database. This approach allows for precise control over access and operations in a MongoDB environment. Each user is associated with specific roles, defining the actions they are authorized to perform within the designated database.

MongoDB uses Capabilities as well. Capabilities are features that can be added or removed to your API for MongoDB account. Many of these features affect account behavior, so it's important to be fully aware of the effect a capability has before you enable or disable it. For more information click here.

The available privileges are:

  • Query and Write: find, insert, remove, update.
  • Change Streams: changeStream.
  • Database Management: ceateCollection, createIndex, dropCollection, killCursors, killAnyCursor.
  • Server Administration: dropDatabase, dropIndex, relndex.
  • Diagnostics: collStats, dbStats, listDatabases, listCollections, listIndexes.

The following are the built-in-roles for azure MongoDB RBAC:

Built-in rolePrivileges
readchangeStream, collStats, find, killCursors, listIndexes, listCollections.
readWriteHas the following privileges: collStats, find, killCursors, listIndexes, listCollections, ceateCollection, dropCollection, createIndex, dropIndex, insert, remove, update.
dbAdmincollStats, dbStats, listIndexes, listCollections, ceateCollection, dropCollection, dropDatabase, createIndex, dropIndex, relndex.
dbOwnercollStats, dbStats, listIndexes, listCollections, createCollection, dropCollection, dropDatabase, createIndex, dropIndex, relndex, find, insert. KillCursors, remove, update.  

Note: In MongoDB, the permission model for data operations can include some management operations (like createCollection, dropCollection, dropDatabase), as well as reading and writing data.

In addition to the built-in roles, users can also create custom roles and apply them.

One way to connect via Azure Cosmos RBAC for MongoDB using Pymongo:
(there are other ways such as Node.js, Java, Mongosh)

  • Add the capability “EnableMongoRoleBasedAccessControl” to the cosmos DB account. It enables support for creating users and roles for native MongoDB role-based access control.
  • Add a role definition to the account, if you desire to give the user that custom role.
  • Create a user and assign a role (built in or custom) and a database name.
  • Test the connection with ‘pymongo’.

NoSQL

In NoSQL, Azure Cosmos RBAC is like Azure RBAC as per the following criteria:

  1. They both use role definitions containing a list of allowed actions.
  2. In both the role definitions get assigned through role assignments – that define the scopes that the role definition applies to:
    • Azure Cosmos DB account (/)
    • Azure Cosmos DB database (/dbs/<database-name>)
    • Azure Cosmos DB container (/dbs/<database-name>/colls/<container-name>)

Note: The permission model for data operations in NoSQL covers only database operations that involve reading and writing data. It does not cover any kind of management operations on management resources, unlike MongoDB that allows some management operations.

In NoSQL there are 2 bulit-roles:

  • Cosmos DB Built-in Data Reader
  • Cosmos DB Built-in Data Contributer


In addition to the built-in roles, users can also create custom roles and apply them.
Below are all actions possible for Azure Cosmos RBAC:

Action nameCorresponding database operation(s)
Microsoft.DocumentDB/databaseAccounts/readMetadataRead account metadata. See Metadata requests for details.
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/createCreate a new item.
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/readRead an individual item by its ID and partition key (point-read).
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/replaceReplace an existing item.
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/upsert"Upsert" an item. This operation creates an item if it doesn't already exist, or to replace the item if it does exist.
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/deleteDelete an item.
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeQueryExecute a SQL query.
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/readChangeFeedRead from the container's change feed. Execute SQL queries using the SDKs.
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/executeStoredProcedureExecute a stored procedure.
Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/manageConflictsManage conflicts for multi-write region accounts (that is, list and delete items from the conflict feed).

Wildcards are supported at both containers and items levels:

  • Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/*
  • Microsoft.DocumentDB/databaseAccounts/sqlDatabases/containers/items/*

One way to connect via Azure Cosmos RBAC for NoSQL using Node.js:
(there are other ways such as .NET, Java, Spring Data, Python, Spark v3, Go)

  • On an empty folder, run npm init –y – and edit the package.json to include “type”: “module”
  • Install packages: @azure/cosmos, @azure/identity, dotenv
  • Authenticate clients: create custom role with actions above or assign a built-in role of Azure Cosmos RBACand get your azure user account or service principal’s id, then assign the role to your azure user account or service principal. Next, authenticate using DefaultAzureCredential imported from @azure/identity. Now you have a CosmosClient instance.
  • Test the connection by adding items to the container.

Accessing Azure Cosmos DB Account

Azure Cosmos DB offers three methods for managing access to your database account:

Access control typeCharacteristics
Connection Strings Allowing any management or data operation.
Role-based access controlAzure Cosmos RBAC(was detailed in the previous section)
Resource tokens Fine grained permission model based on native Azure Cosmos DB users and permissions.

Connection Strings:

In most data engines (except for PostgreSQL) in Cosmos DB, the connection strings are by primary/ secondary keys and an account endpoint. In PostgreSQL however, the connection string is by a username and password, with a secure connection (require ssl mode).

We will explain the concept of the primary and secondary keys that are used for all other data engines.

Primary / Secondary Keys:

Primary/secondary keys provide access to all the administrative resources for the database account. They provide access to accounts, databases, users, and permissions.
Every account is equipped with 4 keys: 2 primary keys and 2 secondary keys. The dual-key structure (primary-secondary key) enables key regeneration or rolling, which ensures continuous access to your account and its associated data.

There are 2 types of keys: read-only and read-write.

When it comes to the permissions for primary and secondary keys, they cannot be utilized to grant granular access, meaning they cannot provide access to specific users or groups at different levels, such as account-level (full access to all databases and containers), database-level, or container-level access.
Therefore, a user with a possession of a primary key can access the entire account.
In terms of access, one can access the Cosmos account by using a connection string that is a combination of the primary key and the account endpoint.

One security concern related to this access control type is the absence of permission scope. Granting access to a user through a connection string enables them to operate on the entire account's data, including all databases, containers, and items. Furthermore, as the primary and secondary keys are universal, any decision to revoke a user's account access requires rotating and regenerating the keys. This process involves distributing the new keys to all relevant users who still require access to the account.

If you still desire to use primary/secondary keys as access for all, consider disabling the ‘Read-write keys’, which will prevent connections using these keys. In such cases, the only option to connect will be with the ‘Read-only keys’. To disable the ‘Read-write keys’ you need to set the `disableKeyBasedMetadataWriteAccess` property to true. After you set this property, changes to any resource can happen from a user with the proper Azure role and credentials.

Role-Based Access Control:

As previously mentioned, Role-based access control is available via NoSQL and MongoDB only.

Written above is the description of Azure Cosmos RBAC in NoSQL and mongo DB and the differences between them. Managing the access to the account via Azure Cosmos RBAC consists of:

  • Authenticating data requests with Azure AD identity.
  • Authorizing data requests with a role-based permission model.

In terms of security, Azure Cosmos RBAC offers robust security advantages by enabling precise control over access to resources. With RBAC, you can assign specific roles and permissions tailored to user responsibilities, ensuring that each user or application has only the necessary access privileges. This adheres to the principle of least privilege, mitigating the risk of unauthorized data access or modifications. By segregating duties through role assignments, conflicts of interest and insider threats are minimized. To enhance security when choosing to access via Azure Cosmos RBAC, consider disabling local authentication, which disables the use of accessing via a connection string.

Resource Tokens:

Azure Cosmos DB resource tokens are available via NoSQL only.
They are dynamically generated security credentials that grant fine-grained and temporary access to specific resources within the database. These tokens enhance security by allowing controlled access without exposing primary or secondary keys, and they are suitable for scenarios where you need to provide specific privileges to users or applications for a limited time or for a restricted scope of containers, databases, or operations.

Resource tokens must be generated by an intermediate server. The server serves as the master-key guardian and generates time-constrained tokens for untrusted clients, such as web browsers.

This server performs the following steps:

  • Handles incoming client requests for new tokens.
  • Verifies client identity in an application-specific way.
  • If the client authenticates successfully, it uses the Cosmos DB interfaces (SDK or REST) to generate a new time-limited token and returns it to the client.

In terms of security, Azure Cosmos DB resource tokens serve as a crucial method for retrieving data tailored to individual users. This approach aligns with the principle of granting the least amount of privilege necessary, which boosts security by avoiding extensive administrative powers, as seen with the primary key. Instead, it emphasizes limited, temporary access and considers the aspect of not being able to reauthenticate.

As to the difference between Resource Tokens and Azure Cosmos RBAC, it is important to note that while the RBAC approach regenerates access tokens as long as the role assignment remains valid for the resource, the utilization of resource tokens will not trigger automatic regeneration.

To enhance security when choosing to access via resource tokens, consider disabling local authentication, which disables the use of accessing via a connection string.

Network Access

In this part of the article, we will discuss the different network access options provided by Azure Cosmos DB:

  • All networks
  • Selected networks
  • Disabled

All networks:

All networks, including the internet, can access this Azure Cosmos DB account.

By default, Azure Cosmos DB account is accessible from the internet, if the request is accompanied by a valid authorization token. This option raises a security concern, as it allows access to the account for all.

Selected Networks:

Limiting public access can be achieved through several methods: configuring IP firewall rules and/or establishing a virtual network. The optimal recommendation is to employ both approaches. By using both, access can be restricted to sources with public IPs and/or from specific subnets within the VNET.

By configuring firewalls, your Azure Cosmos DB account can be set up to be accessible solely from an authorized array of machines and/or cloud services.

When incorporating one or more subnets within VNets, only requests originating from those designated subnets will receive valid responses.

Requests emanating from any other sources will result in a 403 (Forbidden) response.

Disabled:

No public traffic will be able to access this resource. To access Azure Cosmos DB account, one needs to create a private endpoint.

Requests emanating from all sources will result in a 403 (Forbidden) response.

Note: When looking at the properties that describe the Cosmos DB Account, one can observe there is not a specific property indicating “All networks” or “Selected network”. The property is “public_network_access” with 2 options available: ‘Enabled’ / ‘Disabled’.

As one can infer, ‘Enabled’ does not differ which is ‘All network’ and which is ‘Selected network’. The way to determine based on the JSON describing the account is by looking at other components, as shown in the diagram below:

network access options provided by Azure Cosmos DB

As we can see, to determine based on the properties which network option is used at the account, we must look at ‘public_network_access’ property:

  • If ‘Disabled’ - we are at ‘Disabled’ option, which means no public access whatsoever. The way to connect to the account is by using a private endpoint.
  • If ‘Enabled’- we need to check the ‘is_virtual_filter_network_enabled’ property:
    • If ‘True’- we are at ‘Selected Networks’, which means the public network access is limited.
    • If ‘False’- we need to check the ‘ipRules’ property:
      • If ‘Empty’ - we are at ‘All networks’ which means full public access.
      • Else, we are at ‘Selected Networks’, which means the public network access is limited.

Conclusion

In this post, we have become more familiar with Cosmos DB permissions and network access variations. Today, it is quite common to use default properties when they are not necessary for your specific requirements. While sometimes the default is a secure option, from time to time, the default is not necessarily the more secure one. It is important to know whom to provide the connection string based on primary keys, as they grant full administrative actions and remain accessible until rotation or regeneration. Meanwhile, there are more secure options, such as using Azure Cosmos RBAC or granting resource tokens, depending on your preference. When working with NoSQL databases, consider employing resource tokens if you need to grant access for a limited duration or to a temporary user. Alternatively, for permanent user access, you may opt for Azure Cosmos RBAC.

Regarding network access, try to avoid providing full public access. Depending on your requirements, choose between limiting access or disabling it.

By providing this knowledge, our hope is to assist you in keeping your product as secure as possible.

References

Cosmos DB:

https://learn.microsoft.com/en-us/azure/cosmos-db/role-based-access-control

https://learn.microsoft.com/en-us/azure/cosmos-db/resource-model

Mongo RBAC:

https://learn.microsoft.com/en-us/azure/cosmos-db/mongodb/how-to-setup-rbac

https://learn.microsoft.com/en-us/azure/cosmos-db/mongodb/how-to-configure-capabilities#available-capabilities

https://github.com/Azure/azure-sdk-for-net/blob/Azure.Data.Tables_12.8.1/sdk/tables/Azure.Data.Tables/samples/Sample0Auth.md

NoSql RBAC

https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac

https://learn.microsoft.com/en-us/azure/cosmos-db/secure-access-to-data?tabs=using-primary-key

https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/quickstart-python?tabs=azure-portal%2Cpasswordless%2Cwindows%2Csign-in-azure-cli%2Csync

https://learn.microsoft.com/en-us/azure/cosmos-db/audit-control-plane-logs