Skip to content

Commit a83196e

Browse files
authored
BREAKING CHANGE: Add Support for RBAC using Entra ID Token via New-CosmosDbContext - Fixes #479 (#483)
1 parent 740b9ec commit a83196e

28 files changed

Lines changed: 2457 additions & 574 deletions

CHANGELOG.md

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,35 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Removed MacOS-10.15 testing from build pipeline because it is no longer supported by Microsoft
1818
managed Azure DevOps images - Fixes [Issue #476](https://github.com/PlagueHO/CosmosDB/issues/476).
1919
- Added macOS-12 testing to build pipeline - Fixes [Issue #477](https://github.com/PlagueHO/CosmosDB/issues/477).
20+
- Changed integration tests to deploy Cosmos DB using Bicep.
21+
- Update `requirements.psd1` to install modules `Az.Accounts` 2.19.0 and `Az.Resources` 6.16.2.
22+
- Renamed `New-CosmosDbAuthorizationToken` to `New-CosmosDbAuthorizationHeader` to better indicate
23+
actual function return type.
24+
- Refactored `Invoke-CosmosDbRequest` to support getting the EntraIdToken property from the context object
25+
and using it for authentication if it is provided. If the Key property is provided, the EntraIdToken property
26+
will take precendence and the key will be ignored.
27+
- Updated CI pipeline to use `PublishCodeCoverageResults@2` task rather than `PublishCodeCoverageResults@1`
28+
task to support the latest version of the task.
29+
30+
### Changed
31+
32+
- BREAKING CHANGE: Updated module to require `Az.Accounts` v2.19.0 or newer and `Az.Resources`
33+
v6.16.2 or newer.
34+
- Renamed `New-CosmosDbAuthorizationHeader` to `Get-CosmosDbAuthorizationHeaderFromContext` to better indicate
35+
actual function behaviour.
36+
- Renamed `Get-CosmosDbAuthorizationHeadersFromContext` to `Get-CosmosDbAuthorizationHeaderFromContextResourceToken` to better
37+
indicate actual function behaviour and align naming convention.
38+
- Refactored `Invoke-CosmosDbRequest` to clean up logic to generate the authorization header.
39+
- Added new utillity function `Get-CosmosDbAuthorizationHeaderFromContextEntraId` to generate the authorization
40+
header when an Entra ID Token is provided in the context. This function is used by `Invoke-CosmosDbRequest` to
41+
generate the authorization header when an Entra ID Token is provided.
42+
43+
### Added
44+
45+
- Added support for setting an Entra Id OAuth2 Token in the `New-CosmosDbContext` - Fixes [Issue #479](https://github.com/PlagueHO/CosmosDB/issues/479).
46+
- Added new `Get-CosmosDbEntraIdToken` function that uses `Get-AzAccessToken` to get an Entra Id Token
47+
for use in Cosmos DB requests. This is used by `New-CosmosDbContext` to set the Entra Id Token in the
48+
context object - Fixes [Issue #479](https://github.com/PlagueHO/CosmosDB/issues/479).
2049

2150
## [4.7.0] - 2023-01-29
2251

@@ -666,7 +695,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
666695

667696
## [2.0.8.350] - 2018-04-05
668697

669-
- Fixed `New-CosmosDbAuthorizationToken` function to support
698+
- Fixed `New-CosmosDbAuthorizationHeader` function to support
670699
generating authorization tokens for case sensitive resource
671700
names - See [Issue #76](https://github.com/PlagueHO/CosmosDB/issues/76).
672701
Thanks [MWL88](https://github.com/MWL88).
@@ -775,7 +804,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
775804

776805
- Fixed bug in `New-CosmosDbConnection` connecting to Azure and
777806
improved tests.
778-
- Changed `New-CosmosDbAuthorizationToken` to replaced `Connection`
807+
- Changed `New-CosmosDbAuthorizationHeader` to replaced `Connection`
779808
parameter with `Key` and `KeyType` parameter.
780809
- Fixed bug in `Invoke-CosmosDbRequest` that can cause connection
781810
object to be changed.

README.md

Lines changed: 139 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,16 @@
2222
- [Installation](#installation)
2323
- [Getting Started](#getting-started)
2424
- [Working with Contexts](#working-with-contexts)
25+
- [Create a Context using an Entra ID Authorization Token](create-a-context-using-an-entra-id-authorization-token)
26+
- [Configuring Role-Based Access Control (RBAC) with Entra ID](#configuring-role-based-access-control-rbac-with-entra-id)
27+
- [Database Operations allowed by Role-Based Access Control](#database-operations-allowed-by-role-based-access-control)
2528
- [Create a Context specifying the Key Manually](#create-a-context-specifying-the-key-manually)
29+
- [Use CosmosDB Module to Retrieve Key from Azure Management Portal](#use-cosmosdb-module-to-retrieve-key-from-azure-management-portal)
30+
- [Create a Context from Resource Authorization Tokens](#create-a-context-from-resource-authorization-tokens)
2631
- [Create a Context for a Cosmos DB in Azure US Government Cloud](#create-a-context-for-a-cosmos-db-in-azure-us-government-cloud)
2732
- [Create a Context for a Cosmos DB in Azure China Cloud (Mooncake)](#create-a-context-for-a-cosmos-db-in-azure-china-cloud-mooncake)
2833
- [Create a Context for a Cosmos DB with a Custom Endpoint](#create-a-context-for-a-cosmos-db-with-a-custom-endpoint)
29-
- [Use CosmosDB Module to Retrieve Key from Azure Management Portal](#use-cosmosdb-module-to-retrieve-key-from-azure-management-portal)
3034
- [Create a Context for a Cosmos DB Emulator](#create-a-context-for-a-cosmos-db-emulator)
31-
- [Create a Context from Resource Authorization Tokens](#create-a-context-from-resource-authorization-tokens)
3235
- [Working with Accounts](#working-with-accounts)
3336
- [Working with Databases](#working-with-databases)
3437
- [Working with Offers](#working-with-offers)
@@ -81,16 +84,15 @@ For more information on the Cosmos DB Rest APIs, see [this link](https://docs.mi
8184

8285
This module requires the following:
8386

84-
- Windows PowerShell 5.x or PowerShell 6.x:
85-
- **Az.Profile** and **Az.Resources** PowerShell modules
86-
are required if using `New-CosmosDbContext -ResourceGroupName $resourceGroup`
87-
or `*-CosmosDbAccount` functions.
87+
- Windows PowerShell 5.x, PowerShell Core 6.x or PowerShell 7.x
88+
89+
### PowerShell Module Dependencies
8890

89-
> Note: As of 3.0.0.0 of the CosmosDB module, support for **AzureRm** and
90-
> **AzureRm.NetCore** PowerShell modules has been deprecated due to being
91-
> superceeded by the **Az** modules. If it is a requirement that **AzureRm**
92-
> or **AzureRm.NetCore** modules are used then you will need to remain on
93-
> CosmosDB module 2.x.
91+
- **Az.Account**: v2.19.0 or newer.
92+
- **Az.Resources**: 6.16.2 or newer.
93+
94+
These modules are required if using `New-CosmosDbContext -ResourceGroupName $resourceGroup`
95+
or `*-CosmosDbAccount` functions.
9496

9597
## Recommended Knowledge
9698

@@ -129,8 +131,95 @@ the Azure management portal for you.
129131

130132
### Working with Contexts
131133

134+
#### Create a Context Using an Entra ID Authorization Token
135+
136+
You can create a context object that can include use an _Entra ID Authorization Token_
137+
that will be used to authenticate requests to Cosmos DB.
138+
139+
> Important: This is a recommended security practice to use when you've
140+
> [configured role-based access control with Microsoft Entra ID](https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac)
141+
> on your Azure Cosmos DB account. It will help you keep your account secure
142+
> by not exposing the primary or secondary keys in your code.
143+
144+
To create a context object using an _Entra ID Authorization Token_ you will need
145+
to set the `EntraIdToken` parameter to the token you have retrieved from Entra ID
146+
for the identity that you have given appropriate permissions to the `account`,
147+
`database` and/or `collection`. See [this page](https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac#concepts) for more infomration.
148+
149+
```powershell
150+
# Get an OAuth2 resource token from Entra ID for the Cosmos DB account.
151+
# This will use the currently logged in user to authenticate to Entra ID to
152+
# get the token. There are many other ways of doing this.
153+
$entraIdOAuthToken = Get-CosmosDbEntraIdToken -Endpoint 'https://MyAzureCosmosDB.documents.azure.com'
154+
155+
$newCosmosDbContextParams = @{
156+
Account = 'MyAzureCosmosDB'
157+
EntraIdToken = $entraIdOAuthToken
158+
}
159+
$accountContext = New-CosmosDbContext @newCosmosDbContextParams
160+
Get-CosmosDbCollection -Context $accountContext -Id MyNewCollection
161+
```
162+
163+
An alternate method is to allow the New-CosmosDbContext cmdlet to retrieve the
164+
Entra ID token for you. This will require you to have already logged into Azure
165+
and will use the base URI detected for the account as the resource URI for the
166+
token request.
167+
168+
```powershell
169+
$newCosmosDbContextParams = @{
170+
Account = 'MyAzureCosmosDB'
171+
AutoGenerateEntraIdToken = $true
172+
}
173+
$accountContext = New-CosmosDbContext @newCosmosDbContextParams
174+
Get-CosmosDbCollection -Context $accountContext -Id MyNewCollection
175+
```
176+
177+
> Important: Using an Entra ID Authorization Token is only supported by setting it
178+
> in a CosmosDB.Context object and passing that to the commands you want to execute.
179+
> Not all commands support this method of authentication. If you need to use a command
180+
> that doesn't support this method of authentication, you will need to use one of the
181+
> other methods of authentication. See the [Database Operations allowed by Role-Based Access Control](#database-operations-allowed-by-role-based-access-control)
182+
> section for more information.
183+
184+
##### Configuring Role-Based Access Control (RBAC) with Entra ID
185+
186+
There are several ways to configure a Cosmos DB Account with Role-Based Access Control,
187+
including:
188+
189+
- *Azure Bicep*: An example can be found in the [\tests\TestHelper\AzureDeploy\CosmosDb.bicep](\tests\TestHelper\AzureDeploy\CosmosDb.bicep) file.
190+
- *Azure PowerShell*: The integration tests use this method.
191+
- *AzCli*.
192+
193+
> Important Note: One thing I found when adding a SQL Role Assignment to the Cosmos DB
194+
> Account (or Database or Container) is that the principal ID must be the Object ID of
195+
> the user, group or service principal that you want to assign the role to. You can't use
196+
> the Application ID for this value.
197+
198+
For more information on how to configure Role-Based Access Control with Entra ID, see the
199+
[Configure role-based access control with Microsoft Entra ID for your Azure Cosmos DB account](https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac)
200+
page.
201+
202+
##### Database Operations allowed by Role-Based Access Control
203+
204+
Only a subset of all the operations that can be performed on a Cosmos DB account are
205+
allowed by Role-Based Access Control. The following operations are allowed:
206+
This permission model covers only database operations that involve reading and writing data. It does not cover any kind of management operations on management resources, including:
207+
208+
- Create/Replace/Delete Database
209+
- Create/Replace/Delete Container
210+
- Read/Replace Container Throughput
211+
- Create/Replace/Delete/Read Stored Procedures
212+
- Create/Replace/Delete/Read Triggers
213+
- Create/Replace/Delete/Read User Defined Functions
214+
215+
For more information on this, please see the [Role-based access control (RBAC) with Azure Cosmos DB](https://learn.microsoft.com/en-us/azure/cosmos-db/how-to-setup-rbac#permission-model) page.
216+
132217
#### Create a Context specifying the Key Manually
133218

219+
> Note: This method of authenticating to Cosmos DB is not recommended for
220+
> production use. It is recommended to use the _Entra ID Authorization Token_
221+
> method described above.
222+
134223
First convert your key into a secure string:
135224

136225
```powershell
@@ -144,8 +233,43 @@ create a context variable:
144233
$cosmosDbContext = New-CosmosDbContext -Account MyAzureCosmosDB -Database MyDatabase -Key $primaryKey
145234
```
146235

236+
#### Use CosmosDB Module to Retrieve Key from Azure Management Portal
237+
238+
> Note: This method of authenticating to Cosmos DB is not recommended for
239+
> production use. It is recommended to use the _Entra ID Authorization Token_
240+
> method described above.
241+
242+
To create a context object so that the _CosmosDB PowerShell module_
243+
retrieves the primary or secondary key from the Azure Management
244+
Portal, use the following command:
245+
246+
```powershell
247+
$cosmosDbContext = New-CosmosDbContext -Account MyAzureCosmosDB -Database MyDatabase -ResourceGroupName MyCosmosDbResourceGroup -MasterKeyType SecondaryMasterKey
248+
```
249+
250+
_Note: if PowerShell is not connected to Azure then an interactive
251+
Azure login will be initiated. If PowerShell is already connected to
252+
an account that doesn't contain the Cosmos DB you wish to connect to then
253+
you will first need to connect to the correct account using the
254+
`Connect-AzAccount` cmdlet._
255+
256+
#### Create a Context from Resource Authorization Tokens
257+
258+
> Note: This method of authenticating to Cosmos DB is better than using master key
259+
> authentication, as it provides the ability to limit access to specific resources.
260+
> However, it is recommended to use the _Entra ID Authorization Token_ method
261+
> described above if possible.
262+
263+
See the section [Using Resource Authorization Tokens](#using-resource-authorization-tokens)
264+
for instructions on how to create a Context object containing one or more _Resource
265+
Authorization Tokens_.
266+
147267
#### Create a Context for a Cosmos DB in Azure US Government Cloud
148268

269+
> Note: This method of authenticating to Cosmos DB is not recommended for
270+
> production use. It is recommended to use the _Entra ID Authorization Token_
271+
> method described above.
272+
149273
Use the key secure string, Azure Cosmos DB account name and database to
150274
create a context variable and set the `Environment` parameter to
151275
`AzureUSGovernment`:
@@ -156,6 +280,10 @@ $cosmosDbContext = New-CosmosDbContext -Account MyAzureCosmosDB -Database MyData
156280

157281
#### Create a Context for a Cosmos DB in Azure China Cloud (Mooncake)
158282

283+
> Note: This method of authenticating to Cosmos DB is not recommended for
284+
> production use. It is recommended to use the _Entra ID Authorization Token_
285+
> method described above.
286+
159287
Use the key secure string, Azure Cosmos DB account name and database to
160288
create a context variable and set the `Environment` parameter to
161289
`AzureChinaCloud`:
@@ -173,22 +301,6 @@ Cosmos DB custom endpoint hostname:
173301
$cosmosDbContext = New-CosmosDbContext -Account MyAzureCosmosDB -Database MyDatabase -Key $primaryKey -EndpointHostname documents.eassov.com
174302
```
175303

176-
#### Use CosmosDB Module to Retrieve Key from Azure Management Portal
177-
178-
To create a context object so that the _CosmosDB PowerShell module_
179-
retrieves the primary or secondary key from the Azure Management
180-
Portal, use the following command:
181-
182-
```powershell
183-
$cosmosDbContext = New-CosmosDbContext -Account MyAzureCosmosDB -Database MyDatabase -ResourceGroupName MyCosmosDbResourceGroup -MasterKeyType SecondaryMasterKey
184-
```
185-
186-
_Note: if PowerShell is not connected to Azure then an interactive
187-
Azure login will be initiated. If PowerShell is already connected to
188-
an account that doesn't contain the Cosmos DB you wish to connect to then
189-
you will first need to connect to the correct account using the
190-
`Connect-AzAccount` cmdlet._
191-
192304
#### Create a Context for a Cosmos DB Emulator
193305

194306
Microsoft provides a [Cosmos DB emulator](https://docs.microsoft.com/azure/cosmos-db/local-emulator) that
@@ -208,12 +320,6 @@ $primaryKey = ConvertTo-SecureString -String 'GFJqJesi2Rq910E0G7P4WoZkzowzbj23Sm
208320
$cosmosDbContext = New-CosmosDbContext -Emulator -Database MyDatabase -Uri https://cosmosdbemulator.contoso.com:9081 -Key $primaryKey
209321
```
210322

211-
#### Create a Context from Resource Authorization Tokens
212-
213-
See the section [Using Resource Authorization Tokens](#using-resource-authorization-tokens)
214-
for instructions on how to create a Context object containing one or more _Resource
215-
Authorization Tokens_.
216-
217323
### Working with Accounts
218324

219325
You can create, retrieve, update and remove Azure Cosmos DB accounts using

RequiredModules.psd1

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
Sampler = 'latest'
1818
'Sampler.GitHubTasks' = 'latest'
1919
MarkdownLinkCheck = 'latest'
20-
'Az.Accounts' = '2.2.8'
21-
'Az.Resources' = '1.3.1'
20+
'Az.Accounts' = '2.19.0'
21+
'Az.Resources' = '6.16.2'
22+
'Az.CosmosDB' = '1.14.2' # Required by integration tests
2223
}

0 commit comments

Comments
 (0)