Skip to content

feat(mcp): add server-managed bearer credential references - #1663

Open
FenjuFu wants to merge 2 commits into
iflytek:mainfrom
FenjuFu:feat/mcp-bearer-auth
Open

feat(mcp): add server-managed bearer credential references#1663
FenjuFu wants to merge 2 commits into
iflytek:mainfrom
FenjuFu:feat/mcp-bearer-auth

Conversation

@FenjuFu

@FenjuFu FenjuFu commented Aug 30, 2026

Copy link
Copy Markdown
Member

Summary

Adds the first secure backend slice for authenticated URL-based MCP servers. plugin-link can now resolve a Bearer credential from an operator-managed environment reference bound to an exact HTTPS MCP URL, without adding tokens to workflow JSON, public request schemas, database rows, logs, or telemetry.

This advances, but does not close, #1661. UI/database-backed credential management and tenant-scoped secret lifecycle remain follow-up work.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation/configuration update
  • Refactoring

Related Issue

Refs #1661.

Also enables the authenticated client half needed by:

Changes

  • adds MCP_SERVER_BEARER_TOKEN_REFS, a bounded JSON map from exact final HTTPS MCP URL to secret environment-variable name
  • resolves the referenced token only inside plugin-link and supplies Authorization: Bearer ... through the official httpx/MCP SDK client
  • applies the same path to tool discovery and tool calls because both use initialized_mcp_session
  • rejects embedded URL user-info, invalid/oversized configs, invalid env references, missing/invalid credentials, and non-HTTPS authenticated endpoints
  • disables redirects and AUTO?SSE fallback whenever a Bearer credential is active, preventing credentials from crossing origins/transports
  • preserves all existing behavior for MCP URLs that have no configured credential reference
  • documents the non-secret mapping consistently in core, Docker, and Helm link config templates

Example operator configuration (the token value must be injected separately by deployment secret storage):

MCP_SERVER_BEARER_TOKEN_REFS={https://gitnexus.internal.example/mcp:GITNEXUS_MCP_TOKEN}

Security properties

  • workflow/API callers cannot supply or read the Authorization header
  • mapping is exact-URL-bound and limited to 100 entries / 64 KiB
  • token is limited to visible ASCII / 8 KiB and is never included in exception messages
  • malformed global auth configuration fails closed instead of silently sending an unauthenticated request
  • authenticated connections require the final HTTPS Streamable HTTP endpoint; redirects and legacy SSE fallback are refused

Testing

  • uv run python -m pytest tests/unit -q ? 220 passed
  • Final focused suite after HTTPS enforcement ? 35 passed
  • Black 24.4.2 check
  • isort 5.13.2 check with Black profile
  • flake8 7.0.0 with repository CI flags
  • mypy 1.18.2 with repository CI flags
  • pylint 3.1.0 with repository CI flags ? 8.28/10, above 8.0 threshold
  • New tests cover canonical URL matching, malformed config, duplicate URLs, missing/invalid secrets, no secret echo, header injection, redirect disabling, and no authenticated SSE fallback
  • Manual deployed GitNexus/Astron E2E ? intentionally not claimed; [FEATURE] Authenticated Streamable HTTP MCP connector for GitNexus #1661 still needs the UI/managed-secret layer and merge/deployment approval

Scope / follow-ups

This PR deliberately does not persist credentials in Astron tables or expose a frontend secret editor. The environment reference is a deployer-managed first stage that supports rotation without rewriting workflows. A later #1661 PR can replace/augment the resolver with tenant-scoped secret storage while keeping the same transport contract and tests.

Screenshots

Not applicable; no UI changes.

Checklist

  • Code follows project coding standards
  • Self-review completed
  • Configuration templates updated
  • No token values, private URLs, or machine-specific paths committed
  • Breaking changes documented ? none; unconfigured endpoints retain existing behavior

Persistence update

Commit 8a9b8cd2 adds V1.49 persistence for auth_type and RSA-encrypted credential_ciphertext, validates Bearer configuration before workflow release side effects, and exposes only hasCredential in response DTOs. The ciphertext is never returned.

Validation:

  • Maven reactor compile (commons/toolkit/hub) with JDK 21: passed
  • McpServiceImplBusinessExceptionTest: 2 passed

Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
Signed-off-by: FenjuFu <92919259+FenjuFu@users.noreply.github.com>
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.

1 participant