Skip to content

feat: add azd ai agent connection commands + credential resolution in run#8174

Merged
Nathandrake229 merged 16 commits into
mainfrom
naman/azd-ai-connection-impl
May 15, 2026
Merged

feat: add azd ai agent connection commands + credential resolution in run#8174
Nathandrake229 merged 16 commits into
mainfrom
naman/azd-ai-connection-impl

Conversation

@Nathandrake229
Copy link
Copy Markdown
Contributor

@Nathandrake229 Nathandrake229 commented May 14, 2026

Summary

Adds azd ai agent connection commands for managing Foundry project connections, and credential reference resolution in azd ai agent run.

Design spec: #8138
Namespace issue: #8166
PM spec: coreai-microsoft/foundrysdk_specs#165

New Commands

azd ai agent connection list

List all connections in the Foundry project.

Flags:
  --kind string              Filter by connection kind (e.g., RemoteTool, ApiKey)
  -p, --project-endpoint     Foundry project endpoint URL
  -o, --output               Output format: table (default), json

azd ai agent connection show <name>

Show connection details. Metadata only by default.

Flags:
  --show-credentials         Fetch credential values from the data plane
  -p, --project-endpoint     Foundry project endpoint URL
  -o, --output               Output format: table (default), json

When --show-credentials is used, output includes credential reference strings for agent.yaml:

Credential References (for agent.yaml):
  x-api-key: ${{connections.my-conn.credentials.x-api-key}}

azd ai agent connection create <name>

Create a new connection. Fails if connection already exists unless --force is used.

Flags:
  --kind string              Connection kind (e.g., remote-tool, cognitive-search, api-key)
  --target string            Target URL or ARM resource ID
  --auth-type string         Auth type: api-key, custom-keys, none (default: none)
  --key string               API key value (for api-key auth)
  --custom-key stringArray   Custom key=value pair (repeatable, for custom-keys auth)
  --metadata stringArray     Metadata key=value pair (repeatable)
  --force                    Replace existing connection (upsert via ARM PUT)
  -p, --project-endpoint     Foundry project endpoint URL

Examples:

# api-key connection
azd ai agent connection create my-search \
  --kind cognitive-search \
  --target https://my-search.search.windows.net/ \
  --auth-type api-key --key "abc123"

# custom-keys connection (e.g., MCP tool with API key header)
azd ai agent connection create my-tavily \
  --kind remote-tool \
  --target https://mcp.tavily.com/mcp \
  --auth-type custom-keys --custom-key "x-api-key=tvly-abc123"

# no-auth connection
azd ai agent connection create my-public \
  --kind remote-tool \
  --target https://public-mcp.example.com \
  --auth-type none

azd ai agent connection update <name>

Update a connection's target or credential values. Only specified flags are changed; all other fields are preserved (GET-then-PUT merge). Does not accept --auth-type (delete and recreate to change auth type).

Flags:
  --target string            New target URL or ARM resource ID
  --key string               New API key value (for api-key auth)
  --custom-key stringArray   Update custom key=value (repeatable, for custom-keys auth)
  -p, --project-endpoint     Foundry project endpoint URL

Examples:

azd ai agent connection update prod-search --key "$NEW_SEARCH_KEY"
azd ai agent connection update my-conn --target https://new-endpoint.com

azd ai agent connection delete <name>

Delete a connection. Prompts for confirmation unless --force is used.

Flags:
  --force                    Skip confirmation prompt
  -p, --project-endpoint     Foundry project endpoint URL

azd ai agent connection metadata set|remove|list

Manage metadata key-value pairs on a connection. Metadata is organizational data attached to connections (e.g., type: custom_MCP, ApiType: Azure).

azd ai agent connection metadata list <connection-name>
azd ai agent connection metadata set <connection-name> <key=value>
azd ai agent connection metadata remove <connection-name> <key>

azd ai agent connection key list

List credential keys on a connection (fetches from data-plane). Shows actual secret values.

azd ai agent connection key list <connection-name>

Agent Run Enhancement

