Skip to content

fix(agents): attach and authenticate every toolboxes reference - #10631

Open
Zhijie Huang (hund030) wants to merge 4 commits into
Azure:mainfrom
hund030:fix/agent-toolboxes-auth
Open

Zhijie Huang (hund030) wants to merge 4 commits into
Azure:mainfrom
hund030:fix/agent-toolboxes-auth

Conversation

@hund030

Copy link
Copy Markdown
Contributor

Summary

Fixes #10621. Referencing toolboxes on a Copilot-harness prompt agent was silently ignored during deployment, while the legacy singular toolbox field attached an unauthenticated MCP URL that failed at runtime with HTTP 401. This change retires singular toolbox and wires every toolboxes entry to an authenticated UserEntraToken project connection and MCP tool attachment.

Changes

  • schemas/azure.ai.agent.json & internal/pkg/agents/agent_yaml: Retire singular toolbox in favor of plural toolboxes ([]ToolboxReference) and reject singular or mixed toolbox/toolboxes configurations with migration guidance.
  • internal/project/prompt_skills.go & prompt_graph.go: Validate each toolboxes service dependency in promptGraph, parse the deployed toolbox name and version from TOOLBOX_<NAME>_MCP_ENDPOINT, create or reuse a compatible <toolboxName>-mcp RemoteTool (UserEntraToken, audience: https://ai.azure.com) connection via ARM, and link project_connection_id on each injected MCP tool.
  • internal/cmd/agent_dependency_plan.go & resource_services.go: Align init and file-backed dependency planning exclusively with plural toolboxes.

Manual Validation

  • Deployed a Copilot-harness prompt agent (harness.type: microsoft_copilot_preview) with one and two azure.ai.toolbox services (web_search) via azd deploy --all --no-prompt in westus2; confirmed via azd ai agent show --output json and ARM GET that <toolbox>-mcp UserEntraToken connections were created/reused and linked via project_connection_id on each MCP tool.
  • Invoked the deployed agent via azd ai agent invoke with built-in Copilot tools disabled (microsoft_copilot_toolset_preview defaultConfig.enabled: false) and confirmed live MCP tool calls succeeded against both attached toolboxes without HTTP 401.
  • Verified azd deploy rejects singular toolbox, mixed toolbox + toolboxes, and missing uses entries with actionable error messages.

- Retire singular `toolbox` in favor of plural `toolboxes` across schema, validation, and dependency planning.
- Resolve each referenced `azure.ai.toolbox` MCP endpoint and version in `promptGraph`, ensure a compatible `UserEntraToken` project connection (`<toolbox>-mcp`), and link `project_connection_id` on each injected MCP tool.
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 2 pipeline(s).
24 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Connection lifecycle, identity resolution, and request replay defects can disrupt existing agents or prevent deployment.

5 open issues
What changed in this PR

Addresses #10621 by wiring plural toolboxes references into authenticated MCP attachments for Copilot-harness prompt agents.

Changes:

  • Retires singular toolbox with migration diagnostics.
  • Resolves deployed toolbox endpoints and creates or reuses authenticated project connections.
  • Updates dependency planning, documentation, and tests.

Paths are relative to cli/azd/extensions/azure.ai.agents/.

File Description
schemas/​azure.ai.agent.json Rejects legacy and unsupported toolbox configurations.
README.md Documents plural toolbox references.
internal/​project/​service_target_agent.go Removes singular dependency wiring.
internal/​project/​prompt_skills.go Resolves toolbox attachments and authenticated connections.
internal/​project/​prompt_skills_test.go Tests connections and multiple attachments.
internal/​project/​prompt_json_schema_test.go Tests plural schema acceptance.
internal/​project/​prompt_inline_test.go Tests parsing, validation, and round trips.
internal/​project/​prompt_graph.go Wires plural references into deployment.
internal/​project/​prompt_connections_test.go Separates toolbox and connection dependencies.
internal/​project/​foundry_dependencies_test.go Removes obsolete singular-helper coverage.
internal/​project/​agent_definition.go Rejects legacy and unsupported fields.
internal/​project/​agent_definition_test.go Updates hosted-agent round-trip coverage.
internal/​pkg/​agents/​agent_yaml/​yaml.go Defines and decodes plural references.
internal/​pkg/​agents/​agent_yaml/​prompt_strict_inline.go Adds singular-field migration errors.
internal/​pkg/​agents/​agent_yaml/​prompt_schema_test.go Tests plural YAML round trips.
internal/​pkg/​agents/​agent_yaml/​parse.go Validates legacy and voice-agent restrictions.
internal/​exterrors/​codes.go Adds toolbox connection operation attribution.
internal/​cmd/​resource_services.go Collects plural toolbox dependencies.
internal/​cmd/​resource_services_test.go Updates dependency wiring tests.
internal/​cmd/​agent_dependency_plan.go Removes singular dependency planning.
internal/​cmd/​agent_dependency_plan_test.go Tests plural planning and legacy rejection.

Review effort: Balanced

Comment thread cli/azd/extensions/azure.ai.agents/internal/project/prompt_skills.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/project/prompt_skills.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/project/prompt_skills.go Outdated
- Reconcile prior toolbox version URLs in `reconcileMcpTool` and use `<toolbox>-v<version>-mcp` when `<toolbox>-mcp` points to another version.
- Resolve ARM account identity from `AZURE_AI_PROJECT_ID`, use replayable `req.SetBody` on connection PUTs, and propagate connection `` errors.
Copilot AI balanced review requested due to automatic review settings October 20, 2026 08:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread cli/azd/extensions/azure.ai.agents/internal/project/prompt_skills.go Outdated
- Disambiguate `server_label` with the service key when multiple `toolboxes` entries share a toolbox resource name and track claimed `Tools` indices across `toolboxNode.Resolve`.
- Require HTTPS Foundry project URLs (`*.services.ai.azure.com/api/projects/<project>/...`) in `parseToolboxMCPEndpoint` before configuring `UserEntraToken` connections.
Copilot AI balanced review requested due to automatic review settings October 20, 2026 09:25
@github-actions github-actions Bot added the ext-foundry azure.ai.{agents,connections,inspector,projects,routines,skills,toolboxes}, microsoft.foundry label Oct 20, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Connection creation and MCP reconciliation still have correctness issues that can break deployed attachments.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Concurrent deployments race on shared toolbox connection names

cli/​azd/​extensions/​azure.ai.agents/​internal/​project/​prompt_skills.go:995

Parallel agent deployments attaching different versions of the same toolbox can both GET 404 for <toolbox>-mcp, then PUT different targets here. Both return that connection name, so the last PUT leaves one agent's server_url mismatched with its connection target. The version-scoped fallback never runs in this interleaving; services without mutual uses edges deploy in parallel (cli/azd/docs/concurrency-model.md:111–116). Use deterministic endpoint-specific names for new connections, or supported atomic create-if-absent behavior with compatibility checking on conflicts. Add coverage for concurrent first deployments.

2 resolved since last review

Review effort: Balanced

Comment thread cli/azd/extensions/azure.ai.agents/internal/project/prompt_skills.go Outdated
Copilot AI balanced review requested due to automatic review settings October 20, 2026 10:24

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Parallel connection creation can overwrite another agent’s target, and preserved aliases can produce duplicate MCP labels.

1 open issue
1 previously missed issue

In code that hasn't changed since last review

Medium severity Parallel deployments can overwrite MCP connection targets

cli/​azd/​extensions/​azure.ai.agents/​internal/​project/​prompt_skills.go:995

The GET-then-PUT sequence can overwrite another agent's connection during parallel deployment. Two agents pinning different versions of the same toolbox can both receive 404 for <toolbox>-mcp, then PUT different targets and return the same connection name. The last write leaves one agent's server_url mismatched with its connection target. The version-scoped fallback only handles connections visible during GET. Services without mutual uses edges deploy in parallel (cli/azd/docs/concurrency-model.md:111–116). Use immutable endpoint-specific names from initial creation, or atomic creation with conflict rechecking, and add an interleaved first-deployment test.

1 resolved since last review

Review effort: Balanced

return err
}
}
return nil
@azure-sdk-automation

