Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions site/developer/_sidebar.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ website:
- text: "Quickstart"
- notebooks/quickstart/quickstart_documentation.ipynb
- notebooks/quickstart/quickstart_validation.ipynb
- text: "Quickstart (OIDC device flow)"
file: notebooks/quickstart/quickstart_model_documentation_oidc_device_flow.ipynb
# USING THE VARIABLE IN THE LINK TEXT MESSES UP THE MOBILE VIEW & BREADCRUMB
- section: "Install and initialize ValidMind"
contents:
- text: "Install and initialize the library"
file: developer/quickstart/install-and-initialize-validmind-library.qmd
- text: "Authenticate with OIDC device flow"
file: developer/quickstart/authenticate-with-oidc-device-flow.qmd
- text: "Install and initialize the library for R"
file: developer/quickstart/install-and-initialize-validmind-for-r.qmd
- text: "Use an HTTP proxy with the library"
Expand Down
153 changes: 153 additions & 0 deletions site/developer/quickstart/authenticate-with-oidc-device-flow.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
---
# Copyright © 2023-2026 ValidMind Inc. All rights reserved.
# Refer to the LICENSE file in the root of this repository for details.
# SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial
title: "Authenticate with OIDC device flow"
date: last-modified
listing:
- id: whats-next
type: grid
max-description-length: 250
sort: false
fields: [title, description]
grid-columns: 2
contents:
- store-credentials-in-env-file.qmd
- ../../notebooks/quickstart/quickstart_model_documentation_oidc_device_flow.ipynb
---

Authenticate the {{< var validmind.developer >}} with your organization's identity provider using the OAuth 2.0 / OIDC **device authorization flow** ([RFC 8628](https://datatracker.ietf.org/doc/html/rfc8628)), instead of long-lived API keys.

When OIDC is enabled for your organization, `vm.init()` opens a browser sign-in flow (verification URL and user code), then uses a bearer access token for ValidMind API calls. Cached tokens are reused and refreshed when possible.

::: {.attn}

## Prerequisites

- [x] {{< var link.login >}}
- [x] Your organization has OIDC library connectivity enabled.[^1]
- [x] You have {{< var validmind.developer >}} version **2.13** or later.[^2]
- [x] The record you want to connect to is registered in the inventory.[^3]
- [x] The document you want to connect to has a template applied.[^4]

:::

## When should I use OIDC?

Use the device flow when your organization prefers interactive IdP sign-in over API keys — for example, notebook or local CLI work under SSO policies.

::: {.callout-note}
## API keys and OIDC are mutually exclusive

Pass **either** `api_key` and `api_secret` **or** `issuer` and `client_id` (via arguments or environment variables). Mixing both raises an authentication error.

:::

::: {.callout}
## Current scope

