Skip to content

Support header isolation keys for agent sessions#8206

Open
glharper wants to merge 2 commits into
mainfrom
glharper/ai-agent-isolation-headers
Open

Support header isolation keys for agent sessions#8206
glharper wants to merge 2 commits into
mainfrom
glharper/ai-agent-isolation-headers

Conversation

@glharper
Copy link
Copy Markdown
Member

@glharper glharper commented May 15, 2026

Summary

  • add --user-isolation-key and --chat-isolation-key to session-level Azure AI Agents commands
  • propagate the Foundry isolation headers through invoke, monitor, files, and sessions APIs
  • preserve existing --isolation-key behavior for session ownership headers

Tests

  • go test .\... -count=1

Fixes #8154

Add user and chat isolation key flags to session-level agent commands and propagate them through invoke, monitor, files, and sessions requests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@glharper glharper marked this pull request as ready for review May 18, 2026 15:47
Copilot AI review requested due to automatic review settings May 18, 2026 15:47
@github-actions
Copy link
Copy Markdown

🔗 Linked Issue Required

Thanks for the contribution! Please link a GitHub issue to this PR by adding Fixes #123 to the description or using the sidebar.
No issue yet? Feel free to create one!

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 support for propagating Foundry header-based isolation keys across session-scoped Azure AI Agents operations in the azure.ai.agents extension, while preserving the existing session-ownership isolation key behavior.

Changes:

  • Introduces SessionRequestOptions + well-known header constants in agent_api and threads these options through session lifecycle, files, and log streaming APIs.
  • Adds --user-isolation-key and --chat-isolation-key flags to session-level CLI commands (sessions, invoke, monitor, files) and applies them to outbound requests (including LRO polling and conversation creation).
  • Expands unit tests to validate header propagation across the affected operations and command flag registration.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/operations.go Adds isolation header constants + SessionRequestOptions, and applies headers across session/files/logstream operations.
cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/operations_test.go Adds tests ensuring isolation headers are applied for session lifecycle, file ops, and log streaming.
cli/azd/extensions/azure.ai.agents/internal/cmd/isolation_headers.go New shared flag plumbing for --user-isolation-key / --chat-isolation-key and conversion to request options.
cli/azd/extensions/azure.ai.agents/internal/cmd/session.go Registers isolation header flags on session commands and propagates options to agent API calls.
cli/azd/extensions/azure.ai.agents/internal/cmd/session_test.go Extends tests to assert new isolation flags exist with correct defaults.
cli/azd/extensions/azure.ai.agents/internal/cmd/monitor.go Adds isolation header flags and passes options to session log streaming.
cli/azd/extensions/azure.ai.agents/internal/cmd/monitor_test.go Extends tests to assert new isolation flags exist with correct defaults.
cli/azd/extensions/azure.ai.agents/internal/cmd/invoke.go Adds isolation header flags and propagates options through invoke flows (requests, LRO polling, conversation creation).
cli/azd/extensions/azure.ai.agents/internal/cmd/invoke_test.go Adds tests asserting flag registration and propagation through LRO polling and conversation creation.
cli/azd/extensions/azure.ai.agents/internal/cmd/helpers.go Threads session request options into conversation ID resolution and conversation creation.
cli/azd/extensions/azure.ai.agents/internal/cmd/files.go Adds isolation header flags for file operations and propagates options to agent API calls.
cli/azd/extensions/azure.ai.agents/internal/cmd/files_test.go Extends tests to assert new isolation flags exist across file subcommands.
Comments suppressed due to low confidence (1)

cli/azd/extensions/azure.ai.agents/internal/cmd/invoke_test.go:1162

  • This test stores the request pointer in an outer variable from the server handler goroutine and reads it from the test goroutine without synchronization; with t.Parallel() this will be flagged as a race by the race detector. Use a channel to hand the request back to the test (or otherwise synchronize) before making assertions.