Copy link
Copy Markdown
Contributor

azure.ai.agents PR build

Note

This is an unsigned development build. Install it only if you trust this PR.

Install the extension:

azd ext install "https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/pr/10631/azure-ai-agents.zip"
  • Version: 1.0.0-beta.21.pr.10631.6978624
  • Merge commit: 02d379a

return exterrors.Validation(
exterrors.CodeInvalidAgentManifest,
fmt.Sprintf(
"MCP tool %q declares server_url %q, which conflicts with toolbox %q endpoint %q",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[azd-code-reviewer][HIGH] This error includes raw existingURL and mcpURL; the invalid-endpoint path below also prints ref.MCPEndpoint verbatim. These URLs can carry userinfo, SAS/sig query parameters, or fragments from authored or persisted configuration, leaking credentials into terminal and CI logs. Clear URL.User, RawQuery, Fragment, and RawFragment before formatting either error, and add a non-disclosure test with credential-bearing URLs.

if projectConnectionID != "" {
existingConn, has := tool["project_connection_id"]
if !has || strings.TrimSpace(fmt.Sprintf("%v", existingConn)) == "" || urlChanged {
tool["project_connection_id"] = projectConnectionID

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[azd-code-reviewer][HIGH] On an exact server_url match, a non-empty existing project_connection_id is preserved even when it names a missing or incompatible connection. The code has just ensured a UserEntraToken connection in projectConnectionID, but the published tool can keep pointing at stale auth and still fail with 401. Set project_connection_id to the ensured connection for every managed toolbox match while preserving unrelated options, and add coverage where an exact URL starts with a different non-empty connection ID.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ext-agents azure.ai.agents extension ext-foundry azure.ai.{agents,connections,inspector,projects,routines,skills,toolboxes}, microsoft.foundry

Projects

None yet

Development

Successfully merging this pull request may close these issues.

azure.ai.agents: attach and authenticate every toolboxes reference

3 participants