diff --git a/site/developer/_sidebar.yaml b/site/developer/_sidebar.yaml index 399bd86069..72307efb83 100644 --- a/site/developer/_sidebar.yaml +++ b/site/developer/_sidebar.yaml @@ -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" diff --git a/site/developer/quickstart/authenticate-with-oidc-device-flow.qmd b/site/developer/quickstart/authenticate-with-oidc-device-flow.qmd new file mode 100644 index 0000000000..e1a879742b --- /dev/null +++ b/site/developer/quickstart/authenticate-with-oidc-device-flow.qmd @@ -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//v2.0", + client_id="", + audience="", # 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//v2.0 +VM_OIDC_CLIENT_ID= +VM_OIDC_AUDIENCE= +VM_API_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 ` 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} +::: + + + + +[^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) diff --git a/site/developer/quickstart/install-and-initialize-validmind-library.qmd b/site/developer/quickstart/install-and-initialize-validmind-library.qmd index a09c2cf6d2..53ef22db27 100644 --- a/site/developer/quickstart/install-and-initialize-validmind-library.qmd +++ b/site/developer/quickstart/install-and-initialize-validmind-library.qmd @@ -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 --- @@ -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 >}}** diff --git a/site/developer/quickstart/store-credentials-in-env-file.qmd b/site/developer/quickstart/store-credentials-in-env-file.qmd index 44e85fb267..59271f4dd6 100644 --- a/site/developer/quickstart/store-credentials-in-env-file.qmd +++ b/site/developer/quickstart/store-credentials-in-env-file.qmd @@ -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= - VM_API_KEY= - VM_API_SECRET= - VM_API_MODEL= - ``` + **API key credentials**[^6] + + ```yaml + VM_API_HOST= + VM_API_KEY= + VM_API_SECRET= + VM_API_MODEL= + ``` + + **OIDC credentials**[^11] + + ```yaml + VM_API_HOST= + VM_OIDC_ISSUER= + VM_OIDC_CLIENT_ID= + VM_OIDC_AUDIENCE= + VM_API_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] @@ -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) diff --git a/site/developer/validmind-library.qmd b/site/developer/validmind-library.qmd index e522a4772a..3ff75d309e 100644 --- a/site/developer/validmind-library.qmd +++ b/site/developer/validmind-library.qmd @@ -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 diff --git a/site/get-started/common-steps/_get-your-code-snippet.qmd b/site/get-started/common-steps/_get-your-code-snippet.qmd index 335faf663d..301e371194 100644 --- a/site/get-started/common-steps/_get-your-code-snippet.qmd +++ b/site/get-started/common-steps/_get-your-code-snippet.qmd @@ -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"} diff --git a/site/guide/monitoring/enable-monitoring.qmd b/site/guide/monitoring/enable-monitoring.qmd index 0d2965d6f3..0874816e1a 100644 --- a/site/guide/monitoring/enable-monitoring.qmd +++ b/site/guide/monitoring/enable-monitoring.qmd @@ -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) diff --git a/site/reference/validmind-rest-api-vm.qmd b/site/reference/validmind-rest-api-vm.qmd index 7c97cb7869..6da11fbdc5 100644 --- a/site/reference/validmind-rest-api-vm.qmd +++ b/site/reference/validmind-rest-api-vm.qmd @@ -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: @@ -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**. @@ -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 ` + +If your user belongs to **more than one** organization, also include: + +- `X-Organization-Id: ` + +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. diff --git a/site/reference/vm-api.qmd b/site/reference/vm-api.qmd index e9e1cf0497..f118475ec5 100644 --- a/site/reference/vm-api.qmd +++ b/site/reference/vm-api.qmd @@ -18,6 +18,14 @@ bread-crumbs: false ``` +::: {.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} diff --git a/site/support/troubleshooting.qmd b/site/support/troubleshooting.qmd index 443618c45e..26126a99c0 100644 --- a/site/support/troubleshooting.qmd +++ b/site/support/troubleshooting.qmd @@ -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