func TestCreateConversation_PropagatesIsolationHeaders(t *testing.T) {
	t.Parallel()

	var request *http.Request
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		request = r
		w.WriteHeader(http.StatusOK)
		_, _ = w.Write([]byte(`{"id":"conv-headers"}`))
	}))
	defer srv.Close()

Comment on lines +9 to +11
"azureaiagent/internal/pkg/agents/agent_api"

"github.com/spf13/cobra"
Comment on lines +482 to +488
func TestGetAgentSessionLogStream_ApplyIsolationHeaders(t *testing.T) {
var request *http.Request
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
request = r
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte("event: log\n\n"))
}))
Comment on lines +971 to +981
func TestHandleInvocationLRO_PropagatesIsolationHeaders(t *testing.T) {
origInterval := defaultLROPollInterval
defaultLROPollInterval = time.Millisecond
t.Cleanup(func() { defaultLROPollInterval = origInterval })

var pollRequest *http.Request
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
pollRequest = r
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(`{"status":"completed"}`))
}))
@glharper
Copy link
Copy Markdown
Member Author

@copilot apply changes based on the comments in this thread

Copy link
Copy Markdown
Contributor

Copilot AI commented May 18, 2026

@copilot apply changes based on the comments in this thread

Applied all three review comments in af6d390:

  1. Import grouping in isolation_headers.go: reordered to stdlib → external (github.com/spf13/cobra) → local (azureaiagent/...).
  2. Data race in operations_test.go: replaced the shared var request *http.Request assignment in the httptest handler with a buffered channel (reqCh := make(chan *http.Request, 1)).
  3. Data race in invoke_test.go: same fix applied to both TestHandleInvocationLRO_PropagatesIsolationHeaders and TestCreateConversation_PropagatesIsolationHeaders.

All three tests pass under go test -race.

Copy link
Copy Markdown
Contributor

@wbreza wbreza left a comment

Choose a reason for hiding this comment

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

Supplemental review — focused on what the prior reviewer didn't already cover. Prior race-condition findings stand; please address those.

Test Coverage

LRO polling test only verifies the last poll requestTestHandleInvocationLRO_PropagatesIsolationHeaders (invoke_test.go ~L446–497) overwrites pollRequest on each iteration, so headers are only asserted on the final poll. Recommend pairing this with the race fix already requested: switch to a buffered channel (or mutex-guarded slice) and assert headers on every poll request. That single change resolves the race and tightens the contract.

No partial-set coverage for the new flags — every new test sets both UserIsolationKey and ChatIsolationKey (or neither). Please add cases for user-only and chat-only to lock in the independence of the two headers. ApplyHeaders is implemented correctly today, but a future change that gates one header on the other being set would currently slip through.

Minor

Duplicated test logicTestApplyIsolationHeaders (invoke_test.go ~L396–419) duplicates TestSessionRequestOptions_ApplyHeaders (operations_test.go ~L1170–1185). Consider removing it, or repurposing it to test the CLI-flag-struct → SessionRequestOptions conversion (sessionRequestOptions / sessionRequestOptionsWithSessionKey), which is currently only exercised indirectly through end-to-end tests.

Flag help text disambiguationisolation_headers.go adds --user-isolation-key and --chat-isolation-key alongside the pre-existing --isolation-key. The three names look very similar in --help. Consider noting in the descriptions that the new flags are independent of the session-ownership --isolation-key to reduce CLI confusion.

Looks good

  • Headers are applied consistently across sessions, files, invoke (incl. LRO polling), monitor/log-stream, and conversation creation.
  • SessionRequestOptions.ApplyHeaders is nil-safe and filters empty values.
  • Existing --isolation-key semantics preserved via sessionRequestOptionsWithSessionKey.
  • Header constants are exported with doc comments.
  • No isolation-key values are logged in debug output.

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.

Support sending custom user and chat isolation key headers on session-level azd ai agent commands

4 participants