Credential reference resolution in azd ai agent run

When azd ai agent run starts a local agent, it now scans agent.yaml environment_variables for ${{connections.<name>.credentials.<key>}} patterns, resolves them via the Foundry data-plane API, and injects actual credential values into the spawned agent process.

Example agent.yaml:

environment_variables:
  - name: TAVILY_API_KEY
    value: "${{connections.my-conn.credentials.x-api-key}}"

At azd ai agent run time, the extension fetches the credential from the Foundry project and sets TAVILY_API_KEY=<actual-secret> in the agent process.

This is additive — existing env var handling (${VAR} references, FOUNDRY_* translations) is unchanged.

Architecture

  • Connection code in internal/connections/ — self-contained, no agent imports, easy to lift-and-shift
  • Hybrid API: ARM SDK (armcognitiveservices.ProjectConnectionsClient) for CRUD, data-plane (POST getConnectionWithCredentials) for credential fetch
  • ARM PUT requires credentials but ARM GET never returns them — rebuildAndPutConnection helper fetches credentials from data-plane before every PUT (used by update, metadata set, metadata remove)
  • ARM context discovery via data-plane bootstrap GET (extracts subscription/rg from connection id field)
  • 5-level project endpoint resolution: -p flag > azd env > global config > env var > error
  • Commands under azd ai agent connection until core namespace change lands ([Agents Extension] azd ai connection commands — blocked by namespace prefix conflict #8166)

Files changed

New files (connection commands):

  • internal/connections/cmd/root.go — connection subcommand group with -p flag
  • internal/connections/cmd/endpoint.go — endpoint resolution + ARM discovery
  • internal/connections/cmd/context.go — shared connection context (ARM + data-plane clients)
  • internal/connections/cmd/connection.go — list, show, create, update, delete + helpers
  • internal/connections/cmd/connection_metadata.go — metadata set, remove, list
  • internal/connections/cmd/connection_key.go — key set, remove, list
  • internal/connections/pkg/connections/models.go — Connection, ConnectionCredentials types
  • internal/connections/pkg/connections/data_client.go — data-plane client
  • internal/connections/exterrors/errors.go — structured error factories
  • internal/connections/exterrors/codes.go — error codes

New files (agent run enhancement):

  • internal/cmd/connection_credentials.go — scans manifest for connection refs, resolves via data-plane

Modified files:

  • internal/cmd/root.go — adds connection subcommand (one line)
  • internal/cmd/run.go — adds credential resolution step after existing env var loading
  • go.mod / go.sum — adds armcognitiveservices SDK dependency

Naman Tyagi and others added 6 commits May 13, 2026 19:48
Add connection CRUD commands as a sibling subcommand group under azd ai:
- azd ai connection list (ARM with server-side category filter)
- azd ai connection show (ARM metadata + optional data-plane credentials)
- azd ai connection create (ARM PUT with --force upsert, pre-check GET)
- azd ai connection delete (ARM DELETE with confirmation prompt)

Architecture:
- Extension namespace changed from ai.agent to ai
- Connection code in internal/connections/ (self-contained, no agent imports)
- Hybrid API: ARM SDK for CRUD, data-plane for credential fetch
- 5-level project endpoint resolution cascade
- ARM context discovery via data-plane bootstrap GET
- Credential reference strings in show output for agent.yaml

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
During local agent startup, scan the agent manifest environment_variables
for connection reference patterns, fetch credentials from the Foundry
data plane via POST getConnectionWithCredentials, and inject resolved
values into the spawned agent process environment.

- Reads agent.manifest.yaml / agent.yaml from the project directory
- Matches pattern and resolves via data-plane API
- Caches per connection name to avoid redundant API calls
- Logs key names only, never credential values
- Fails gracefully with a warning if resolution fails

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Revert namespace change from ai to ai.agent. Connection commands now live
at azd ai agent connection until the azd core namespace change lands.

Per Travis: write commands under azd ai agent for now, keep code in
separate files/packages for easy lift-and-shift when Jeffrey's core
change is ready.

Changes:
- Revert extension.yaml namespace to ai.agent
- Revert main.go to original import
- Add connection command to existing cmd/root.go NewRootCommand
- Remove unused internal/root.go and exported SetupDebugLogging

The connection code stays self-contained in internal/connections/
with no imports from internal/cmd/ (agent code).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The data-plane getConnectionWithCredentials API returns credentials as
flat key-value pairs alongside the type field, not nested under a keys
sub-object. Fix ConnectionCredentials to parse raw JSON correctly:
- ApiKey: extracts "key" field
- CustomKeys: extracts all non-type fields as custom keys
- Fix JSON output double-nesting (credentials.credentials)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The connection credential resolver now handles both file formats:
- agent.manifest.yaml (AgentManifest with template wrapper)
- agent.yaml (ContainerAgent without wrapper)

Finds first file with environment_variables, parses both formats.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The credential resolver now specifically looks for files containing
the connection reference pattern, and checks agent.yaml first since
that is the file the agent app code references directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The requirement spec (PR #165) uses kebab-case for enum values:
api-key, custom-keys, none (not ApiKey, CustomKeys, None).

Updated --auth-type default, switch cases, help text, and examples.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Nathandrake229 Nathandrake229 marked this pull request as ready for review May 14, 2026 07:41
Copilot AI review requested due to automatic review settings May 14, 2026 07:41
Per the requirement spec (PR #165):
- update: partial merge via GET-then-PUT (--target, --key, --custom-key)
- metadata set/remove/list: manage metadata key-value pairs
- key set/remove/list: manage credential keys via data-plane

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds Foundry project connection management commands to the azure.ai.agents extension and enhances azd ai agent run to resolve ${{connections.<name>.credentials.<key>}} references from agent.yaml at runtime via the Foundry data-plane API.

Changes:

  • Introduces azd ai agent connection {list,show,create,delete} command group backed by ARM CRUD + data-plane credential fetch.
  • Adds a data-plane client + models and a small structured error helper package for the new connection commands.
  • Updates azd ai agent run to scan the agent manifest for connection credential references and inject resolved secrets into the spawned agent process environment.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 15 comments.

Show a summary per file
File Description
cli/azd/extensions/azure.ai.agents/internal/connections/pkg/connections/models.go Adds connection/credential models and a helper to parse credential payloads.
cli/azd/extensions/azure.ai.agents/internal/connections/pkg/connections/data_client.go Adds a Foundry data-plane client for listing connections and fetching credentials.
cli/azd/extensions/azure.ai.agents/internal/connections/exterrors/errors.go Adds helpers to build structured extension errors and map Azure SDK errors.
cli/azd/extensions/azure.ai.agents/internal/connections/exterrors/codes.go Defines error codes and operation names used by the connections feature.
cli/azd/extensions/azure.ai.agents/internal/connections/cmd/root.go Wires the connection subcommand group and shared --project-endpoint flag.
cli/azd/extensions/azure.ai.agents/internal/connections/cmd/endpoint.go Implements project endpoint resolution and ARM context discovery.
cli/azd/extensions/azure.ai.agents/internal/connections/cmd/context.go Creates shared connection context (ARM + data-plane clients, credential creation).
cli/azd/extensions/azure.ai.agents/internal/connections/cmd/connection.go Implements list/show/create/delete command handlers and output formatting.
cli/azd/extensions/azure.ai.agents/internal/cmd/connection_credentials.go Adds agent.yaml scanning + credential reference resolution for run.
cli/azd/extensions/azure.ai.agents/internal/cmd/run.go Calls connection credential resolution and injects resolved secrets into env.
cli/azd/extensions/azure.ai.agents/internal/cmd/root.go Registers the new connection command group on the extension root.
cli/azd/extensions/azure.ai.agents/go.mod Adds ARM SDK dependency needed by the new connection commands.
cli/azd/extensions/azure.ai.agents/go.sum Updates dependency checksums for the new ARM SDK module.

Comment thread cli/azd/extensions/azure.ai.agents/internal/connections/pkg/connections/models.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/connections/cmd/endpoint.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/run.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/run.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/connections/cmd/endpoint.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/go.mod Outdated
ARM PUT rejects bodies without credentials for CustomKeys/ApiKey auth.
ARM GET never returns credentials. Solution: always fetch credentials
from data-plane before PUTting back.

Added rebuildAndPutConnection helper used by update, metadata set,
and metadata remove commands.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@Nathandrake229 Nathandrake229 enabled auto-merge (squash) May 14, 2026 09:14
Naman Tyagi and others added 4 commits May 14, 2026 15:03
Review fixes:
- Remove RawFields JSON tag (fixes double nesting)
- Add pagination to ListConnections
- Use errors.AsType in ServiceFromAzure
- Fix error suggestion to reference existing commands
- Add nil check on props in show command
- Add normalizeKind mapping (kebab-case CLI to PascalCase ARM)
- Add input validation for create (kind, target, key)
- Add warning for malformed key=value pairs
- Align YAML import with agent_yaml package
- Check both AZURE_AI_PROJECT_ENDPOINT and FOUNDRY_PROJECT_ENDPOINT
- Add TODO for tests and env var docs
- Break long lines for lll linter

CI fixes:
- Run go fix for modernizations
- Add tavily/tvly to cspell config

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Use the existing resolveAgentEndpoint function for credential resolution
endpoint discovery instead of hardcoding AZURE_AI_PROJECT_ENDPOINT and
FOUNDRY_PROJECT_ENDPOINT key names.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- gofmt: fix formatting in exterrors/codes.go
- gosec G304: add nolint comments for os.ReadFile on known project paths
- cspell: rename connectioncmd alias to conncmd to avoid unknown word

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 14, 2026

📋 Prioritization Note

Thanks for the contribution! The linked issue isn't in the current milestone yet.
Review may take a bit longer — reach out to @rajeshkamal5050 or @kristenwomack if you'd like to discuss prioritization.

Copy link
Copy Markdown
Member

@trangevi trangevi left a comment

Choose a reason for hiding this comment

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

Please add tests

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/connection_credentials.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/connections/cmd/connection.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/connections/cmd/connection_key.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/connections/cmd/connection_key.go Outdated
Naman Tyagi and others added 2 commits May 15, 2026 03:00
- Refactor all connection commands (list, show, create, update, delete)
  to use the Action pattern: RunE validates inputs, action struct runs.
- Remove cobra.Command dependency from resolveProjectEndpoint and
  resolveConnectionContext for better testability.
- Remove stub 'key remove' command (not yet supported by ARM API).
- Remove TODO comment in connection_credentials.go (replaced by tests).
- Add TODO to unify endpoint resolution with project set/unset commands.
- Extract extractConnectionRefs and lookupCredentialValue as testable
  pure functions from resolveConnectionCredentials.
- Add unit tests for: parseEndpointComponents, parseARMResourceID,
  normalizeKind, normalizeAuthType, parseKVPtrMap, buildCredentialReferences,
  ParseCredentials, extractConnectionRefs, lookupCredentialValue,
  findManifestInDir, connectionRefPattern.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Remove connection key and metadata subcommands as agreed by
@therealjohn and @trangevi — these are redundant with
'connection show --show-credentials' and 'connection update --metadata'.

Removes: connection_key.go, connection_metadata.go, rebuildAndPutConnection
helper, and unused operation codes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread cli/azd/.vscode/cspell.yaml Outdated
Extension-specific words (conncmd, tavily, tvly) belong in the
extension's own cspell.yaml, not the core cli/azd/.vscode/cspell.yaml.
The extension config already has these words.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@trangevi
Copy link
Copy Markdown
Member

/check-enforcer override

@JeffreyCA
Copy link
Copy Markdown
Contributor

@microsoft-github-policy-service rerun

@Nathandrake229 Nathandrake229 merged commit fdae616 into main May 15, 2026
21 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add azd ai connection create/update/show/list to manage Foundry Connections

5 participants