Skip to content

vMCP: implement embeddedAuthServer outgoing auth strategy #3925

@jhrozek

Description

@jhrozek

Part of https://github.com/stacklok/stacklok-epics/issues/251
Depends on #3924

Summary

Implement the embeddedAuthServer outgoing auth strategy in vMCP so that backends requiring interactive upstream OAuth can trigger step-up authentication via 403 + insufficient_scope.

What needs to change

  1. Return 403 with insufficient_scope: When vMCP routes a request to a backend configured with embeddedAuthServer and no upstream token exists for the authenticated user, return HTTP 403 with WWW-Authenticate: Bearer error="insufficient_scope", scope="upstream:<provider_name>". The MCP SDK handles this natively and re-authenticates with the same authserver.

  2. New outgoing auth strategy: Create an embedded_auth_server strategy type and register it in the outgoing auth factory (pkg/vmcp/auth/factory/outgoing.go). The strategy needs access to the authserver's UpstreamTokenStorage to look up upstream tokens by user and provider.

  3. Strategy type and config: Add embedded_auth_server to the strategy type constants and config structs (pkg/vmcp/auth/types/types.go). Add a CRD converter for ExternalAuthTypeEmbeddedAuthServer in the converter registry (pkg/vmcp/auth/converters/).

  4. Upstream token injection: When an upstream token exists for the user and provider, the strategy injects it into the outgoing request to the backend (similar to how header_injection works, but the token comes from authserver storage rather than static config).

  5. Authserver integration: vMCP needs access to the authserver's UpstreamTokenStorage interface. Currently the EmbeddedAuthServer exposes IDPTokenStorage() — wire this into the outgoing auth strategy.

Testing

  • Unit tests for the new strategy (mock UpstreamTokenStorage)
  • Test 403 response generation with correct WWW-Authenticate header
  • Test token injection when upstream token exists
  • Test that non-embeddedAuthServer backends are unaffected

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions