Skip to content

feat: add granular per-session flags for multitenancy hardening#1474

Merged
MackinnonBuck merged 12 commits into
mainfrom
mackinnonbuck/sdk-granular-multitenancy-flags
May 28, 2026
Merged

feat: add granular per-session flags for multitenancy hardening#1474
MackinnonBuck merged 12 commits into
mainfrom
mackinnonbuck/sdk-granular-multitenancy-flags

Conversation

@MackinnonBuck
Copy link
Copy Markdown
Collaborator

@MackinnonBuck MackinnonBuck commented May 27, 2026

Summary

Add 8 new optional fields to SessionConfigBase across all 6 SDK languages (Node.js, Go, Python, .NET, Rust, Java) for granular per-session control of host-level features in multitenant deployments.

Fixes https://github.com/github/copilot-agent-runtime/issues/7156

New fields

Field Type Purpose
skipEmbeddingRetrieval boolean? Prevent cross-session info leakage via shared embedding cache
organizationCustomInstructions string? Inject org-level custom instructions into system prompt
enableOnDemandInstructionDiscovery boolean? Control instruction file discovery after file views
enableFileHooks boolean? Control loading of file-based hooks from .github/hooks/
enableHostGitOperations boolean? Control git operations on host filesystem
enableSessionStore boolean? Control cross-session store for search/retrieval
enableSkills boolean? Control skill loading (builtin + discovered)
embeddingCacheStorage string? Control embedding cache storage strategy ("persistent" or "in-memory")

