diff --git a/.secrets.baseline b/.secrets.baseline index a564ade05..6956014ed 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -142,7 +142,7 @@ "filename": "deploy/.env.example", "hashed_secret": "9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684", "is_verified": false, - "line_number": 37 + "line_number": 40 } ], "deploy/compose/README.md": [ @@ -355,5 +355,5 @@ } ] }, - "generated_at": "2026-07-15T21:41:56Z" + "generated_at": "2026-07-17T19:18:23Z" } diff --git a/deploy/.env.example b/deploy/.env.example index bbb6b5f99..8dffdf95f 100644 --- a/deploy/.env.example +++ b/deploy/.env.example @@ -16,6 +16,9 @@ AIQ_DEV_ENV=cli # ----------------------------------------------------------------------------- NVIDIA_API_KEY= +# Frontier models: required only for config_frontier_models.yml (GPT-5.2 orchestration/planning/writing). +# OPENAI_API_KEY= + # Web search (Required — set at least one provider key) YDC_API_KEY= @@ -69,6 +72,17 @@ DASK_DISTRIBUTED__LOGGING__DISTRIBUTED=warning # Credentials use workload identity or the standard AWS credential chain. # Local MinIO may set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in deploy/.env. +# ----------------------------------------------------------------------------- +# Content encryption (optional; encrypts stored report/artifact content at rest) +# See docs/source/deployment/content-encryption.md. Set the same value on every +# API and worker process. Default (unset) is `off` — content is stored as plaintext. +# key — one operator-managed static 32-byte key (dev/test); set AIQ_CONTENT_ENCRYPTION_KEY. +# vault — HashiCorp Vault Transit (production); see the doc for the Vault variables. +# ----------------------------------------------------------------------------- +# AIQ_CONTENT_ENCRYPTION=key +# AIQ_CONTENT_ENCRYPTION_KEY= # base64/base64url value decoding to exactly 32 bytes (key mode) +# AIQ_CONTENT_ENCRYPTION_KEY_ID= # optional operator-managed key id (defaults to "static-key") + # ----------------------------------------------------------------------------- # Per-user MCP auth token store (config_web_frag_mcp_auth.yml) # Shared, persistent store the API process (connect) and the Dask worker (job) diff --git a/docs/source/customization/guardrails.md b/docs/source/customization/guardrails.md index 17a749842..fc20001ed 100644 --- a/docs/source/customization/guardrails.md +++ b/docs/source/customization/guardrails.md @@ -52,7 +52,9 @@ Presidio analyzer and anonymizer import, `en_core_web_lg` is installed, and emai ## Configuration Shape The guardrails configuration is placed in the top-level `middleware` section. Defining an entry makes that middleware -available; attach it to the workflow or function that should be guarded. The `guardrails` block uses NAT/NeMo +available; attach it to the workflow or function that should be guarded, and use its `workflow_functions` block to +select which fields it evaluates. Attaching a middleware without a matching `workflow_functions` selection resolves to +zero guarded fields, so the boundary appears configured but is not enforced. The `guardrails` block uses NAT/NeMo Guardrails configuration. Refer to `configs/config_web_default_guardrails.yml` for the full field-selection paths used by each boundary. @@ -60,11 +62,25 @@ each boundary. middleware: workflow_guardrails: _type: workflow_guardrails + workflow_functions: + "": + choices: + - message.content guardrails: # NeMo Guardrails configuration. shallow_agent_guardrails: _type: shallow_agent_guardrails + workflow_functions: + shallow_research_agent: + pre_invoke: + messages: + HumanMessage: + - content + post_invoke: + messages: + AIMessage: + - content guardrails: # NeMo Guardrails configuration. diff --git a/docs/source/customization/mcp-tools.md b/docs/source/customization/mcp-tools.md index 57fcc73dd..d2597d6d1 100644 --- a/docs/source/customization/mcp-tools.md +++ b/docs/source/customization/mcp-tools.md @@ -289,8 +289,12 @@ For the broader auth context (UI sign-in flow, validator registration, headless Use per-user MCP OAuth when each AIQ user must authorize the upstream MCP server with their own identity. The reference configuration is [`configs/config_web_frag_mcp_auth.yml`](../../../configs/config_web_frag_mcp_auth.yml). It combines -an OAuth-protected data source, NAT's `per_user_mcp_client`, an `mcp_oauth2` provider, and a shared -token object store. +an OAuth-protected data source (declared with a `per_user_auth` block), an `mcp_oauth2` authentication +provider, and a shared token object store. The config deliberately does **not** declare a +`per_user_mcp_client` function group: AIQ builds the per-user MCP client in code, per job, from the +`mcp_oauth2` provider's server URL and the signed-in user's stored token. A config-declared +`per_user_mcp_client` is built by NAT's interactive-session builder, which fails for a user with no +token and breaks the interactive WebSocket chat path. Set these values before starting AIQ: @@ -338,8 +342,18 @@ for protocol details. - Store secrets in environment variables or a secret manager, not in YAML checked into source control. - Use service-account MCP auth only when shared app-level access is acceptable. -- Use `per_user_auth: true` for upstream MCP OAuth; `requires_auth: true` only gates a source on - AIQ sign-in and does not authorize the upstream MCP server. +- Use a nested `per_user_auth` block (the `PerUserAuthConfig` object, not a bare boolean) for upstream + MCP OAuth; `requires_auth: true` only gates a source on AIQ sign-in and does not authorize the + upstream MCP server: + + ```yaml + per_user_auth: + required: true # gate job submission until the user connects + provider: google # provider identifier + mcp_server_id: gdrive # key used to look up the user's token in NAT token storage + auth_provider: mcp_oauth2_gdrive # the `authentication` (mcp_oauth2) provider for this source + ``` + - Keep token forwarding scoped to trusted internal services and HTTPS endpoints. - Use `requires_auth: true` for sources that depend on AIQ sign-in but do not have a separate upstream OAuth connection. diff --git a/skills/aiq-deploy/SKILL.md b/skills/aiq-deploy/SKILL.md index 7bb611d75..b7f4ad490 100644 --- a/skills/aiq-deploy/SKILL.md +++ b/skills/aiq-deploy/SKILL.md @@ -9,7 +9,7 @@ compatibility: | Python 3.11+ and uv for local process or CLI mode, Node.js 20+ and npm for local web UI mode, or kubectl 1.28+ and Helm 3.12+ for Kubernetes and Helm mode. metadata: - version: "2.1.0" + version: "2.2.0" author: "NVIDIA AI-Q Blueprint Team " github-url: "https://github.com/NVIDIA-AI-Blueprints/aiq" tags: @@ -172,7 +172,7 @@ generation quality. ## Version Compatibility -**IMPORTANT:** This skill is designed for NVIDIA AI-Q Blueprint version 2.1.0. +**IMPORTANT:** This skill is designed for NVIDIA AI-Q Blueprint version 2.2.0. Semantic Versioning Compatibility Rules: @@ -188,11 +188,11 @@ Compatible IF: Examples: -- Skill version 2.1.0 is compatible with Blueprint version 2.1.0. -- Skill version 2.1.0 is compatible with Blueprint version 2.2.0. -- Skill version 2.1.0 is compatible with Blueprint version 2.1.5. -- Skill version 2.1.0 is not compatible with Blueprint version 3.0.0. -- Skill version 2.1.0 is not compatible with Blueprint version 2.0.0. +- Skill version 2.2.0 is compatible with Blueprint version 2.2.0. +- Skill version 2.2.0 is compatible with Blueprint version 2.3.0. +- Skill version 2.2.0 is compatible with Blueprint version 2.2.5. +- Skill version 2.2.0 is not compatible with Blueprint version 3.0.0. +- Skill version 2.2.0 is not compatible with Blueprint version 2.1.0. If your Blueprint version is not compatible: diff --git a/skills/aiq-research/SKILL.md b/skills/aiq-research/SKILL.md index 670d8249c..25bd10302 100644 --- a/skills/aiq-research/SKILL.md +++ b/skills/aiq-research/SKILL.md @@ -13,7 +13,7 @@ compatibility: | access to a running local AI-Q Blueprint server at `http://localhost:8000` by default. Non-local backends must be explicitly trusted by the user and granted by the host tool outside this public skill. metadata: - version: "2.1.0" + version: "2.2.0" author: "NVIDIA AI-Q Blueprint Team " github-url: "https://github.com/NVIDIA-AI-Blueprints/aiq" tags: @@ -211,7 +211,7 @@ citations and source URLs intact in every follow-up answer. ## Version Compatibility -**IMPORTANT:** This skill is designed for NVIDIA AI-Q Blueprint version 2.1.0. +**IMPORTANT:** This skill is designed for NVIDIA AI-Q Blueprint version 2.2.0. Semantic Versioning Compatibility Rules: @@ -227,11 +227,11 @@ Compatible IF: Examples: -- Skill version 2.1.0 is compatible with Blueprint version 2.1.0. -- Skill version 2.1.0 is compatible with Blueprint version 2.2.0. -- Skill version 2.1.0 is compatible with Blueprint version 2.1.5. -- Skill version 2.1.0 is not compatible with Blueprint version 3.0.0. -- Skill version 2.1.0 is not compatible with Blueprint version 2.0.0. +- Skill version 2.2.0 is compatible with Blueprint version 2.2.0. +- Skill version 2.2.0 is compatible with Blueprint version 2.3.0. +- Skill version 2.2.0 is compatible with Blueprint version 2.2.5. +- Skill version 2.2.0 is not compatible with Blueprint version 3.0.0. +- Skill version 2.2.0 is not compatible with Blueprint version 2.1.0. If your Blueprint version is not compatible: @@ -395,7 +395,7 @@ source URLs intact. python3 $SKILL_DIR/scripts/aiq.py agents ``` 2. If agents are unavailable, report the compatibility failure and offer to run `aiq-deploy` validation. -3. Confirm the deployed Blueprint version is compatible with skill version 2.1.0. +3. Confirm the deployed Blueprint version is compatible with skill version 2.2.0. ### Issue: Job is interrupted or appears stuck