- Supported for the **Python** {{< var validmind.developer >}} via `vm.init()`.
- Device authorization flow only. Redirect-based OAuth and client-credentials (machine-to-machine) grants are not supported by the library.
- Availability depends on your organization's library connectivity settings. If Getting Started only shows an API key snippet, use [Install and initialize the {{< var validmind.developer >}}](install-and-initialize-validmind-library.qmd).
- The **Public REST API** can also accept OIDC bearer tokens when enabled for your organization. See [Public REST API authentication](/reference/validmind-rest-api-vm.qmd#authentication).

:::

## Authenticate with OIDC

### 1. Get your OIDC code snippet

When your organization allows device-flow connectivity, the {{< var validmind.platform >}} can show an OIDC snippet on the record **Getting Started** page:

1. In the left sidebar, click **{{< fa cubes >}} Inventory**.

2. Select a record by clicking on it or find your record by applying a filter or searching for it.[^5]

3. In the left sidebar that appears for your record, click **{{< fa rocket >}} Getting Started**.

4. Select the **Document** you want to automatically upload test results to.[^6]

5. Under the OIDC connectivity section, click **{{< fa regular copy >}} Copy snippet to clipboard**.

::: {.callout}
If you see a message asking you to contact an administrator to set OIDC connectivity, your organization allows OIDC but the device-flow client settings are not configured yet. Ask your ValidMind administrator to complete that setup.

:::

### 2. Initialize the {{< var validmind.developer >}}

Paste the snippet into your notebook or script. A typical OIDC `vm.init()` looks like this:

```python
import validmind as vm

vm.init(
api_host="{{< var api.host >}}/tracking",
issuer="https://login.microsoftonline.com/<tenant-id>/v2.0",
client_id="<oauth-public-client-id>",
audience="<api-audience-or-resource>", # often required
document="document-key", # requires library >=2.12.0
model="MODEL_IDENTIFIER",
)
```

| Argument | Environment variable | Description |
|----------|----------------------|-------------|
| `issuer` | `VM_OIDC_ISSUER` | OpenID Provider issuer URL used for discovery |
| `client_id` | `VM_OIDC_CLIENT_ID` | Public OAuth client ID registered for device flow |
| `audience` | `VM_OIDC_AUDIENCE` | API audience / resource identifier (often required so tokens are accepted by ValidMind) |
| `scope` | `VM_OIDC_SCOPE` | Optional. Defaults to `openid profile email offline_access` |
| `api_host` | `VM_API_HOST` | Location of the {{< var vm.product >}} tracking API |
| `model` | `VM_API_MODEL` | Record identifier |
| `document` | — | Document to receive uploaded test results |

When you run the cell, the library may print a **verification URL** and **user code**. Open the URL, enter the code, and complete sign-in with your identity provider. The notebook or script waits until authorization finishes.

::: {.callout}
To also enable monitoring, add `monitoring=True` to `vm.init()`.[^7]
:::

### 3. (Optional) Store OIDC settings in an `.env` file

You can keep OIDC settings out of source code the same way you store API credentials:[^8]

```bash
VM_API_HOST=https://api.prod.validmind.ai/api/v1/tracking
VM_OIDC_ISSUER=https://login.microsoftonline.com/<tenant-id>/v2.0
VM_OIDC_CLIENT_ID=<oauth-public-client-id>
VM_OIDC_AUDIENCE=<api-audience-or-resource>
VM_API_MODEL=<model>
```

Then call `vm.init()` with only the values that should stay in the notebook, such as `document=` or `monitoring=True`.

## What happens after you sign in?

1. The library discovers your IdP from `{issuer}/.well-known/openid-configuration`.
2. It starts the device authorization flow and waits for you to complete browser sign-in.
3. Access (and refresh, when issued) tokens are cached under `~/.validmind/credentials.json`.
4. Later `vm.init()` calls reuse or refresh cached tokens when possible.
5. API requests use `Authorization: Bearer <access_token>` instead of API key headers.

Treat the credentials file like other secrets on shared machines.

## Try it in a notebook

For a full documentation walkthrough that uses OIDC instead of API keys, see [Quickstart for model documentation (OIDC device flow)](/notebooks/quickstart/quickstart_model_documentation_oidc_device_flow.ipynb).

## What's next

:::{#whats-next}
:::


<!-- FOOTNOTES -->

[^1]: Your ValidMind administrator configures library connectivity and the OIDC device-flow client for your organization.
[^2]: [Upgrade the {{< var validmind.developer >}}](install-and-initialize-validmind-library.qmd#upgrade-validmind)
[^3]: [Register records in the inventory](/guide/inventory/register-records-in-inventory.qmd)
[^4]: [Working with templates](/guide/templates/working-with-document-templates.qmd)
[^5]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records)
[^6]: [Managing documents](/guide/templates/managing-documents.qmd)
[^7]: [Enable monitoring](/guide/monitoring/enable-monitoring.qmd)
[^8]: [Store record credentials in `.env` files](store-credentials-in-env-file.qmd)
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,9 @@ listing:
max-description-length: 250
sort: false
fields: [title, description]
grid-columns: 2
grid-columns: 3
contents:
- authenticate-with-oidc-device-flow.qmd
- store-credentials-in-env-file.qmd
- ../how-to/testing-overview.qmd
---
Expand Down Expand Up @@ -107,6 +108,12 @@ vm.init(
To also enable monitoring, add `monitoring=True` to the `vm.init` method in your code snippet. [^8]
:::

::: {.callout-note}
## Prefer OAuth / OIDC instead of API keys?

If your organization enables OIDC library connectivity, you can authenticate with the device authorization flow instead of `api_key` and `api_secret`. See [Authenticate with OIDC device flow](authenticate-with-oidc-device-flow.qmd).
:::

::: {.feature}
#### **Automate with {{< var vm.product >}}**

Expand Down
30 changes: 23 additions & 7 deletions site/developer/quickstart/store-credentials-in-env-file.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -75,14 +75,28 @@ i. Create a new file in the same folder as your notebook and name it `.env`.

This is a hidden file, so you may need to change your settings to view it.

ii. Use the code snippet from your clipboard to build the credentials in your `.env` file in the following format:[^6]
ii. Use the code snippet from your clipboard to build the credentials in your `.env` file.

```yaml
VM_API_HOST=<api_host>
VM_API_KEY=<api_key>
VM_API_SECRET=<api_secret>
VM_API_MODEL=<model>
```
**API key credentials**[^6]

```yaml
VM_API_HOST=<api_host>
VM_API_KEY=<api_key>
VM_API_SECRET=<api_secret>
VM_API_MODEL=<model>
```

**OIDC credentials**[^11]

```yaml
VM_API_HOST=<api_host>
VM_OIDC_ISSUER=<issuer>
VM_OIDC_CLIENT_ID=<client_id>
VM_OIDC_AUDIENCE=<audience>
VM_API_MODEL=<model>
```

Do not combine API key and OIDC variables for the same `vm.init()` call.

::: {.callout}
To define the document to connect the {{< var validmind.developer >}} to, or to enable monitoring, include these in your `vm.init()` snippet within your Jupyter Notebook.[^7]
Expand Down Expand Up @@ -198,3 +212,5 @@ c. Run the cell.
[^9]: [Enable monitoring](/guide/monitoring/enable-monitoring.qmd)

[^10]: [Install and initialize the {{< var validmind.developer >}}](/developer/quickstart/install-and-initialize-validmind-library.qmd#upgrade-validmind)

[^11]: [Authenticate with OIDC device flow](/developer/quickstart/authenticate-with-oidc-device-flow.qmd)
2 changes: 2 additions & 0 deletions site/developer/validmind-library.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ listing:
contents:
- ../notebooks/quickstart/quickstart_documentation.ipynb
- ../notebooks/quickstart/quickstart_validation.ipynb
- ../notebooks/quickstart/quickstart_model_documentation_oidc_device_flow.ipynb
- quickstart/authenticate-with-oidc-device-flow.qmd
- id: development
type: grid
grid-columns: 2
Expand Down
2 changes: 1 addition & 1 deletion site/get-started/common-steps/_get-your-code-snippet.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Refer to the LICENSE file in the root of this repository for details.
SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial -->

Before we move on, let's also retrieve the unique *code snippet* for your model that enables you to connect your testing environment with the correct document in the {{< var validmind.platform >}}:
Before we move on, let's also retrieve the unique *code snippet* for your model that enables you to connect your testing environment with the correct document in the {{< var validmind.platform >}}. Most organizations use an API key snippet; if your organization enables OIDC library connectivity, Getting Started can also show an OIDC device-flow snippet.^[[Authenticate with OIDC device flow](/developer/quickstart/authenticate-with-oidc-device-flow.qmd)]


:::: {.content-visible unless-format="revealjs" when-meta="includes.developer"}
Expand Down
2 changes: 1 addition & 1 deletion site/guide/monitoring/enable-monitoring.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ title: "Enable monitoring"
date: last-modified
---

To start uploading ongoing monitoring results for a record (model) to {{< var vm.product >}}, enable monitoring in your code snippet within the {{< var validmind.platform >}} and then select a monitoring template. You can enable monitoring for both new and existing records.
To start uploading ongoing monitoring results for a record (model) to {{< var vm.product >}}, enable monitoring in your code snippet within the {{< var validmind.platform >}} and then select a monitoring template. You can enable monitoring for both new and existing records. Add `monitoring=True` whether you authenticate with API keys or with [OIDC device flow](/developer/quickstart/authenticate-with-oidc-device-flow.qmd).

::: {.callout title="To try out monitoring, check out the code sample for ongoing monitoring."}
[Quickstart for ongoing monitoring of models with {{< var vm.product >}} {{< fa hand-point-right >}}](/notebooks/use_cases/ongoing_monitoring/quickstart_customer_churn_ongoing_monitoring.ipynb)
Expand Down
55 changes: 50 additions & 5 deletions site/reference/validmind-rest-api-vm.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,26 @@ This version of the API is **v1**, specified in the path (`/vm/api/v1`). Future

## Authentication

### Required headers
You can authenticate Public REST API requests with **API keys** or, when your organization enables it, an **OIDC bearer access token**.

All API endpoints require authentication using two headers that must be included with every request:
::: {.callout-note}
## Availability of OIDC

OIDC bearer auth for the Public REST API depends on your organization's API connectivity settings. If bearer requests return `403`, your organization may require API keys only — contact your ValidMind administrator.
:::

::: {.panel-tabset}

### API key

#### Required headers

Include both headers with every request:

- `x-api-key`: Your ValidMind API key
- `x-api-secret`: Your ValidMind API secret
- `x-api-secret`: Your ValidMind API secret

### Request example
#### Request example

To use this cURL example, replace `API_KEY` and `API_SECRET` with your own credentials:

Expand All @@ -56,7 +68,7 @@ curl -X GET "https://api.prod.validmind.ai/vm/api/v1/models" \
-H 'x-api-secret: API_SECRET'
```

### Get your API key and secret
#### Get your API key and secret {#get-your-api-key-and-secret}

1. In the left sidebar, click **{{< fa gear >}} Settings**.

Expand All @@ -67,6 +79,39 @@ curl -X GET "https://api.prod.validmind.ai/vm/api/v1/models" \
- Locate **API Key** and click **{{< fa clipboard >}} Copy to Clipboard**.
- Locate **Secret Key** and click **{{< fa clipboard >}} Copy to Clipboard**.

### OIDC bearer token

#### Required headers

Include an OIDC access token obtained from your organization's identity provider (for example via the OAuth 2.0 device authorization flow):

- `Authorization: Bearer <access_token>`

If your user belongs to **more than one** organization, also include:

- `X-Organization-Id: <organization-cuid>`

When you belong to exactly one organization, you can omit `X-Organization-Id` and the API uses that membership.

::: {.callout}
Do not send API key headers together with a bearer token for the same request. Use one authentication mode at a time.
:::

#### Request example

```
curl -X GET "https://api.prod.validmind.ai/vm/api/v1/models" \
-H 'accept: application/json' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'X-Organization-Id: ORGANIZATION_CUID'
```

Replace `ACCESS_TOKEN` with a valid OIDC access token for your ValidMind deployment, and `ORGANIZATION_CUID` when you need to select an organization.

For library sessions that use the same device-flow pattern in Python notebooks, see [Authenticate with OIDC device flow](/developer/quickstart/authenticate-with-oidc-device-flow.qmd). Public API callers obtain and refresh tokens with their IdP client, then pass the access token in the `Authorization` header as shown above.

:::

## Data formats

The APIs follows REST principles and uses JSON for both requests and responses.
Expand Down
8 changes: 8 additions & 0 deletions site/reference/vm-api.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ bread-crumbs: false
</style>
```

::: {.callout-note}
## Authentication in this reference

The interactive OpenAPI explorer below is generated from the Public REST API schema and currently focuses on **API key** authentication (`x-api-key` / `x-api-secret`).

The Public REST API also accepts **OIDC bearer tokens** (`Authorization: Bearer`) when your organization enables that connectivity mode. For headers, organization selection, and examples, see [Authentication](/reference/validmind-rest-api-vm.qmd#authentication) on the Public REST API overview.
:::

::: {.column-screen}
<script type="module" src="https://unpkg.com/rapidoc/dist/rapidoc-min.js"></script>

Expand Down
18 changes: 18 additions & 0 deletions site/support/troubleshooting.qmd
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,24 @@ Make sure that you are using the correct initialization credentials for the reco

Follow the steps in [Install and initialize the {{< var validmind.developer >}}](/developer/quickstart/install-and-initialize-validmind-library.qmd) for detailed instructions on how to integrate the {{< var vm.developer >}} and upload to the {{< var vm.platform >}}.

If your organization uses OIDC instead of API keys, initialize with `issuer` and `client_id` (or the matching `VM_OIDC_*` environment variables). See [Authenticate with OIDC device flow](/developer/quickstart/authenticate-with-oidc-device-flow.qmd).

## OIDC authentication errors when initializing the {{< var validmind.developer >}}

### Issue

When you run `vm.init()` with OIDC settings, sign-in fails, token refresh fails, or API calls return `401` / `403` after device authorization completes.

### Fix

- Confirm you are on {{< var validmind.developer >}} version **2.13** or later.
- Pass **either** API key credentials **or** OIDC settings — not both.
- Verify `issuer`, `client_id`, and (when required) `audience` match the values configured for your organization.
- Complete the browser device-flow prompt when the library prints a verification URL and user code.
- If tokens were previously cached for a different client or audience, remove or update `~/.validmind/credentials.json` and run `vm.init()` again.

For setup details, see [Authenticate with OIDC device flow](/developer/quickstart/authenticate-with-oidc-device-flow.qmd).

## SSL verification errors when initializing the {{< var validmind.developer >}} {#ssl-verification-when-initializing-library}

### Issue
Expand Down
Loading