From 1308d144bbdcb8905cd648b21cf4206258396e39 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Wed, 29 Apr 2026 18:51:45 -0700 Subject: [PATCH 01/12] docs: Add Databricks Unity Catalog integration documentation Add documentation for the new Databricks integration that enables linking ValidMind inventory records to Databricks Unity Catalog resources including models, datasets, and agents. - Add Databricks to supported connections in configure-connections.qmd - Add Databricks to model inventory integrations in managing-integrations.qmd - Add step-by-step connection and linking examples in integrations-examples.qmd Closes sc-14813 --- .../integrations/configure-connections.qmd | 15 ++++ .../integrations/integrations-examples.qmd | 74 ++++++++++++++++++- .../integrations/managing-integrations.qmd | 4 + 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/site/guide/integrations/configure-connections.qmd b/site/guide/integrations/configure-connections.qmd index dfa716269e..8b9718129b 100644 --- a/site/guide/integrations/configure-connections.qmd +++ b/site/guide/integrations/configure-connections.qmd @@ -121,6 +121,21 @@ Required configuration details: **[personal access token]{.smallcaps}** : Select a secret containing your GitLab Personal Access Token with `api` or `read_api` scope. +### Databricks + +A unified analytics platform for data engineering, data science, and machine learning, including Unity Catalog for centralized metadata management. + +Required configuration details: + +**[databricks host]{.smallcaps}** +: The URL of your Databricks workspace, such as `https://yourcompany.cloud.databricks.com`. + +**[client id]{.smallcaps}** +: The secret that stores the OAuth client ID for service principal authentication. + +**[client secret]{.smallcaps}** +: The secret that stores the OAuth client secret for service principal authentication. + ### Custom A user-defined connection to a third-party system that implements the {{< var vm.product >}} reference API.[^4] diff --git a/site/guide/integrations/integrations-examples.qmd b/site/guide/integrations/integrations-examples.qmd index 9ee496a775..c613f308dd 100644 --- a/site/guide/integrations/integrations-examples.qmd +++ b/site/guide/integrations/integrations-examples.qmd @@ -14,6 +14,7 @@ Adapt these usage examples for your own workflows or connections to interact wit - [Add webhook step triggers](#add-webhook-step-triggers) - [Synchronize models with AWS SageMaker](#synchronize-models-with-aws-sagemaker) - [Synchronize models with AWS Bedrock](#synchronize-models-with-aws-bedrock) +- [Synchronize models with Databricks](#synchronize-models-with-databricks) - [Synchronize models with GitLab](#synchronize-models-with-gitlab) ::: {.attn} @@ -377,6 +378,75 @@ This builds a complete dependency graph showing how your AI applications relate 9. Click **Link Model**. +### Synchronize models with Databricks + +The Databricks integration lets you link {{< var vm.product >}} inventory records to models, datasets, and agents in Databricks Unity Catalog. This supports governance across your ML ecosystem and enables bidirectional metadata synchronization. + +Databricks Unity Catalog provides a unified governance solution for all data and AI assets across your Databricks workspaces. The integration exposes three primary resource types: + +- **Models** — Registered ML models in Unity Catalog's model registry. +- **Datasets** — Tables and datasets managed by Unity Catalog. +- **Agents** — AI agents and applications built on Databricks. + +#### Configure the connection + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **Databricks**. + +5. Complete: + + - **[integration name]{.smallcaps}** — How other admins can identify the connection. + - **[description]{.smallcaps}** (optional) — The intended usage or additional details. + - **[databricks host]{.smallcaps}** — The URL of your Databricks workspace, such as `https://yourcompany.cloud.databricks.com`. + - **[client id]{.smallcaps}** — The secret that stores the OAuth client ID for service principal authentication. + - **[client secret]{.smallcaps}** — The secret that stores the OAuth client secret for service principal authentication. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection: + + a. Hover over the Databricks connection you just created. + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. + + If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. + +#### Link records to Databricks + +Once the connection is configured, you can link {{< var vm.product >}} inventory records to your Databricks Unity Catalog resources: + +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.[^15] + +3. Scroll down until you locate the **Databricks** connection box in the right sidebar. + +4. Hover over the Databricks box. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens, use the tabs to filter by resource type: + + - **All** — View all available Unity Catalog resources. + - **Models** — Registered models in Unity Catalog's model registry. + - **Datasets** — Tables and datasets managed by Unity Catalog. + - **Agents** — AI agents built on Databricks. + +7. Click **[select model]{.smallcaps}** to choose the specific Unity Catalog resource to link. + +8. Optional: Click **Test Connection** to ensure the connection is working as expected. + + If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. + +9. Click **Link Model**. + +After linking, metadata from the Unity Catalog resource syncs to {{< var vm.product >}}. You can use linked fields in custom calculated fields to surface Databricks metadata directly in your inventory views. + ### Synchronize models with GitLab Synchronize GitLab model registry with ValidMind model inventory for comprehensive model tracking. @@ -461,4 +531,6 @@ Synchronize GitLab model registry with ValidMind model inventory for comprehensi [^13]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) -[^14]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) \ No newline at end of file +[^14]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) + +[^15]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) \ No newline at end of file diff --git a/site/guide/integrations/managing-integrations.qmd b/site/guide/integrations/managing-integrations.qmd index da285be92d..e0b719628f 100644 --- a/site/guide/integrations/managing-integrations.qmd +++ b/site/guide/integrations/managing-integrations.qmd @@ -86,6 +86,10 @@ Link to models in external registries and development platforms and keep invento - AWS Bedrock ::: +::: {.w-20-ns} +- Databricks +::: + ::: {.w-20-ns} - MLflow ::: From 0a489b4bb5b06fd0633790163981b9b6edaeda64 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Thu, 30 Apr 2026 02:21:59 -0700 Subject: [PATCH 02/12] Add placeholder columns to integrations grid layout --- .../integrations/managing-integrations.qmd | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/site/guide/integrations/managing-integrations.qmd b/site/guide/integrations/managing-integrations.qmd index e0b719628f..b5403f1459 100644 --- a/site/guide/integrations/managing-integrations.qmd +++ b/site/guide/integrations/managing-integrations.qmd @@ -94,6 +94,14 @@ Link to models in external registries and development platforms and keep invento - MLflow ::: +::: {.w-20-ns} +  +::: + +:::: + +:::: {.flex .flex-wrap .justify-around} + ::: {.w-20-ns} - GitLab ::: @@ -102,6 +110,18 @@ Link to models in external registries and development platforms and keep invento - Custom integrations ::: +::: {.w-20-ns} +  +::: + +::: {.w-20-ns} +  +::: + +::: {.w-20-ns} +  +::: + :::: --- From 1e17a85c04181e1b158f7baa7f01700aac6f1ead Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Thu, 30 Apr 2026 02:27:33 -0700 Subject: [PATCH 03/12] Fix Databricks connection field names to match UI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - databricks host → workspace url - client id → sql warehouse id - client secret → personal access token --- site/guide/integrations/integrations-examples.qmd | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/site/guide/integrations/integrations-examples.qmd b/site/guide/integrations/integrations-examples.qmd index c613f308dd..3e4a5e78eb 100644 --- a/site/guide/integrations/integrations-examples.qmd +++ b/site/guide/integrations/integrations-examples.qmd @@ -402,9 +402,9 @@ Databricks Unity Catalog provides a unified governance solution for all data and - **[integration name]{.smallcaps}** — How other admins can identify the connection. - **[description]{.smallcaps}** (optional) — The intended usage or additional details. - - **[databricks host]{.smallcaps}** — The URL of your Databricks workspace, such as `https://yourcompany.cloud.databricks.com`. - - **[client id]{.smallcaps}** — The secret that stores the OAuth client ID for service principal authentication. - - **[client secret]{.smallcaps}** — The secret that stores the OAuth client secret for service principal authentication. + - **[workspace url]{.smallcaps}** — Your Databricks workspace URL, found in the browser address bar, such as `https://adb-1234567890.azuredatabricks.net`. + - **[sql warehouse id]{.smallcaps}** — The ID of your SQL Warehouse, found in SQL Warehouses settings. + - **[personal access token]{.smallcaps}** — Select a secret containing your Databricks Personal Access Token. - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. 6. Click **Save Integration**. From 5f5112121fd6226186e65acd159abdc84a6448e8 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Thu, 30 Apr 2026 02:32:48 -0700 Subject: [PATCH 04/12] Fix Databricks link model steps to match UI --- site/guide/integrations/integrations-examples.qmd | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/site/guide/integrations/integrations-examples.qmd b/site/guide/integrations/integrations-examples.qmd index 3e4a5e78eb..45852d3557 100644 --- a/site/guide/integrations/integrations-examples.qmd +++ b/site/guide/integrations/integrations-examples.qmd @@ -430,14 +430,12 @@ Once the connection is configured, you can link {{< var vm.product >}} inventory 5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. -6. In the modal that opens, use the tabs to filter by resource type: +6. In the modal that opens: - - **All** — View all available Unity Catalog resources. - - **Models** — Registered models in Unity Catalog's model registry. - - **Datasets** — Tables and datasets managed by Unity Catalog. - - **Agents** — AI agents built on Databricks. + - **[select model]{.smallcaps}** — Choose the Databricks model to link from the dropdown. + - **[sync frequency]{.smallcaps}** — Set how often ValidMind automatically syncs data from the external system. -7. Click **[select model]{.smallcaps}** to choose the specific Unity Catalog resource to link. +7. Click **Link Model** to complete the link. 8. Optional: Click **Test Connection** to ensure the connection is working as expected. From 50a648d025fbfda9bafebf6a3204d4a4855fa7c6 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Thu, 30 Apr 2026 15:12:37 -0700 Subject: [PATCH 05/12] docs: Fix Databricks connection field descriptions - client id: Update to describe SQL Warehouse ID - client secret: Update to describe PAT token secret --- site/guide/integrations/configure-connections.qmd | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/site/guide/integrations/configure-connections.qmd b/site/guide/integrations/configure-connections.qmd index 8b9718129b..caaa4326a5 100644 --- a/site/guide/integrations/configure-connections.qmd +++ b/site/guide/integrations/configure-connections.qmd @@ -16,7 +16,7 @@ Each connection enables you to authenticate and keep events flowing between plat - [x] {{< var link.login >}} - [x] You can manage workspace settings.[^1] -- [x] The integration’s required secrets already exist in integration secrets.[^2] +- [x] The integration's required secrets already exist in integration secrets.[^2] - [x] You coordinated with the external system owner to obtain the required credentials and configuration details for the connection. ::: @@ -131,10 +131,10 @@ Required configuration details: : The URL of your Databricks workspace, such as `https://yourcompany.cloud.databricks.com`. **[client id]{.smallcaps}** -: The secret that stores the OAuth client ID for service principal authentication. +: The ID of your SQL Warehouse (found in Databricks SQL Warehouses settings). **[client secret]{.smallcaps}** -: The secret that stores the OAuth client secret for service principal authentication. +: The secret that stores your Databricks personal access token (PAT). ### Custom @@ -239,4 +239,3 @@ If the test is successful, the message **{{< fa check-circle >}} Connection succ [^3]: [Supported connections](#supported-connections) [^4]: [Implement custom integrations](implement-custom-integrations.qmd) - From c1db43a06c016dbb9fd7cbe7228056c246c668bc Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Fri, 1 May 2026 14:09:17 -0700 Subject: [PATCH 06/12] docs: Add developer workflow for running validations on Databricks data Add a new section explaining how to run validation notebooks against Databricks-hosted data, with a link to the quickstart notebook and a mermaid diagram showing the data flow between platforms. --- .../integrations/integrations-examples.qmd | 50 ++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/site/guide/integrations/integrations-examples.qmd b/site/guide/integrations/integrations-examples.qmd index 45852d3557..745d0f4ec6 100644 --- a/site/guide/integrations/integrations-examples.qmd +++ b/site/guide/integrations/integrations-examples.qmd @@ -380,7 +380,7 @@ This builds a complete dependency graph showing how your AI applications relate ### Synchronize models with Databricks -The Databricks integration lets you link {{< var vm.product >}} inventory records to models, datasets, and agents in Databricks Unity Catalog. This supports governance across your ML ecosystem and enables bidirectional metadata synchronization. +The Databricks integration lets you link {{< var vm.product >}} inventory records to models, datasets, and agents in Databricks Unity Catalog. This supports governance across your ML ecosystem and enables bidirectional metadata synchronization. You can also run validation notebooks directly against Databricks-hosted data. Databricks Unity Catalog provides a unified governance solution for all data and AI assets across your Databricks workspaces. The integration exposes three primary resource types: @@ -445,6 +445,54 @@ Once the connection is configured, you can link {{< var vm.product >}} inventory After linking, metadata from the Unity Catalog resource syncs to {{< var vm.product >}}. You can use linked fields in custom calculated fields to surface Databricks metadata directly in your inventory views. +#### Run validations on Databricks data + +::: {.column-margin} +[Databricks quickstart](https://docs.validmind.ai/notebooks/databricks/validmind_databricks_quickstart.html){.button} +::: + +After linking your inventory record to Databricks, you can run validation tests directly against data hosted in Unity Catalog. + +```{mermaid} +%%| fig-cap: "Data flow between Databricks and ValidMind" +flowchart LR + subgraph databricks [Databricks] + UC[Unity Catalog] + Data[Tables/Datasets] + end + + subgraph notebook [Validation Notebook] + SDK[ValidMind SDK] + end + + subgraph validmind [ValidMind Platform] + Report[Validation Report] + Inventory[Inventory Record] + end + + UC --> Data + Data --> SDK + SDK --> Report + Report --> Inventory + Inventory -.->|linked| UC +``` + +The notebook demonstrates how to: + +1. Connect to your Databricks workspace and load data from Unity Catalog tables +2. Initialize ValidMind datasets from Databricks DataFrames: + + ```python + vm_train_ds = vm.init_dataset( + dataset=train_df, + input_id="train_dataset", + target_column=TARGET_COLUMN, + ) + ``` + +3. Register your model and assign predictions +4. Run the test suite to generate validation documentation + ### Synchronize models with GitLab Synchronize GitLab model registry with ValidMind model inventory for comprehensive model tracking. From d78d9c8ff8e56bc8f627cea85f73cdb176e329eb Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Mon, 4 May 2026 16:11:33 -0700 Subject: [PATCH 07/12] Split examples up into separate files. --- site/guide/_sidebar.yaml | 10 +- .../integrations/integrations-examples.qmd | 580 +----------------- .../create-jira-ticket.qmd | 83 +++ .../create-servicenow-incident.qmd | 76 +++ ...ns-examples-aws-sagemaker-linked-model.png | Bin .../integrations-examples-aws-sagemaker.png | Bin .../integrations-examples-gitlab.png | Bin ...examples-http-request-open-jira-ticket.png | Bin ...-http-request-open-servicenow-incident.png | Bin ...integrations-examples-webhook-run_step.png | Bin .../synchronize-aws-bedrock.qmd | 99 +++ .../synchronize-aws-sagemaker.qmd | 82 +++ .../synchronize-databricks.qmd | 139 +++++ .../synchronize-gitlab.qmd | 80 +++ .../use-webhooks-with-workflows.qmd | 128 ++++ 15 files changed, 705 insertions(+), 572 deletions(-) create mode 100644 site/guide/integrations/integrations-examples/create-jira-ticket.qmd create mode 100644 site/guide/integrations/integrations-examples/create-servicenow-incident.qmd rename site/guide/integrations/{ => integrations-examples}/integrations-examples-aws-sagemaker-linked-model.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-aws-sagemaker.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-gitlab.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-http-request-open-jira-ticket.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-http-request-open-servicenow-incident.png (100%) rename site/guide/integrations/{ => integrations-examples}/integrations-examples-webhook-run_step.png (100%) create mode 100644 site/guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd create mode 100644 site/guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd create mode 100644 site/guide/integrations/integrations-examples/synchronize-databricks.qmd create mode 100644 site/guide/integrations/integrations-examples/synchronize-gitlab.qmd create mode 100644 site/guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd diff --git a/site/guide/_sidebar.yaml b/site/guide/_sidebar.yaml index e1a8822d0f..9ddd356c00 100644 --- a/site/guide/_sidebar.yaml +++ b/site/guide/_sidebar.yaml @@ -49,7 +49,15 @@ website: - guide/integrations/link-external-models.qmd - guide/mcp/connect-ai-assistants-via-mcp.qmd - guide/integrations/configure-analytics-exports.qmd - - guide/integrations/integrations-examples.qmd + - file: guide/integrations/integrations-examples.qmd + contents: + - guide/integrations/integrations-examples/create-jira-ticket.qmd + - guide/integrations/integrations-examples/create-servicenow-incident.qmd + - guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd + - guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd + - guide/integrations/integrations-examples/synchronize-databricks.qmd + - guide/integrations/integrations-examples/synchronize-gitlab.qmd + - guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd - text: "---" - section: "Workflows" contents: diff --git a/site/guide/integrations/integrations-examples.qmd b/site/guide/integrations/integrations-examples.qmd index 745d0f4ec6..91c9a5c15e 100644 --- a/site/guide/integrations/integrations-examples.qmd +++ b/site/guide/integrations/integrations-examples.qmd @@ -4,579 +4,17 @@ # SPDX-License-Identifier: AGPL-3.0 AND ValidMind Commercial title: "Integrations examples" date: last-modified +listing: + - id: examples-listing + type: grid + grid-columns: 2 + max-description-length: 250 + sort: true + fields: [title, description] + contents: "integrations-examples/*.qmd" --- Adapt these usage examples for your own workflows or connections to interact with external systems. -- [Create a Jira ticket](#create-a-jira-ticket) -- [Create a ServiceNow incident](#create-a-servicenow-incident) -- [Start workflows via webhook](#start-workflows-via-webhook) -- [Add webhook step triggers](#add-webhook-step-triggers) -- [Synchronize models with AWS SageMaker](#synchronize-models-with-aws-sagemaker) -- [Synchronize models with AWS Bedrock](#synchronize-models-with-aws-bedrock) -- [Synchronize models with Databricks](#synchronize-models-with-databricks) -- [Synchronize models with GitLab](#synchronize-models-with-gitlab) - -::: {.attn} - -## Prerequisites - -- [x] {{< var link.login >}} -- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure workflows.[^1] -- [x] You understand how to configure workflows and add steps to workflows.[^2] -- [x] Secrets are configured for any external systems that require authentication: integration secrets for connections, webhook secrets for HTTP Request step headers.[^3] -- [x] Connections are configured for any external systems you plan to integrate with.[^4] -- [x] You have admin access to the external systems you plan to integrate with. - -::: - -## Workflow examples - -These examples use HTTP requests or webhooks to integrate with external systems: - -- An _HTTP request_ step sends data from {{< var vm.product >}} to another service. A workflow can notify a partner tool when a model reaches a certain state or request an update in an external system. This pattern is useful when {{< var vm.product >}} owns the event and needs to push it outward. - -- A _webhook_ step does the opposite. Another system sends a POST request to start a {{< var vm.product >}} workflow or to continue a workflow that is paused while waiting for a webhook to continue. This lets external tools trigger actions inside {{< var vm.product >}} when an event occurs on their side. - -### Create a Jira ticket - -To create a Jira ticket when model validation requires attention: - -::: {.column-margin} -![Create a Jira issue](integrations-examples-http-request-open-jira-ticket.png){width=80% fig-alt="Screenshot of the HTTP request step configured to create a Jira ticket, showing the required fields described in step 4." .screenshot} -::: - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - -2. Under {{< fa shield >}} Governance, select **Workflows**. - -3. Select the **Model Workflows** tab. - -4. Click on a workflow to modify or click **{{< fa plus >}} Add Model Workflow**[^5] to create a new workflow. - -5. From the **Workflow Steps** modal, drag and drop an **HTTP Request** step[^6] onto the canvas, then connect it to your workflow. - -6. Double-click the step to open the **Configure HTTP Request** modal. - -7. Configure the required fields, replacing the placeholder values with your own: - - - **[url]{.smallcaps}** — `https://yourcompany.atlassian.net/rest/api/3/issue` - - **[method]{.smallcaps}** — POST - - **[headers]{.smallcaps}** — Add: - - `Content-Type`: `application/json` - - `Authorization`: `Bearer {{Jira Personal Access Token}}` - - ::: {.callout-tip title="Use webhook secrets for credentials"} - Instead of entering credentials in plaintext, use a webhook secret: `Bearer {{secret:jira_pat}}`. See [Manage secrets](manage-secrets.qmd#webhook-secrets). - ::: - - - **[body type]{.smallcaps}** — JSON - - **[body]{.smallcaps}** — Use the following JSON payload: - - ```json - { - "fields": { - "project": { - "key": "MODEL" - }, - "summary": "Model validation failed: {{Model Name}}", - "description": "The model [{{Model Name}}|{{Model URL}}] failed validation. Review artifacts in ValidMind.", - "issuetype": { - "name": "Bug" - } - } - } - ``` - -8. Click **Update Step** to save your configuration. - -The HTTP request to create the Jira ticket is sent when the workflow executes the step. - -### Create a ServiceNow incident - -To create a ServiceNow incident when a data drift issue is detected during ongoing monitoring: - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - - -2. Under {{< fa shield >}} Governance, select **Workflows**. - -3. Select the **Model Workflows** tab. - -4. Click on a workflow to modify or click **{{< fa plus >}} Add Model Workflow**[^5] to create a new workflow. - -5. From the **Workflow Steps** modal, drag and drop an **HTTP Request** step[^7] onto the canvas, then connect it to your workflow. - -6. Double-click the step to open the **Configure HTTP Request** modal. - -7. Configure the required fields, replacing the placeholder values with your own: - - - **[url]{.smallcaps}** — `https://yourinstance.service-now.com/api/now/table/incident` - - **[method]{.smallcaps}** — POST - - **[headers]{.smallcaps}** — Add: - - `Content-Type`: `application/json` - - `Authorization`: `Basic {{ServiceNow Credentials}}` - - ::: {.callout-tip title="Use webhook secrets for credentials"} - Instead of entering credentials in plaintext, use a webhook secret: `Basic {{secret:servicenow_creds}}`. See [Manage secrets](manage-secrets.qmd#webhook-secrets). - ::: - - - **[body type]{.smallcaps}** — JSON - - **[body]{.smallcaps}** — Use the following JSON payload: - - ```json - { - "short_description": "Data drift issue detected: {{Model Name}}", - "description": "A potential issue has been identified for model {{Model Name}} (link: [{{Model URL}}]({{Model URL}})). Please review the ongoing monitoring documentation in ValidMind.", - "urgency": "2", - "category": "Model Risk" - } - ``` - -::: {.column-margin} -![Create a ServiceNow incident](integrations-examples-http-request-open-servicenow-incident.png){width=80% fig-alt="Screenshot of the HTTP request step configured to create a ServiceNow incident, showing the required fields described in step 4." .screenshot} -::: - -The HTTP request to create the ServiceNow incident is sent when the workflow executes the step. - -### Start workflows via webhook - -To start a {{< var vm.product >}} workflow from an external system: - -::: {.panel-tabset} - -#### a. Configure workflow in {{< var vm.product >}} - -1. Add a new workflow, selecting the **Via Webhook** workflow start option.[^8] - -2. From the **Workflow Steps** modal, drag and drop a **Webhook** step[^9] onto the canvas, then connect it to your workflow. - -3. Double-click the step to open the **Webhook Step Trigger** modal. - -4. Copy or select the webhook details: - - - **URL** — Click **{{< fa regular copy >}} Copy** for the unique POST webhook URL to use when configuring your external system. - - **[select target model for payload]{.smallcaps}** — Select the model that is associated with the webhook payload from the dropdown. - - **Payload** — Click **{{< fa regular copy >}} Copy** for the JSON payload that external systems must send in their POST request, where the value for `target_cuid` is shown after you select a target: - - ```json - { - "action": "run_workflow", - "target": "", - "entity_name": "InventoryModel" - } - ``` - - - For the required authentication headers, click **{{< fa regular copy >}} Copy** for each of the following key-value pairs and paste them into your external system: - - `x-api-key`: `{{API Key}}` - - `x-api-secret`: `{{API Secret}}` - - **[wait for webhook trigger when reached]{.smallcaps}** — When enabled, the workflow pauses execution when it reaches this step and waits for the external system to send the POST request. - -5. Click **Save**. - -#### b. Start workflow from external system - -Send a POST request to the webhook URL with a JSON payload that includes the `run_workflow` action for the target model CUID: - -```bash -curl -X POST https://api.prod.vm.validmind.ai/vm/api/v1/webhooks/xxxxxxxxxxxxxxxxxxxxxxxxx/xxxx -H 'Content-Type`: `application/json' -H 'x-api-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -H 'x-api-secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' --data '{ - "action": "run_workflow", - "target": "", - "entity_name": "InventoryModel" -}' -``` -::: - -### Add webhook step triggers - -To trigger a waiting {{< var vm.product >}} workflow step to continue from an external system: - -::: {.panel-tabset} - -#### a. Configure workflow in {{< var vm.product >}} - -1. Open the workflow you want to configure, or add a new workflow.[^10] - -2. From the **Workflow Steps** modal, drag and drop a **Webhook** step[^11] onto the canvas, then connect the step to your workflow. - -3. Double-click the step to open the **Webhook Step Trigger** modal. - -4. Copy or select the webhook details: - - - **URL** — Click **{{< fa regular copy >}} Copy** for the unique POST webhook URL to use when configuring your external system. - - **[select target model for payload]{.smallcaps}** — Select the model that is associated with the webhook payload from the dropdown. - - **Payload** — Click **{{< fa regular copy >}} Copy** for the JSON payload that external systems must send in their POST request, where the value for `target_cuid` is shown after you select a target: - - ```json - { - "action": "run_step", - "target": "", - "entity_name": "InventoryModel" - } - ``` - - - For the required authentication headers, click **{{< fa regular copy >}} Copy** for each of the following key-value pairs and paste them into your external system: - - `x-api-key`: `{{API Key}}` - - `x-api-secret`: `{{API Secret}}` - -5. Click **Update Step** to save your configuration. - -When the workflow reaches this step, it pauses and waits for the external system. - -#### b. Trigger workflow to continue from external system - -Send a POST request to the webhook URL with a JSON payload containing the `run_step` action for the model CUID: - -```bash -curl -X POST https://api.prod.vm.validmind.ai/vm/api/v1/webhooks/xxxxxxxxxxxxxxxxxxxxxxxxx/xxxx -H 'Content-Type`: `application/json' -H 'x-api-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -H 'x-api-secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' --data '{ - "action": "run_step", - "target": "", - "entity_name": "InventoryModel" -}' -``` - -::: - -## Connection examples - -### Synchronize models with AWS SageMaker - -::: {.column-margin} -![Connect with AWS SageMaker](integrations-examples-aws-sagemaker.png){width=80% fig-alt="Screenshot of the AWS Sagemaker connection configured to synchronize models, showing the required fields described in step 5." .screenshot} -::: - -To synchronize models registered in the {{< var vm.product >}} model inventory with AWS SageMaker models, you need to first configure the connection and then link the models: - -#### Configure the connection - -::: {.column-margin} -![A linked AWS SageMaker model](integrations-examples-aws-sagemaker-linked-model.png){width=60% fig-alt="Screenshot of the model linked to AWS SageMaker, showing the required fields described in step 4." .screenshot} -::: - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - -2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. - -3. Click **{{< fa plus >}} Add Connection**. - -4. In the modal that opens, select **AWS Sagemaker**. - -5. Complete: - - - **[integration name]{.smallcaps}** — How other admins can identify the connection. - - **[description]{.smallcaps}** (optional) — The intended usage or additional details. - - **[aws region]{.smallcaps}** - The primary region where your SageMaker model registry lives, for example `us-west-2`. - - **[aws access key id]{.smallcaps}** — The secret generated by AWS IAM with permissions to read the model registry. - - **[aws secret access key]{.smallcaps}** — The secret generated by AWS IAM with permissions to read the model registry. - - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. - -6. Click **Save Integration**. - -7. Test the connection: - - a. Hover over the AWS SageMaker connection you just created. - b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. - - If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. - - -#### Link the models - -1. In the left sidebar, click **{{< fa cubes >}} Inventory**. - -2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^12] - -3. Scroll down until you locate the **Amazon Sagemaker** connection box in the right sidebar. - -4. Hover over the Amazon SageMaker box. - -5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. - -6. In the modal that opens, click the [select model]{.smallcaps} dropdown to pick the AWS SageMaker model to link. - -7. Optional: Click **Test Connection** to ensure the connection is working as expected. - - If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. - -8. Click **Link Model**. - -### Synchronize models with AWS Bedrock - -The AWS Bedrock integration lets you link {{< var vm.product >}} models to foundation models and generative AI agents in Amazon Bedrock, supporting governance across your AI/ML ecosystem. - -AWS Bedrock exposes two primary integration surfaces: - -- **Foundation model layer** — Access to AWS-hosted and custom foundation models through the Bedrock model catalog (Discover and Tune views). - -- **Application layer** — Bedrock primitives such as agents, flows, and knowledge bases that represent built generative AI applications and workflows. - -#### Configure the connection - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - -2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. - -3. Click **{{< fa plus >}} Add Connection**. - -4. In the modal that opens, select **AWS Bedrock**. - -5. Complete: - - - **[integration name]{.smallcaps}** — How other admins can identify the connection. - - **[description]{.smallcaps}** (optional) — The intended usage or additional details. - - **[aws region]{.smallcaps}** — The primary region where your Bedrock resources are deployed, for example `us-east-1`. - - **[aws access key id]{.smallcaps}** — The secret generated by AWS IAM with permissions to access Bedrock. - - **[aws secret access key]{.smallcaps}** — The secret generated by AWS IAM with permissions to access Bedrock. - - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. - -6. Click **Save Integration**. - -7. Test the connection: - - a. Hover over the AWS Bedrock connection you just created. - b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. - - If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. - -#### Link models from Bedrock - -Once the connection is configured, you can link {{< var vm.product >}} models to your Bedrock resources: - -::: {.callout title="Model dependencies"} -Bedrock agents, flows, and runtimes typically call foundation models (LLMs) under the hood. When you link these application-layer resources to {{< var vm.product >}}, consider also registering their underlying foundation models and creating dependency relationships between them. - -This builds a complete dependency graph showing how your AI applications relate to underlying models. Benefits include: - -- **Impact analysis** — See which applications are affected if a foundation model is deprecated or has compliance issues. -- **Full audit trails** — Documentation and risk assessments capture the entire model stack, not just the top-level application. -- **Governance visibility** — Track model versions and changes across your AI ecosystem. +:::{#examples-listing} ::: - -1. In the left sidebar, click **{{< fa cubes >}} Inventory**. - -2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^13] - -3. Scroll down until you locate the **Amazon Bedrock** connection box in the right sidebar. - -4. Hover over the Amazon Bedrock box. - -5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. - -6. In the modal that opens, use the tabs to filter by resource type: - - - **All** — View all available Bedrock resources. - - **Foundation Models** — AWS-hosted and custom foundation models from the Bedrock catalog. - - **Agents** — Generative AI agents you've built in Bedrock. - - **Flows** — Prompt flows and orchestration workflows. - - **AgentCore Runtimes** — Agent runtime environments. - -7. Click **[select model]{.smallcaps}** to choose the specific Bedrock resource to link. - -8. Optional: Click **Test Connection** to ensure the connection is working as expected. - - If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. - -9. Click **Link Model**. - -### Synchronize models with Databricks - -The Databricks integration lets you link {{< var vm.product >}} inventory records to models, datasets, and agents in Databricks Unity Catalog. This supports governance across your ML ecosystem and enables bidirectional metadata synchronization. You can also run validation notebooks directly against Databricks-hosted data. - -Databricks Unity Catalog provides a unified governance solution for all data and AI assets across your Databricks workspaces. The integration exposes three primary resource types: - -- **Models** — Registered ML models in Unity Catalog's model registry. -- **Datasets** — Tables and datasets managed by Unity Catalog. -- **Agents** — AI agents and applications built on Databricks. - -#### Configure the connection - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - -2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. - -3. Click **{{< fa plus >}} Add Connection**. - -4. In the modal that opens, select **Databricks**. - -5. Complete: - - - **[integration name]{.smallcaps}** — How other admins can identify the connection. - - **[description]{.smallcaps}** (optional) — The intended usage or additional details. - - **[workspace url]{.smallcaps}** — Your Databricks workspace URL, found in the browser address bar, such as `https://adb-1234567890.azuredatabricks.net`. - - **[sql warehouse id]{.smallcaps}** — The ID of your SQL Warehouse, found in SQL Warehouses settings. - - **[personal access token]{.smallcaps}** — Select a secret containing your Databricks Personal Access Token. - - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. - -6. Click **Save Integration**. - -7. Test the connection: - - a. Hover over the Databricks connection you just created. - b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. - - If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. - -#### Link records to Databricks - -Once the connection is configured, you can link {{< var vm.product >}} inventory records to your Databricks Unity Catalog resources: - -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.[^15] - -3. Scroll down until you locate the **Databricks** connection box in the right sidebar. - -4. Hover over the Databricks box. - -5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. - -6. In the modal that opens: - - - **[select model]{.smallcaps}** — Choose the Databricks model to link from the dropdown. - - **[sync frequency]{.smallcaps}** — Set how often ValidMind automatically syncs data from the external system. - -7. Click **Link Model** to complete the link. - -8. Optional: Click **Test Connection** to ensure the connection is working as expected. - - If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. - -9. Click **Link Model**. - -After linking, metadata from the Unity Catalog resource syncs to {{< var vm.product >}}. You can use linked fields in custom calculated fields to surface Databricks metadata directly in your inventory views. - -#### Run validations on Databricks data - -::: {.column-margin} -[Databricks quickstart](https://docs.validmind.ai/notebooks/databricks/validmind_databricks_quickstart.html){.button} -::: - -After linking your inventory record to Databricks, you can run validation tests directly against data hosted in Unity Catalog. - -```{mermaid} -%%| fig-cap: "Data flow between Databricks and ValidMind" -flowchart LR - subgraph databricks [Databricks] - UC[Unity Catalog] - Data[Tables/Datasets] - end - - subgraph notebook [Validation Notebook] - SDK[ValidMind SDK] - end - - subgraph validmind [ValidMind Platform] - Report[Validation Report] - Inventory[Inventory Record] - end - - UC --> Data - Data --> SDK - SDK --> Report - Report --> Inventory - Inventory -.->|linked| UC -``` - -The notebook demonstrates how to: - -1. Connect to your Databricks workspace and load data from Unity Catalog tables -2. Initialize ValidMind datasets from Databricks DataFrames: - - ```python - vm_train_ds = vm.init_dataset( - dataset=train_df, - input_id="train_dataset", - target_column=TARGET_COLUMN, - ) - ``` - -3. Register your model and assign predictions -4. Run the test suite to generate validation documentation - -### Synchronize models with GitLab - -Synchronize GitLab model registry with ValidMind model inventory for comprehensive model tracking. - -#### Configure the connection - -::: {.column-margin} -![Configure GitLab connection](integrations-examples-gitlab.png){width=80% fig-alt="Screenshot of the Configure GitLab dialog showing fields for integration name, description, project ID, GitLab instance URL, personal access token, and initial status." .screenshot} -::: - -1. In the left sidebar, click **{{< fa gear >}} Settings**. - -2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. - -3. Click **{{< fa plus >}} Add Connection**. - -4. In the modal that opens, select **GitLab**. - -5. Complete: - - - **[integration name]{.smallcaps}** — How other admins can identify the connection. - - **[description]{.smallcaps}** (optional) — The intended usage or additional details. - - **[project id]{.smallcaps}** — The GitLab project ID or path containing ML models (required). - - **[gitlab instance url]{.smallcaps}** (optional) — Leave empty to use GitLab.com, or enter your self-hosted GitLab URL. - - **[personal access token]{.smallcaps}** — Select a secret containing your GitLab Personal Access Token with `api` or `read_api` scope. - - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. - -6. Click **Save Integration**. - -7. Test the connection: - - a. Hover over the GitLab connection you just created. - b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. - - If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. - -#### Link the models - -1. In the left sidebar, click **{{< fa cubes >}} Inventory**. - -2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^14] - -3. Scroll down until you locate the **GitLab** connection box in the right sidebar. - -4. Hover over the GitLab box. - -5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. - -6. In the modal that opens, click the [select model]{.smallcaps} dropdown to pick the GitLab model to link. - -7. Optional: Click **Test Connection** to ensure the connection is working as expected. - - If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. - -8. Click **Link Model**. - - - -[^1]: [Manage permissions](/guide/configuration/manage-permissions.qmd) - -[^2]: [Introduction to workflows](/guide/workflows/introduction-to-workflows.qmd) - -[^3]: [Manage secrets](manage-secrets.qmd) - -[^4]: [Configure connections](configure-connections.qmd) - -[^5]: [Add new workflows](/guide/workflows/configure-workflows.qmd#add-new-workflows) - -[^6]: [Workflow step types](/guide/workflows/workflow-step-types.qmd#http-request) - -[^7]: [Workflow step types](/guide/workflows/workflow-step-types.qmd#http-request) - -[^8]: [Add new workflows](/guide/workflows/configure-workflows.qmd#add-new-workflows) - -[^9]: [Workflow step types](/guide/workflows/workflow-step-types.qmd#webhook) - -[^10]: [Add new workflows](/guide/workflows/configure-workflows.qmd#add-new-workflows) - -[^11]: [Workflow step types](/guide/workflows/workflow-step-types.qmd#webhook) - -[^12]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) - -[^13]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) - -[^14]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) - -[^15]: [Working with the inventory](/guide/inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) \ No newline at end of file diff --git a/site/guide/integrations/integrations-examples/create-jira-ticket.qmd b/site/guide/integrations/integrations-examples/create-jira-ticket.qmd new file mode 100644 index 0000000000..cc487738e7 --- /dev/null +++ b/site/guide/integrations/integrations-examples/create-jira-ticket.qmd @@ -0,0 +1,83 @@ +--- +# 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: "Create a Jira ticket" +date: last-modified +--- + +Create a Jira ticket when model validation requires attention using an HTTP request workflow step. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure workflows.[^1] +- [x] You understand how to configure workflows and add steps to workflows.[^2] +- [x] A webhook secret is configured for your Jira Personal Access Token.[^3] +- [x] You have admin access to Jira. + +::: + +::: {.column-margin} +![Create a Jira issue](integrations-examples-http-request-open-jira-ticket.png){width=80% fig-alt="Screenshot of the HTTP request step configured to create a Jira ticket, showing the required fields described in step 4." .screenshot} +::: + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa shield >}} Governance, select **Workflows**. + +3. Select the **Model Workflows** tab. + +4. Click on a workflow to modify or click **{{< fa plus >}} Add Model Workflow**[^4] to create a new workflow. + +5. From the **Workflow Steps** modal, drag and drop an **HTTP Request** step[^5] onto the canvas, then connect it to your workflow. + +6. Double-click the step to open the **Configure HTTP Request** modal. + +7. Configure the required fields, replacing the placeholder values with your own: + + - **[url]{.smallcaps}** — `https://yourcompany.atlassian.net/rest/api/3/issue` + - **[method]{.smallcaps}** — POST + - **[headers]{.smallcaps}** — Add: + - `Content-Type`: `application/json` + - `Authorization`: `Bearer {{Jira Personal Access Token}}` + + ::: {.callout-tip title="Use webhook secrets for credentials"} + Instead of entering credentials in plaintext, use a webhook secret: `Bearer {{secret:jira_pat}}`. See [Manage secrets](../manage-secrets.qmd#webhook-secrets). + ::: + + - **[body type]{.smallcaps}** — JSON + - **[body]{.smallcaps}** — Use the following JSON payload: + + ```json + { + "fields": { + "project": { + "key": "MODEL" + }, + "summary": "Model validation failed: {{Model Name}}", + "description": "The model [{{Model Name}}|{{Model URL}}] failed validation. Review artifacts in ValidMind.", + "issuetype": { + "name": "Bug" + } + } + } + ``` + +8. Click **Update Step** to save your configuration. + +The HTTP request to create the Jira ticket is sent when the workflow executes the step. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Introduction to workflows](../../workflows/introduction-to-workflows.qmd) + +[^3]: [Manage secrets](../manage-secrets.qmd) + +[^4]: [Add new workflows](../../workflows/configure-workflows.qmd#add-new-workflows) + +[^5]: [Workflow step types](../../workflows/workflow-step-types.qmd#http-request) diff --git a/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd b/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd new file mode 100644 index 0000000000..2fab57ae78 --- /dev/null +++ b/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd @@ -0,0 +1,76 @@ +--- +# 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: "Create a ServiceNow incident" +date: last-modified +--- + +Create a ServiceNow incident when a data drift issue is detected during ongoing monitoring using an HTTP request workflow step. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure workflows.[^1] +- [x] You understand how to configure workflows and add steps to workflows.[^2] +- [x] A webhook secret is configured for your ServiceNow credentials.[^3] +- [x] You have admin access to ServiceNow. + +::: + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + + +2. Under {{< fa shield >}} Governance, select **Workflows**. + +3. Select the **Model Workflows** tab. + +4. Click on a workflow to modify or click **{{< fa plus >}} Add Model Workflow**[^4] to create a new workflow. + +5. From the **Workflow Steps** modal, drag and drop an **HTTP Request** step[^5] onto the canvas, then connect it to your workflow. + +6. Double-click the step to open the **Configure HTTP Request** modal. + +7. Configure the required fields, replacing the placeholder values with your own: + + - **[url]{.smallcaps}** — `https://yourinstance.service-now.com/api/now/table/incident` + - **[method]{.smallcaps}** — POST + - **[headers]{.smallcaps}** — Add: + - `Content-Type`: `application/json` + - `Authorization`: `Basic {{ServiceNow Credentials}}` + + ::: {.callout-tip title="Use webhook secrets for credentials"} + Instead of entering credentials in plaintext, use a webhook secret: `Basic {{secret:servicenow_creds}}`. See [Manage secrets](../manage-secrets.qmd#webhook-secrets). + ::: + + - **[body type]{.smallcaps}** — JSON + - **[body]{.smallcaps}** — Use the following JSON payload: + + ```json + { + "short_description": "Data drift issue detected: {{Model Name}}", + "description": "A potential issue has been identified for model {{Model Name}} (link: [{{Model URL}}]({{Model URL}})). Please review the ongoing monitoring documentation in ValidMind.", + "urgency": "2", + "category": "Model Risk" + } + ``` + +::: {.column-margin} +![Create a ServiceNow incident](integrations-examples-http-request-open-servicenow-incident.png){width=80% fig-alt="Screenshot of the HTTP request step configured to create a ServiceNow incident, showing the required fields described in step 4." .screenshot} +::: + +The HTTP request to create the ServiceNow incident is sent when the workflow executes the step. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Introduction to workflows](../../workflows/introduction-to-workflows.qmd) + +[^3]: [Manage secrets](../manage-secrets.qmd) + +[^4]: [Add new workflows](../../workflows/configure-workflows.qmd#add-new-workflows) + +[^5]: [Workflow step types](../../workflows/workflow-step-types.qmd#http-request) diff --git a/site/guide/integrations/integrations-examples-aws-sagemaker-linked-model.png b/site/guide/integrations/integrations-examples/integrations-examples-aws-sagemaker-linked-model.png similarity index 100% rename from site/guide/integrations/integrations-examples-aws-sagemaker-linked-model.png rename to site/guide/integrations/integrations-examples/integrations-examples-aws-sagemaker-linked-model.png diff --git a/site/guide/integrations/integrations-examples-aws-sagemaker.png b/site/guide/integrations/integrations-examples/integrations-examples-aws-sagemaker.png similarity index 100% rename from site/guide/integrations/integrations-examples-aws-sagemaker.png rename to site/guide/integrations/integrations-examples/integrations-examples-aws-sagemaker.png diff --git a/site/guide/integrations/integrations-examples-gitlab.png b/site/guide/integrations/integrations-examples/integrations-examples-gitlab.png similarity index 100% rename from site/guide/integrations/integrations-examples-gitlab.png rename to site/guide/integrations/integrations-examples/integrations-examples-gitlab.png diff --git a/site/guide/integrations/integrations-examples-http-request-open-jira-ticket.png b/site/guide/integrations/integrations-examples/integrations-examples-http-request-open-jira-ticket.png similarity index 100% rename from site/guide/integrations/integrations-examples-http-request-open-jira-ticket.png rename to site/guide/integrations/integrations-examples/integrations-examples-http-request-open-jira-ticket.png diff --git a/site/guide/integrations/integrations-examples-http-request-open-servicenow-incident.png b/site/guide/integrations/integrations-examples/integrations-examples-http-request-open-servicenow-incident.png similarity index 100% rename from site/guide/integrations/integrations-examples-http-request-open-servicenow-incident.png rename to site/guide/integrations/integrations-examples/integrations-examples-http-request-open-servicenow-incident.png diff --git a/site/guide/integrations/integrations-examples-webhook-run_step.png b/site/guide/integrations/integrations-examples/integrations-examples-webhook-run_step.png similarity index 100% rename from site/guide/integrations/integrations-examples-webhook-run_step.png rename to site/guide/integrations/integrations-examples/integrations-examples-webhook-run_step.png diff --git a/site/guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd b/site/guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd new file mode 100644 index 0000000000..ef136a1d60 --- /dev/null +++ b/site/guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd @@ -0,0 +1,99 @@ +--- +# 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: "Synchronize models with AWS Bedrock" +date: last-modified +--- + +Link {{< var vm.product >}} models to foundation models and generative AI agents in Amazon Bedrock, supporting governance across your AI/ML ecosystem. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure connections.[^1] +- [x] You have AWS IAM credentials with permissions to access Bedrock. + +::: + +AWS Bedrock exposes two primary integration surfaces: + +- **Foundation model layer** — Access to AWS-hosted and custom foundation models through the Bedrock model catalog (Discover and Tune views). + +- **Application layer** — Bedrock primitives such as agents, flows, and knowledge bases that represent built generative AI applications and workflows. + +## Configure the connection + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **AWS Bedrock**. + +5. Complete: + + - **[integration name]{.smallcaps}** — How other admins can identify the connection. + - **[description]{.smallcaps}** (optional) — The intended usage or additional details. + - **[aws region]{.smallcaps}** — The primary region where your Bedrock resources are deployed, for example `us-east-1`. + - **[aws access key id]{.smallcaps}** — The secret generated by AWS IAM with permissions to access Bedrock. + - **[aws secret access key]{.smallcaps}** — The secret generated by AWS IAM with permissions to access Bedrock. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection: + + a. Hover over the AWS Bedrock connection you just created. + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. + + If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. + +## Link models from Bedrock + +Once the connection is configured, you can link {{< var vm.product >}} models to your Bedrock resources: + +::: {.callout title="Model dependencies"} +Bedrock agents, flows, and runtimes typically call foundation models (LLMs) under the hood. When you link these application-layer resources to {{< var vm.product >}}, consider also registering their underlying foundation models and creating dependency relationships between them. + +This builds a complete dependency graph showing how your AI applications relate to underlying models. Benefits include: + +- **Impact analysis** — See which applications are affected if a foundation model is deprecated or has compliance issues. +- **Full audit trails** — Documentation and risk assessments capture the entire model stack, not just the top-level application. +- **Governance visibility** — Track model versions and changes across your AI ecosystem. +::: + +1. In the left sidebar, click **{{< fa cubes >}} Inventory**. + +2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^2] + +3. Scroll down until you locate the **Amazon Bedrock** connection box in the right sidebar. + +4. Hover over the Amazon Bedrock box. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens, use the tabs to filter by resource type: + + - **All** — View all available Bedrock resources. + - **Foundation Models** — AWS-hosted and custom foundation models from the Bedrock catalog. + - **Agents** — Generative AI agents you've built in Bedrock. + - **Flows** — Prompt flows and orchestration workflows. + - **AgentCore Runtimes** — Agent runtime environments. + +7. Click **[select model]{.smallcaps}** to choose the specific Bedrock resource to link. + +8. Optional: Click **Test Connection** to ensure the connection is working as expected. + + If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. + +9. Click **Link Model**. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Working with the inventory](../../inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) diff --git a/site/guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd b/site/guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd new file mode 100644 index 0000000000..cc87f119f5 --- /dev/null +++ b/site/guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd @@ -0,0 +1,82 @@ +--- +# 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: "Synchronize models with AWS SageMaker" +date: last-modified +--- + +Synchronize models registered in the {{< var vm.product >}} model inventory with AWS SageMaker models. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure connections.[^1] +- [x] You have AWS IAM credentials with permissions to read the SageMaker model registry. + +::: + +## Configure the connection + +::: {.column-margin} +![Connect with AWS SageMaker](integrations-examples-aws-sagemaker.png){width=80% fig-alt="Screenshot of the AWS Sagemaker connection configured to synchronize models, showing the required fields described in step 5." .screenshot} +::: + +::: {.column-margin} +![A linked AWS SageMaker model](integrations-examples-aws-sagemaker-linked-model.png){width=60% fig-alt="Screenshot of the model linked to AWS SageMaker, showing the required fields described in step 4." .screenshot} +::: + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **AWS Sagemaker**. + +5. Complete: + + - **[integration name]{.smallcaps}** — How other admins can identify the connection. + - **[description]{.smallcaps}** (optional) — The intended usage or additional details. + - **[aws region]{.smallcaps}** - The primary region where your SageMaker model registry lives, for example `us-west-2`. + - **[aws access key id]{.smallcaps}** — The secret generated by AWS IAM with permissions to read the model registry. + - **[aws secret access key]{.smallcaps}** — The secret generated by AWS IAM with permissions to read the model registry. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection: + + a. Hover over the AWS SageMaker connection you just created. + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. + + If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. + + +## Link the models + +1. In the left sidebar, click **{{< fa cubes >}} Inventory**. + +2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^2] + +3. Scroll down until you locate the **Amazon Sagemaker** connection box in the right sidebar. + +4. Hover over the Amazon SageMaker box. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens, click the [select model]{.smallcaps} dropdown to pick the AWS SageMaker model to link. + +7. Optional: Click **Test Connection** to ensure the connection is working as expected. + + If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. + +8. Click **Link Model**. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Working with the inventory](../../inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) diff --git a/site/guide/integrations/integrations-examples/synchronize-databricks.qmd b/site/guide/integrations/integrations-examples/synchronize-databricks.qmd new file mode 100644 index 0000000000..4c8c78a355 --- /dev/null +++ b/site/guide/integrations/integrations-examples/synchronize-databricks.qmd @@ -0,0 +1,139 @@ +--- +# 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: "Synchronize models with Databricks" +date: last-modified +--- + +Link {{< var vm.product >}} inventory records to models, datasets, and agents in Databricks Unity Catalog for governance across your ML ecosystem and bidirectional metadata synchronization. You can also run validation notebooks directly against Databricks-hosted data. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure connections.[^1] +- [x] A secret is configured for your Databricks Personal Access Token.[^2] +- [x] You have admin access to your Databricks workspace. + +::: + +Databricks Unity Catalog provides a unified governance solution for all data and AI assets across your Databricks workspaces. The integration exposes three primary resource types: + +- **Models** — Registered ML models in Unity Catalog's model registry. +- **Datasets** — Tables and datasets managed by Unity Catalog. +- **Agents** — AI agents and applications built on Databricks. + +## Configure the connection + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **Databricks**. + +5. Complete: + + - **[integration name]{.smallcaps}** — How other admins can identify the connection. + - **[description]{.smallcaps}** (optional) — The intended usage or additional details. + - **[workspace url]{.smallcaps}** — Your Databricks workspace URL, found in the browser address bar, such as `https://adb-1234567890.azuredatabricks.net`. + - **[sql warehouse id]{.smallcaps}** — The ID of your SQL Warehouse, found in SQL Warehouses settings. + - **[personal access token]{.smallcaps}** — Select a secret containing your Databricks Personal Access Token. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection: + + a. Hover over the Databricks connection you just created. + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. + + If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. + +## Link records to Databricks + +Once the connection is configured, you can link {{< var vm.product >}} inventory records to your Databricks Unity Catalog resources: + +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.[^3] + +3. Scroll down until you locate the **Databricks** connection box in the right sidebar. + +4. Hover over the Databricks box. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens: + + - **[select model]{.smallcaps}** — Choose the Databricks model to link from the dropdown. + - **[sync frequency]{.smallcaps}** — Set how often ValidMind automatically syncs data from the external system. + +7. Click **Link Model** to complete the link. + +8. Optional: Click **Test Connection** to ensure the connection is working as expected. + + If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. + +9. Click **Link Model**. + +After linking, metadata from the Unity Catalog resource syncs to {{< var vm.product >}}. You can use linked fields in custom calculated fields to surface Databricks metadata directly in your inventory views. + +## Run validations on Databricks data + +::: {.column-margin} +[Databricks quickstart](https://docs.validmind.ai/notebooks/databricks/validmind_databricks_quickstart.html){.button} +::: + +After linking your inventory record to Databricks, you can run validation tests directly against data hosted in Unity Catalog. + +```{mermaid} +%%| fig-cap: "Data flow between Databricks and ValidMind" +flowchart LR + subgraph databricks [Databricks] + UC[Unity Catalog] + Data[Tables/Datasets] + end + + subgraph notebook [Validation Notebook] + SDK[ValidMind SDK] + end + + subgraph validmind [ValidMind Platform] + Report[Validation Report] + Inventory[Inventory Record] + end + + UC --> Data + Data --> SDK + SDK --> Report + Report --> Inventory + Inventory -.->|linked| UC +``` + +The notebook demonstrates how to: + +1. Connect to your Databricks workspace and load data from Unity Catalog tables +2. Initialize ValidMind datasets from Databricks DataFrames: + + ```python + vm_train_ds = vm.init_dataset( + dataset=train_df, + input_id="train_dataset", + target_column=TARGET_COLUMN, + ) + ``` + +3. Register your model and assign predictions +4. Run the test suite to generate validation documentation + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Manage secrets](../manage-secrets.qmd) + +[^3]: [Working with the inventory](../../inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) diff --git a/site/guide/integrations/integrations-examples/synchronize-gitlab.qmd b/site/guide/integrations/integrations-examples/synchronize-gitlab.qmd new file mode 100644 index 0000000000..c8a9095ee4 --- /dev/null +++ b/site/guide/integrations/integrations-examples/synchronize-gitlab.qmd @@ -0,0 +1,80 @@ +--- +# 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: "Synchronize models with GitLab" +date: last-modified +--- + +Synchronize GitLab model registry with ValidMind model inventory for comprehensive model tracking. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure connections.[^1] +- [x] A secret is configured for your GitLab Personal Access Token with `api` or `read_api` scope.[^2] +- [x] You have access to the GitLab project containing ML models. + +::: + +## Configure the connection + +::: {.column-margin} +![Configure GitLab connection](integrations-examples-gitlab.png){width=80% fig-alt="Screenshot of the Configure GitLab dialog showing fields for integration name, description, project ID, GitLab instance URL, personal access token, and initial status." .screenshot} +::: + +1. In the left sidebar, click **{{< fa gear >}} Settings**. + +2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**. + +3. Click **{{< fa plus >}} Add Connection**. + +4. In the modal that opens, select **GitLab**. + +5. Complete: + + - **[integration name]{.smallcaps}** — How other admins can identify the connection. + - **[description]{.smallcaps}** (optional) — The intended usage or additional details. + - **[project id]{.smallcaps}** — The GitLab project ID or path containing ML models (required). + - **[gitlab instance url]{.smallcaps}** (optional) — Leave empty to use GitLab.com, or enter your self-hosted GitLab URL. + - **[personal access token]{.smallcaps}** — Select a secret containing your GitLab Personal Access Token with `api` or `read_api` scope. + - **[initial status]{.smallcaps}** — Set to `Operational` to enable immediately or `Disabled` if you plan to finish setup later. + +6. Click **Save Integration**. + +7. Test the connection: + + a. Hover over the GitLab connection you just created. + b. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa circle-check >}} Test Connection**. + + If the test is successful, the message **{{< fa check-circle >}} Connection successful** displays. + +## Link the models + +1. In the left sidebar, click **{{< fa cubes >}} Inventory**. + +2. Select a model by clicking on it or find your model by applying a filter or searching for it.[^3] + +3. Scroll down until you locate the **GitLab** connection box in the right sidebar. + +4. Hover over the GitLab box. + +5. When the **{{< fa ellipsis-vertical >}}** menu appears, click on it and select **{{< fa link >}} Link Model**. + +6. In the modal that opens, click the [select model]{.smallcaps} dropdown to pick the GitLab model to link. + +7. Optional: Click **Test Connection** to ensure the connection is working as expected. + + If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. + +8. Click **Link Model**. + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Manage secrets](../manage-secrets.qmd) + +[^3]: [Working with the inventory](../../inventory/working-with-the-inventory.qmd#search-filter-and-sort-records) diff --git a/site/guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd b/site/guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd new file mode 100644 index 0000000000..22b7dd9a0d --- /dev/null +++ b/site/guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd @@ -0,0 +1,128 @@ +--- +# 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: "Use webhooks with workflows" +date: last-modified +--- + +Use webhooks to let external systems start {{< var vm.product >}} workflows or trigger paused workflows to continue. + +::: {.attn} + +## Prerequisites + +- [x] {{< var link.login >}} +- [x] You are a [{{< fa hand >}} Customer Admin]{.bubble} or assigned another role with sufficient permissions to configure workflows.[^1] +- [x] You understand how to configure workflows and add steps to workflows.[^2] +- [x] You have admin access to the external system that will send webhook requests. + +::: + +## Start a workflow via webhook + +Start a {{< var vm.product >}} workflow from an external system by sending a POST request to trigger a new workflow. + +::: {.panel-tabset} + +### a. Configure workflow in {{< var vm.product >}} + +1. Add a new workflow, selecting the **Via Webhook** workflow start option.[^3] + +2. From the **Workflow Steps** modal, drag and drop a **Webhook** step[^4] onto the canvas, then connect it to your workflow. + +3. Double-click the step to open the **Webhook Step Trigger** modal. + +4. Copy or select the webhook details: + + - **URL** — Click **{{< fa regular copy >}} Copy** for the unique POST webhook URL to use when configuring your external system. + - **[select target model for payload]{.smallcaps}** — Select the model that is associated with the webhook payload from the dropdown. + - **Payload** — Click **{{< fa regular copy >}} Copy** for the JSON payload that external systems must send in their POST request, where the value for `target_cuid` is shown after you select a target: + + ```json + { + "action": "run_workflow", + "target": "", + "entity_name": "InventoryModel" + } + ``` + + - For the required authentication headers, click **{{< fa regular copy >}} Copy** for each of the following key-value pairs and paste them into your external system: + - `x-api-key`: `{{API Key}}` + - `x-api-secret`: `{{API Secret}}` + - **[wait for webhook trigger when reached]{.smallcaps}** — When enabled, the workflow pauses execution when it reaches this step and waits for the external system to send the POST request. + +5. Click **Save**. + +### b. Start workflow from external system + +Send a POST request to the webhook URL with a JSON payload that includes the `run_workflow` action for the target model CUID: + +```bash +curl -X POST https://api.prod.vm.validmind.ai/vm/api/v1/webhooks/xxxxxxxxxxxxxxxxxxxxxxxxx/xxxx -H 'Content-Type`: `application/json' -H 'x-api-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -H 'x-api-secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' --data '{ + "action": "run_workflow", + "target": "", + "entity_name": "InventoryModel" +}' +``` +::: + +## Trigger a paused workflow to continue + +Trigger a waiting {{< var vm.product >}} workflow step to continue from an external system. Use this pattern when a workflow pauses at a webhook step and waits for external input before proceeding. + +::: {.panel-tabset} + +### a. Configure workflow in {{< var vm.product >}} + +1. Open the workflow you want to configure, or add a new workflow.[^3] + +2. From the **Workflow Steps** modal, drag and drop a **Webhook** step[^4] onto the canvas, then connect the step to your workflow. + +3. Double-click the step to open the **Webhook Step Trigger** modal. + +4. Copy or select the webhook details: + + - **URL** — Click **{{< fa regular copy >}} Copy** for the unique POST webhook URL to use when configuring your external system. + - **[select target model for payload]{.smallcaps}** — Select the model that is associated with the webhook payload from the dropdown. + - **Payload** — Click **{{< fa regular copy >}} Copy** for the JSON payload that external systems must send in their POST request, where the value for `target_cuid` is shown after you select a target: + + ```json + { + "action": "run_step", + "target": "", + "entity_name": "InventoryModel" + } + ``` + + - For the required authentication headers, click **{{< fa regular copy >}} Copy** for each of the following key-value pairs and paste them into your external system: + - `x-api-key`: `{{API Key}}` + - `x-api-secret`: `{{API Secret}}` + +5. Click **Update Step** to save your configuration. + +When the workflow reaches this step, it pauses and waits for the external system. + +### b. Trigger workflow to continue from external system + +Send a POST request to the webhook URL with a JSON payload containing the `run_step` action for the model CUID: + +```bash +curl -X POST https://api.prod.vm.validmind.ai/vm/api/v1/webhooks/xxxxxxxxxxxxxxxxxxxxxxxxx/xxxx -H 'Content-Type`: `application/json' -H 'x-api-key: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' -H 'x-api-secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' --data '{ + "action": "run_step", + "target": "", + "entity_name": "InventoryModel" +}' +``` + +::: + + + +[^1]: [Manage permissions](../../configuration/manage-permissions.qmd) + +[^2]: [Introduction to workflows](../../workflows/introduction-to-workflows.qmd) + +[^3]: [Add new workflows](../../workflows/configure-workflows.qmd#add-new-workflows) + +[^4]: [Workflow step types](../../workflows/workflow-step-types.qmd#webhook) From 5a944615af9f8d53dee492cf176315b124055b37 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Mon, 4 May 2026 16:34:25 -0700 Subject: [PATCH 08/12] File rename --- site/guide/_sidebar.yaml | 2 +- ...ks.qmd => synchronize-with-databricks.qmd} | 90 +++++++++---------- 2 files changed, 45 insertions(+), 47 deletions(-) rename site/guide/integrations/integrations-examples/{synchronize-databricks.qmd => synchronize-with-databricks.qmd} (87%) diff --git a/site/guide/_sidebar.yaml b/site/guide/_sidebar.yaml index 9ddd356c00..ec417ba925 100644 --- a/site/guide/_sidebar.yaml +++ b/site/guide/_sidebar.yaml @@ -55,7 +55,7 @@ website: - guide/integrations/integrations-examples/create-servicenow-incident.qmd - guide/integrations/integrations-examples/synchronize-aws-bedrock.qmd - guide/integrations/integrations-examples/synchronize-aws-sagemaker.qmd - - guide/integrations/integrations-examples/synchronize-databricks.qmd + - guide/integrations/integrations-examples/synchronize-with-databricks.qmd - guide/integrations/integrations-examples/synchronize-gitlab.qmd - guide/integrations/integrations-examples/use-webhooks-with-workflows.qmd - text: "---" diff --git a/site/guide/integrations/integrations-examples/synchronize-databricks.qmd b/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd similarity index 87% rename from site/guide/integrations/integrations-examples/synchronize-databricks.qmd rename to site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd index 4c8c78a355..06fb77caad 100644 --- a/site/guide/integrations/integrations-examples/synchronize-databricks.qmd +++ b/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd @@ -2,8 +2,19 @@ # 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: "Synchronize models with Databricks" +title: "Synchronize with Databricks" date: last-modified +listing: + - id: whats-next + type: grid + grid-columns: 2 + max-description-length: 250 + sort: false + fields: [title, description] + contents: + - path: https://docs.validmind.ai/notebooks/databricks/validmind_databricks_quickstart.html + title: "Databricks quickstart" + description: "Install the {{< var validmind.developer >}}, load data from a Unity Catalog table via Spark, train a simple classification model, and run ValidMind tests to send results to the {{< var validmind.platform >}}." --- Link {{< var vm.product >}} inventory records to models, datasets, and agents in Databricks Unity Catalog for governance across your ML ecosystem and bidirectional metadata synchronization. You can also run validation notebooks directly against Databricks-hosted data. @@ -19,12 +30,42 @@ Link {{< var vm.product >}} inventory records to models, datasets, and agents in ::: + +## How does the integration with Databricks work? + Databricks Unity Catalog provides a unified governance solution for all data and AI assets across your Databricks workspaces. The integration exposes three primary resource types: - **Models** — Registered ML models in Unity Catalog's model registry. - **Datasets** — Tables and datasets managed by Unity Catalog. - **Agents** — AI agents and applications built on Databricks. +After linking your inventory record to Databricks, you can run validation tests directly against data hosted in Unity Catalog. + +```{mermaid} +%%| fig-cap: "Data flow between Databricks and ValidMind" +flowchart LR + subgraph databricks [Databricks] + UC[Unity Catalog] + Data[Tables/Datasets] + end + + subgraph notebook [Validation Notebook] + SDK[ValidMind SDK] + end + + subgraph validmind [ValidMind Platform] + Report[Validation Report] + Inventory[Inventory Record] + end + + UC --> Data + Data --> SDK + SDK --> Report + Report --> Inventory + Inventory -.->|linked| UC +``` + + ## Configure the connection 1. In the left sidebar, click **{{< fa gear >}} Settings**. @@ -82,54 +123,11 @@ Once the connection is configured, you can link {{< var vm.product >}} inventory After linking, metadata from the Unity Catalog resource syncs to {{< var vm.product >}}. You can use linked fields in custom calculated fields to surface Databricks metadata directly in your inventory views. -## Run validations on Databricks data +## What's next -::: {.column-margin} -[Databricks quickstart](https://docs.validmind.ai/notebooks/databricks/validmind_databricks_quickstart.html){.button} +:::{#whats-next} ::: -After linking your inventory record to Databricks, you can run validation tests directly against data hosted in Unity Catalog. - -```{mermaid} -%%| fig-cap: "Data flow between Databricks and ValidMind" -flowchart LR - subgraph databricks [Databricks] - UC[Unity Catalog] - Data[Tables/Datasets] - end - - subgraph notebook [Validation Notebook] - SDK[ValidMind SDK] - end - - subgraph validmind [ValidMind Platform] - Report[Validation Report] - Inventory[Inventory Record] - end - - UC --> Data - Data --> SDK - SDK --> Report - Report --> Inventory - Inventory -.->|linked| UC -``` - -The notebook demonstrates how to: - -1. Connect to your Databricks workspace and load data from Unity Catalog tables -2. Initialize ValidMind datasets from Databricks DataFrames: - - ```python - vm_train_ds = vm.init_dataset( - dataset=train_df, - input_id="train_dataset", - target_column=TARGET_COLUMN, - ) - ``` - -3. Register your model and assign predictions -4. Run the test suite to generate validation documentation - [^1]: [Manage permissions](../../configuration/manage-permissions.qmd) From 92bc660175911d39b6f2af4e1e1f5b6c67a08a90 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Mon, 4 May 2026 16:54:39 -0700 Subject: [PATCH 09/12] Remove terminology ambiguity --- .../integrations-examples/synchronize-with-databricks.qmd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd b/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd index 06fb77caad..112f075e1d 100644 --- a/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd +++ b/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd @@ -33,7 +33,7 @@ Link {{< var vm.product >}} inventory records to models, datasets, and agents in ## How does the integration with Databricks work? -Databricks Unity Catalog provides a unified governance solution for all data and AI assets across your Databricks workspaces. The integration exposes three primary resource types: +Databricks Unity Catalog provides a unified governance solution for all data and AI assets across your Databricks workspaces. The integration exposes three Unity Catalog resource types: - **Models** — Registered ML models in Unity Catalog's model registry. - **Datasets** — Tables and datasets managed by Unity Catalog. From 7a20d7a8b04f16d8fec50c461b5b3144f2d3a73e Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Tue, 5 May 2026 08:51:05 -0700 Subject: [PATCH 10/12] Edits --- .../integrations-examples/synchronize-with-databricks.qmd | 6 +----- site/guide/integrations/managing-integrations.qmd | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd b/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd index 112f075e1d..236485f346 100644 --- a/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd +++ b/site/guide/integrations/integrations-examples/synchronize-with-databricks.qmd @@ -115,11 +115,7 @@ Once the connection is configured, you can link {{< var vm.product >}} inventory 7. Click **Link Model** to complete the link. -8. Optional: Click **Test Connection** to ensure the connection is working as expected. - - If the test is successful, the message **{{< fa check-circle >}} Connection Test Successful** displays. - -9. Click **Link Model**. +8. Click **Link Model**. After linking, metadata from the Unity Catalog resource syncs to {{< var vm.product >}}. You can use linked fields in custom calculated fields to surface Databricks metadata directly in your inventory views. diff --git a/site/guide/integrations/managing-integrations.qmd b/site/guide/integrations/managing-integrations.qmd index b5403f1459..2f15044cb0 100644 --- a/site/guide/integrations/managing-integrations.qmd +++ b/site/guide/integrations/managing-integrations.qmd @@ -107,7 +107,7 @@ Link to models in external registries and development platforms and keep invento ::: ::: {.w-20-ns} -- Custom integrations +- Custom ::: ::: {.w-20-ns} From 07dcb8d1524bb473b114706922c63c1cdd8a6f97 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Tue, 5 May 2026 08:57:56 -0700 Subject: [PATCH 11/12] Add missing headings for steps --- .../integrations/integrations-examples/create-jira-ticket.qmd | 2 ++ .../integrations-examples/create-servicenow-incident.qmd | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/site/guide/integrations/integrations-examples/create-jira-ticket.qmd b/site/guide/integrations/integrations-examples/create-jira-ticket.qmd index cc487738e7..975f31de73 100644 --- a/site/guide/integrations/integrations-examples/create-jira-ticket.qmd +++ b/site/guide/integrations/integrations-examples/create-jira-ticket.qmd @@ -20,6 +20,8 @@ Create a Jira ticket when model validation requires attention using an HTTP requ ::: +## Configure the workflow step + ::: {.column-margin} ![Create a Jira issue](integrations-examples-http-request-open-jira-ticket.png){width=80% fig-alt="Screenshot of the HTTP request step configured to create a Jira ticket, showing the required fields described in step 4." .screenshot} ::: diff --git a/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd b/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd index 2fab57ae78..7ecde2eadf 100644 --- a/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd +++ b/site/guide/integrations/integrations-examples/create-servicenow-incident.qmd @@ -20,8 +20,9 @@ Create a ServiceNow incident when a data drift issue is detected during ongoing ::: -1. In the left sidebar, click **{{< fa gear >}} Settings**. +## Configure the workflow step +1. In the left sidebar, click **{{< fa gear >}} Settings**. 2. Under {{< fa shield >}} Governance, select **Workflows**. From 79ffd2d68ee009e755effcadded94d44309258b5 Mon Sep 17 00:00:00 2001 From: Nik Richers Date: Tue, 5 May 2026 09:04:51 -0700 Subject: [PATCH 12/12] Add configuration screenshot --- .../configure-databricks.png | Bin 0 -> 72235 bytes .../synchronize-with-databricks.qmd | 4 ++++ 2 files changed, 4 insertions(+) create mode 100644 site/guide/integrations/integrations-examples/configure-databricks.png diff --git a/site/guide/integrations/integrations-examples/configure-databricks.png b/site/guide/integrations/integrations-examples/configure-databricks.png new file mode 100644 index 0000000000000000000000000000000000000000..d524781af9ba8727d44ff260bbd2c846fd5eec8a GIT binary patch literal 72235 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⪼5HL8qbkDIO|Q=1%d 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 Settings**. 2. Under {{< fa puzzle-piece >}} Integrations, select **Connections**.