Skip to content

Commit 2c3be08

Browse files
authored
DRIVERS-2416 Add Azure built-in integration for OIDC. (#1513)
1 parent 156b0ca commit 2c3be08

File tree

2 files changed

+100
-3
lines changed

2 files changed

+100
-3
lines changed

source/auth/auth.md

Lines changed: 72 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1214,10 +1214,15 @@ in the MONGODB-OIDC specification, including sections or blocks that specificall
12141214

12151215
- ENVIRONMENT\
12161216
Drivers MUST allow the user to specify the name of a built-in OIDC application environment integration
1217-
to use to obtain credentials. If provided, the value MUST be one of `["test"]`. If both `ENVIRONMENT` and an
1218-
[OIDC Callback](#oidc-callback) or [OIDC Human Callback](#oidc-human-callback) are provided for the same
1217+
to use to obtain credentials. If provided, the value MUST be one of `["test", "azure"]`. If both `ENVIRONMENT` and
1218+
an [OIDC Callback](#oidc-callback) or [OIDC Human Callback](#oidc-human-callback) are provided for the same
12191219
`MongoClient`, the driver MUST raise an error.
12201220

1221+
- TOKEN_RESOURCE\
1222+
The URI of the target resource. This property is currently only used and required by the Azure
1223+
built-in OIDC provider integration. If `TOKEN_RESOURCE` is provided and `PROVIDER_NAME` is not `azure` or
1224+
`TOKEN_RESOURCE` is not provided and `PROVIDER_NAME` is `azure`, the driver MUST raise an error.
1225+
12211226
- OIDC_CALLBACK\
12221227
An [OIDC Callback](#oidc-callback) that returns OIDC credentials. Drivers MAY allow the user to
12231228
specify an [OIDC Callback](#oidc-callback) using a `MongoClient` configuration instead of a mechanism property,
@@ -1263,6 +1268,64 @@ MUST use the contents of that file as value in the `jwt` field of the `saslStart
12631268
Drivers MAY implement the "test" integration so that it conforms to the function signature of the
12641269
[OIDC Callback](#oidc-callback) to prevent having to re-implement the "test" integration logic in the OIDC prose tests.
12651270

1271+
**Azure**
1272+
1273+
The Azure provider integration is enabled by setting auth mechanism property `ENVIRONMENT:azure`.
1274+
1275+
If enabled, drivers MUST use an internal machine callback that calls the
1276+
[Azure Instance Metadata Service](https://learn.microsoft.com/en-us/azure/virtual-machines/instance-metadata-service)
1277+
and parse the JSON response body, as follows:
1278+
1279+
Make an HTTP GET request to
1280+
1281+
```
1282+
http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=<resource>&client_id=<client_id>
1283+
```
1284+
1285+
with headers
1286+
1287+
```
1288+
Accept: application/json
1289+
Metadata: true
1290+
```
1291+
1292+
where `<resource>` is the value of the `TOKEN_RESOURCE` mechanism property and `<client_id>` is the `username` from the
1293+
connection string. If a `username` is not provided, the `client_id` query parameter should be omitted. The timeout
1294+
should equal the `callbackTimeoutMS` parameter given to the callback.
1295+
1296+
Example code for the above using curl, where `$TOKEN_RESOURCE` is the value of the `TOKEN_RESOURCE` mechanism property.
1297+
1298+
```bash
1299+
curl -X GET \
1300+
-H "Accept: application/json" \
1301+
-H "Metadata: true" \
1302+
--max-time $CALLBACK_TIMEOUT_MS \
1303+
"http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$TOKEN_RESOURCE"
1304+
```
1305+
1306+
The JSON response will be in this format:
1307+
1308+
```json
1309+
{
1310+
"access_token": "eyJ0eXAi...",
1311+
"refresh_token": "",
1312+
"expires_in": "3599",
1313+
"expires_on": "1506484173",
1314+
"not_before": "1506480273",
1315+
"resource": "https://management.azure.com/",
1316+
"token_type": "Bearer"
1317+
}
1318+
```
1319+
1320+
The driver MUST use the returned `"access_token"` value as the access token in a `JwtStepRequest`. If the response does
1321+
not return a status code of 200, the driver MUST raise an error including the HTTP response body.
1322+
1323+
For more details, see
1324+
[How to use managed identities for Azure resources on an Azure VM to acquire an access token](https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-use-vm-token).
1325+
1326+
The callback itself MUST not perform any caching, and the driver MUST cache its tokens in the same way as if a custom
1327+
callback had been provided by the user.
1328+
12661329
#### OIDC Callback
12671330

12681331
Drivers MUST allow users to provide a callback that returns an OIDC access token. The purpose of the callback is to
@@ -1280,6 +1343,8 @@ The driver MUST pass the following information to the callback:
12801343

12811344
- `timeout`: A timeout, in milliseconds, a deadline, or a `timeoutContext`.
12821345

1346+
- `username`: The username given as part of the connection string or `MongoClient` parameter.
1347+
12831348
- `version`: The callback API version number. The version number is used to communicate callback API changes that are
12841349
not breaking but that users may want to know about and review their implementation. Drivers MUST pass `1` for the
12851350
initial callback API version number and increment the version number anytime the API changes. Note that this may
@@ -1310,6 +1375,7 @@ An example callback API might look like:
13101375
```typescript
13111376
interface OIDCCallbackParams {
13121377
callbackTimeoutMS: int;
1378+
username: str;
13131379
version: int;
13141380
}
13151381

@@ -1357,6 +1423,7 @@ interface IdpInfo {
13571423
}
13581424

13591425
interface OIDCCallbackParams {
1426+
username: str;
13601427
callbackTimeoutMS: int;
13611428
version: int;
13621429
idpInfo: Optional<IdpInfo>;
@@ -1574,7 +1641,7 @@ def invalidate(access_token):
15741641
Drivers that support the [Human Authentication Flow](#human-authentication-flow) MUST also cache the `IdPInfo` and
15751642
refresh token in the *Client Cache* when a [OIDC Human Callback](#oidc-human-callback) is configured.
15761643

1577-
####### Authentication
1644+
**Authentication**
15781645

15791646
Use the following algorithm to authenticate a new connection:
15801647

@@ -1921,6 +1988,8 @@ to EC2 instance metadata in ECS, for security reasons, Amazon states it's best p
19211988

19221989
## Changelog
19231990

1991+
- 2024-03-21: Added Azure built-in OIDC provider integration.
1992+
19241993
- 2024-03-09: Rename OIDC integration name and values.
19251994

19261995
- 2024-01-31: Migrated from reStructuredText to Markdown.

source/auth/tests/mongodb-oidc.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,19 @@ OIDC_TOKEN_FILE="$OIDC_TOKEN_DIR/test_user1" /my/test/command
1919

2020
______________________________________________________________________
2121

22+
## Unified Spec Tests
23+
24+
Drivers MUST run the unified spec tests in all supported OIDC environments.
25+
26+
______________________________________________________________________
27+
2228
## Prose Tests
2329

2430
Drivers MUST implement all prose tests in this section. Unless otherwise noted, all `MongoClient` instances MUST be
2531
configured with `retryReads=false`.
2632

33+
Drivers MUST run the prose tests in all supported OIDC environments.
34+
2735
> [!NOTE]
2836
> For test cases that create fail points, drivers MUST either use a unique `appName` or explicitly remove the fail point
2937
> callback to prevent interaction between test cases.
@@ -119,13 +127,33 @@ method, use `mongodb://localhost/?authMechanism=MONGODB-OIDC` for `MONGODB_URI`.
119127
- Assert that the callback was called 2 times (once during the connection handshake, and again during reauthentication).
120128
- Close the client.
121129

130+
## (5) Azure Tests
131+
132+
Drivers MUST only run the Azure tests when testing on an Azure VM. See instructions in
133+
[Drivers Evergreen Tools](https://github.com/mongodb-labs/drivers-evergreen-tools/tree/master/.evergreen/auth_oidc/azure#azure-oidc-testing)
134+
for test setup.
135+
136+
# 5.1 Azure With No Username
137+
138+
- Create a `MongoClient` configured with `ENVIRONMENT:Azure` and a valid `TOKEN_RESOURCE` and no username.
139+
- Perform a `find` operation that succeeds.
140+
- Close the client.
141+
142+
# 5.2 Azure with Bad Usernam
143+
144+
- Create a `MongoClient` configured with `ENVIRONMENT:Azure` and a valid `TOKEN_RESOURCE` and a username of `"bad"`.
145+
- Perform a `find` operation that fails.
146+
- Close the client.
147+
122148
______________________________________________________________________
123149

124150
## Human Authentication Flow Prose Tests
125151

126152
Drivers that support the [Human Authentication Flow](../auth.md#human-authentication-flow) MUST implement all prose
127153
tests in this section. Unless otherwise noted, all `MongoClient` instances MUST be configured with `retryReads=false`.
128154

155+
The human workflow tests MUST only be run when testing in the default environment described beflow.
156+
129157
> [!NOTE]
130158
> For test cases that create fail points, drivers MUST either use a unique `appName` or explicitly remove the fail point
131159
> after the test to prevent interaction between test cases.

0 commit comments

Comments
 (0)