Design decisions

  • All fields are optional -- undefined/nil/null/None means "use runtime default"
  • No SDK-side default coercion -- values pass through directly to the runtime
  • Empty mode applies restrictive defaults (skipEmbeddingRetrieval: true, all enable*: false, embeddingCacheStorage: "in-memory") for secure multitenant deployments
  • organizationCustomInstructions has no empty-mode default (it's host-supplied content, not a toggle)

Changes per language

  • Node.js: types.ts (interface), client.ts (wire + empty defaults), toolSet.test.ts (5 new tests)
  • Go: types.go (structs), client.go (wire), mode_empty.go (defaults), toolset_test.go (3 new tests)
  • Python: client.py (params + wire), _mode.py (defaults), test_tool_set.py (tests)
  • .NET: Types.cs (properties), Client.cs (wire + defaults), ClientOptionsE2ETests.cs (tests)
  • Rust: types.rs (structs + builders), wire.rs (wire structs), session.rs (mapping)
  • Java: SessionConfig.java, CreateSessionRequest.java, ResumeSessionRequest.java, ResumeSessionConfig.java, SessionRequestBuilder.java (wiring), CopilotClient.java (empty-mode defaults)

Testing

  • All 6 SDKs compile cleanly
  • Go unit tests pass
  • Node.js, .NET, Python validated via compilation/import checks

Add 7 new optional fields to SessionConfigBase across all 6 SDK languages
(Node.js, Go, Python, .NET, Rust, Java):

- skipEmbeddingRetrieval: prevent cross-session info leakage via embedding cache
- organizationCustomInstructions: inject org-level instructions into system prompt
- enableOnDemandInstructionDiscovery: control instruction file discovery after file views
- enableFileHooks: control loading of file-based hooks from .github/hooks/
- enableHostGitOperations: control git operations on host filesystem
- enableSessionStore: control cross-session store for search/retrieval
- enableSkills: control skill loading (builtin + discovered)

All fields are optional and pass through to the runtime without SDK-side
default coercion. Empty mode applies restrictive defaults for multitenancy.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 27, 2026 23:53
@MackinnonBuck MackinnonBuck requested a review from a team as a code owner May 27, 2026 23:53
@MackinnonBuck MackinnonBuck marked this pull request as draft May 27, 2026 23:55
@MackinnonBuck MackinnonBuck changed the title feat: add granular per-session flags for multitenancy hardening (#7156) feat: add granular per-session flags for multitenancy hardening May 27, 2026
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 a set of optional, per-session “granular multitenancy” flags across all SDKs to let hosts selectively disable host-level features (embedding retrieval, instruction discovery, file hooks, git ops, session store, skills) and to optionally inject organization-scoped instructions, with restrictive safe-defaults applied in “empty” mode.

Changes:

  • Introduces 7 new session config fields and wires them through session.create / session.resume payloads across Node.js, Go, Python, .NET, Rust, and Java.
  • Applies “empty” mode restrictive defaults for the new flags (skip embeddings on; enable* off) while preserving caller overrides.
  • Adds/extends tests (notably Node/Go/.NET/Java) to validate defaulting and wire propagation.
Show a summary per file
File Description
rust/src/wire.rs Extends Rust create/resume wire structs with the new optional fields (camelCase on the wire).
rust/src/types.rs Adds new config fields, defaults, builders, and wires them into into_wire for create/resume.
rust/src/session.rs Applies “empty” mode restrictive defaults for the new flags during create/resume.
python/test_tool_set.py Updates test imports for new empty-mode default helpers (currently introduces unused imports).
python/copilot/client.py Adds new kwargs, empty-mode defaulting, and JSON payload fields for create/resume.
python/copilot/_mode.py Factors out a generic empty-mode default helper and adds new defaulting functions.
nodejs/test/toolSet.test.ts Adds tests covering empty-mode defaults, overrides, pass-through, and resume behavior.
nodejs/src/types.ts Adds new SessionConfigBase fields and JSDoc describing the flags.
nodejs/src/client.ts Applies empty-mode defaults and forwards new fields on create/resume requests.
java/src/test/java/com/github/copilot/SessionRequestBuilderTest.java Adds tests verifying propagation of new fields into create/resume requests.
java/src/test/java/com/github/copilot/OptionalApiAndJacksonTest.java Adds tests validating Optional/null behavior for the new config fields.
java/src/test/java/com/github/copilot/ConfigCloneTest.java Adds tests ensuring clone preserves the new fields.
java/src/main/java/com/github/copilot/SessionRequestBuilder.java Wires new config fields into create/resume request builders.
java/src/main/java/com/github/copilot/rpc/SessionConfig.java Adds new config fields + fluent accessors/clearers, and clone support.
java/src/main/java/com/github/copilot/rpc/ResumeSessionConfig.java Adds new resume config fields + fluent accessors/clearers, and clone support.
java/src/main/java/com/github/copilot/rpc/CreateSessionRequest.java Adds new wire fields with Jackson annotations + accessors.
java/src/main/java/com/github/copilot/rpc/ResumeSessionRequest.java Adds new wire fields with Jackson annotations + accessors.
go/types.go Adds new config fields and wire request fields for create/resume.
go/toolset_test.go Adds tests for empty-mode defaults, override precedence, and non-empty mode behavior.
go/mode_empty.go Applies empty-mode defaults for the new flags on create and resume configs.
go/client.go Forwards new config fields into the create/resume wire requests.
dotnet/test/E2E/ClientOptionsE2ETests.cs Adds E2E assertions for create/resume wire propagation and empty-mode defaults.
dotnet/src/Types.cs Adds new per-session config properties and copy-constructor propagation.
dotnet/src/Client.cs Applies empty-mode defaults and forwards new fields into create/resume request records.

Copilot's findings

  • Files reviewed: 24/24 changed files
  • Comments generated: 7

Comment thread python/test_tool_set.py
Comment thread rust/src/types.rs
Comment thread rust/src/types.rs
Comment thread nodejs/src/types.ts
Comment thread go/types.go Outdated
Comment thread go/types.go
Comment thread go/types.go Outdated
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for issue #1474 · ● 5.1M

Comment thread go/types.go Outdated
Copy link
Copy Markdown
Contributor

@SteveSandersonMS SteveSandersonMS left a comment

Choose a reason for hiding this comment

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

Great! Thanks for getting all these in.

Some of the CCR comments look valid - approving now to keep things unblocked.

- Go: change OrganizationCustomInstructions to *string for cross-SDK consistency
- Go: clarify *bool field docs (nil = runtime default, non-nil = forwarded)
- Rust: redact organization_custom_instructions in Debug impls
- Node.js: clarify JSDoc defaults apply only in empty mode
- Python: replace unused imports with parametrized tests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@MackinnonBuck MackinnonBuck marked this pull request as ready for review May 28, 2026 19:54
Merge origin/main into feature branch. Conflicts resolved in:
- dotnet/src/Types.cs: added EnableMcpApps alongside our 7 new fields
- go/types.go: merged wire structs with new fields from both sides
  (ReasoningSummary, PluginDirectories, LargeOutput, RequestMcpApps from main)
- rust/src/types.rs: merged enable_mcp_apps field and builder methods
  alongside our 7 granular multitenancy fields
- java SessionRequestBuilderTest: kept both our new tests and main's new tests

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

This comment has been minimized.

MackinnonBuck and others added 2 commits May 28, 2026 13:59
Adds embeddingCacheStorage field ("persistent" | "in-memory") to session
create and resume across all 6 SDKs. In empty mode, defaults to "in-memory"
for multitenant isolation. Companion to runtime PR #8388.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…nular-multitenancy-flags

# Conflicts:
#	dotnet/src/Client.cs
#	go/mode_empty.go
#	go/toolset_test.go
#	go/types.go
#	java/src/main/java/com/github/copilot/CopilotClient.java
#	java/src/test/java/com/github/copilot/SessionRequestBuilderTest.java
#	nodejs/src/client.ts
#	python/copilot/_mode.py
#	python/copilot/client.py
@github-actions

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for issue #1474 · ● 5.4M

Comment thread python/copilot/client.py
… improve tests

- Run formatters across all SDKs (prettier, gofmt, ruff, cargo fmt, spotless, dotnet format)
- Convert EmbeddingCacheStorage from string to EmbeddingCacheStorageMode enum in .NET
- Rename test methods to avoid temporal wording
- Expand EnableFileHooks doc comment in Go ResumeSessionConfig
- Add embeddingCacheStorage test coverage in Go, Java

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

This comment has been minimized.

MackinnonBuck and others added 2 commits May 28, 2026 15:24
Simplify doc comments across all SDKs to focus on user-facing behavior
rather than SDK-to-runtime interaction details. Removes boilerplate like
'When nil, the runtime default is used. When non-nil, the value is passed
through to the runtime.' in favor of concise, behavior-focused docs that
match the existing style of other properties.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Rename to use 'granularMultitenancyFields' instead of 'newSessionFields'
for consistency with .NET and Node.js test naming.

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

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for issue #1474 · ● 7.2M

Comment thread java/src/main/java/com/github/copilot/CopilotClient.java
MackinnonBuck and others added 2 commits May 28, 2026 15:36
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The Cross-SDK Consistency Review identified that Java was only applying
embeddingCacheStorage and mcpOAuthTokenStorage in empty mode, but missing
the 6 boolean flags (skipEmbeddingRetrieval, enableOnDemandInstructionDiscovery,
enableFileHooks, enableHostGitOperations, enableSessionStore, enableSkills).

Also adds embeddingCacheStorage assertion to Node.js empty-mode test for
coverage parity with Go and .NET.

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

This comment has been minimized.

Copy link
Copy Markdown
Contributor

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

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

Generated by SDK Consistency Review Agent for issue #1474 · ● 7.5M

Comment thread rust/src/types.rs
Comment thread rust/src/types.rs
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.

Copilot's findings

  • Files reviewed: 25/25 changed files
  • Comments generated: 4

Comment thread rust/src/types.rs
Comment thread rust/src/types.rs
Comment thread rust/src/types.rs
Comment thread rust/src/types.rs
Add the missing embedding_cache_storage field to:
- SessionConfig custom Debug impl
- ResumeSessionConfig custom Debug impl
- SessionConfig fluent builder (with_embedding_cache_storage)
- ResumeSessionConfig fluent builder (with_embedding_cache_storage)

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.

Copilot's findings

  • Files reviewed: 25/25 changed files
  • Comments generated: 4

Comment thread dotnet/test/E2E/ClientOptionsE2ETests.cs
Comment thread dotnet/test/E2E/ClientOptionsE2ETests.cs
Comment thread java/src/main/java/com/github/copilot/rpc/ResumeSessionConfig.java Outdated
Comment thread java/src/main/java/com/github/copilot/rpc/ResumeSessionConfig.java Outdated
- Add BaseDirectory and AvailableTools to .NET empty-mode default tests
  so they don't throw at client construction time
- Fix enableConfigDiscovery Javadoc in ResumeSessionConfig: use
  Optional.empty() instead of null in @return, remove null from @param
  (setter takes primitive boolean)
- Fix stale 'runtime default' wording in SessionConfig.java getter

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

✅ Cross-SDK Consistency Review

This PR maintains excellent consistency across all 6 SDK implementations. Here's a summary of the cross-language review:

Fields added uniformly across all SDKs

Field Node.js Python Go .NET Rust Java
skipEmbeddingRetrieval
embeddingCacheStorage
organizationCustomInstructions
enableOnDemandInstructionDiscovery
enableFileHooks
enableHostGitOperations
enableSessionStore
enableSkills

Naming conventions followed correctly

  • Node.js/Java: camelCase (skipEmbeddingRetrieval, embeddingCacheStorage)
  • Python/Rust: snake_case (skip_embedding_retrieval, embedding_cache_storage)
  • Go/.NET: PascalCase (SkipEmbeddingRetrieval, EmbeddingCacheStorage)

Empty-mode defaults consistent across all SDKs

All SDKs apply the same restrictive defaults in empty mode:

  • skipEmbeddingRetrieval: true
  • embeddingCacheStorage: "in-memory"
  • All enable* flags: false
  • organizationCustomInstructions: no default (pass-through only)

Wire serialization consistent

All SDKs serialize field names as camelCase JSON keys, matching the expected protocol format (skipEmbeddingRetrieval, embeddingCacheStorage, etc.).

No cross-SDK consistency issues found. 🎉

Generated by SDK Consistency Review Agent for issue #1474 · ● 5.5M ·

@MackinnonBuck MackinnonBuck added this pull request to the merge queue May 28, 2026
Merged via the queue into main with commit 60dac9d May 28, 2026
44 checks passed
@MackinnonBuck MackinnonBuck deleted the mackinnonbuck/sdk-granular-multitenancy-flags branch May 28, 2026 23:34
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.

3 participants