Skip to content

DX-116574: LD multi-context with per-request project and org targeting#89

Merged
aniket-s-kulkarni merged 5 commits into
dremio:mainfrom
aniket-s-kulkarni:feature/ld-multi-context-project-org
Mar 17, 2026
Merged

DX-116574: LD multi-context with per-request project and org targeting#89
aniket-s-kulkarni merged 5 commits into
dremio:mainfrom
aniket-s-kulkarni:feature/ld-multi-context-project-org

Conversation

@aniket-s-kulkarni
Copy link
Copy Markdown
Contributor

@aniket-s-kulkarni aniket-s-kulkarni commented Mar 11, 2026

Summary

  • LD multi-context: FeatureFlagManager._build_context() builds an LD multi-context with application, project, and organization kinds from the current request scope, enabling per-project and per-org flag targeting. Falls back to the existing single "mcp-server" context when neither is available (zero behavioral change for existing deployments).

  • extract_org_id_from_jwt setting: JWT aud extraction is gated behind a new dremio.extract_org_id_from_jwt setting (default false, LD-flaggable). This is the only mechanism to derive the org ID for LD org-based targeting during tool calls — without it there is no way to identify which org is making the request. When enabled, DelegatingTokenVerifier extracts the aud claim from the bearer token JWT (Dremio Cloud sets aud=orgId via TokenServiceImpl). No signature verification — the token is always forwarded to Dremio for real validation; we only read the audience for LD context targeting. Gracefully handles opaque (non-JWT) tokens by returning None.

  • Tenant-scoped OAuth metadata: Added dual route so /mcp/{project_id}/.well-known/oauth-authorization-server resolves to the same handler as the root path. ProjectIdMiddleware extracts the project ID from the URL; Starlette's exact-match Route requires the second registration since the MCP Mount only does prefix matching at /mcp.

  • E2E tests for LD multi-context: 3 new E2E tests verify org_id + project_id flow into the LD context during real tool calls (mock LD client captures variation() contexts). Covers: both IDs present, org-only, and opaque token fallback.

  • Smoke test LD flag check: New --ld-sdk-key, --ld-flag, --ld-expected options on the test command evaluate a real LD flag with the full multi-context (project from URL, org from JWT aud). Asserts that the JWT aud claim contains an orgId before proceeding.

Test plan

  • All 119 existing config tests pass (74 LD + 45 settings)
  • Golden flag keys test updated with dremio.extract_org_id_from_jwt
  • 3 new E2E tests: org_id+project_id in LD context, org_id without project_id, opaque token fallback
  • Smoke test asserts JWT aud has orgId before LD flag evaluation
  • Manual: verify /mcp/{project_id}/.well-known/oauth-authorization-server returns metadata
  • Manual: smoke test against real cluster with --ld-sdk-key and --ld-flag

🤖 Generated with Claude Code

aniket-s-kulkarni and others added 3 commits March 11, 2026 18:25
FeatureFlagManager previously used a hardcoded single LD context
("mcp-server") for all flag evaluations, making per-project and
per-org targeting impossible. This change builds an LD multi-context
from the current request scope so flags can target by application,
project, and organization independently.

Key changes:
- feature_flags: _build_context() creates multi-context with project
  and org kinds when available, falls back to single context otherwise
- settings: add org_id field (NoFlag) on Dremio model
- mcp: DelegatingTokenVerifier extracts org_id from JWT aud claim
  (Dremio Cloud sets aud=orgId); dual-route OAuth metadata endpoint
  so /mcp/{project_id}/.well-known/oauth-authorization-server resolves
- tools: @secured decorator wires org_id ContextVar into run_with()
- manual test: org_id CLI arg now passed through to run_with()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add LDContextKind StrEnum defining projectId and orgId context kinds
- Move project_id/org_id ContextVars to FeatureFlagManager (decoupled from settings)
- Remove org_id from Dremio settings model (only needed for LD context)
- ProjectIdMiddleware and DelegatingTokenVerifier set ContextVars directly
- Update tests to use FeatureFlagManager.set_project_id/set_org_id

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@aniket-s-kulkarni aniket-s-kulkarni changed the title LD multi-context with per-request project and org targeting DX-116574: LD multi-context with per-request project and org targeting Mar 16, 2026
@aniket-s-kulkarni aniket-s-kulkarni enabled auto-merge (squash) March 16, 2026 20:40
Comment thread src/dremioai/servers/mcp.py Outdated
aniket-s-kulkarni and others added 2 commits March 16, 2026 20:52
Add dremio.extract_org_id_from_jwt (default false, LD-flaggable) to
control whether the server reads the JWT aud claim for LD org-based
targeting. Without this setting there is no other mechanism to derive
the org ID during tool calls.

- New Dremio model field + golden flag keys updated
- verify_token gated behind the setting
- conftest: dremio_overrides param for http_streamable_mcp_server
- 3 E2E tests: org+project context, org-only, opaque token fallback
- Smoke test: --ld-sdk-key/--ld-flag/--ld-expected options with aud
  assertion ensuring JWT contains orgId before LD evaluation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hand-rolled base64 payload extraction with
jwt.decode(token, options={"verify_signature": False}) in mcp.py,
stremable_http_cli.py, and test_launchdarkly_e2e.py.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@aniket-s-kulkarni aniket-s-kulkarni merged commit ec4498d into dremio:main Mar 17, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants