Skip to content

Recognise identityFromToken in synthesis-mode detection #5159

@jhrozek

Description

@jhrozek

Recognise identityFromToken in synthesis-mode detection

Description

Final phase of the Snowflake / identityFromToken story (#5150).
PR #5094 added two synthesis-mode-detection sites — an operator status
condition (IdentitySynthesized) and a runtime WARN at provider
construction — both of which check only UserInfo == nil. After
identityFromToken lands, configs that use it instead of userInfo
have a real-identity resolution path but are falsely flagged as
synthesis-mode by both surfaces. Update both predicates and their
associated text so the operator-visible state matches reality.

Context

EmbeddedAuthServerConfig.SyntheticIdentityUpstreams drives the
IdentitySynthesized advisory condition published on both
MCPExternalAuthConfig and VirtualMCPServer status. The runtime
NewOAuth2Provider WARN fires once at construction. Both currently
treat "no userInfo" as the synthesis-mode signal.

When identityFromToken is configured, the runtime priority chain
honours it BEFORE considering synthesis, so the upstream is NOT in
synthesis mode. The detection predicates need to also exclude
upstreams that have identityFromToken set.

The condition messages and the runtime WARN text both need updating
to recommend either userInfo OR identityFromToken as the
identity-resolution alternatives — operators encountering the
condition should see the new option.

The reason-constant string values change to reflect the broader
criterion:

  • OAuth2UpstreamWithoutUserInfoOAuth2UpstreamWithoutIdentityResolution
  • AllUpstreamsHaveUserInfoAllUpstreamsHaveIdentityResolution

This is a breaking change in the observable Kubernetes API surface of
the IdentitySynthesized condition. PR #5094 just landed with no
released consumers, so the rename is safe now and would not have been
if deferred. Anyone matching the old strings in alerting rules,
dashboards, or GitOps tooling will need to update them.

Per .claude/rules/operator.md's status-condition-parity rule, both
MCPExternalAuthConfig and VirtualMCPServer controllers must use
identical condition messages — they share the helper here, so the
fix is single-source by construction.

Dependencies: #5155 (CRD type), #5156 (provider integration so
the runtime priority chain actually does what the predicate now
claims).
Blocks: nothing — this is the final piece.

Acceptance Criteria

  • EmbeddedAuthServerConfig.SyntheticIdentityUpstreams excludes
    upstreams that have identityFromToken configured (in addition to
    the existing userInfo check).
  • The NewOAuth2Provider runtime WARN at provider construction
    fires only when both userInfo and identityFromToken are nil.
  • Both controllers' condition messages and the runtime WARN text
    reference both userInfo and identityFromToken as the
    identity-resolution alternatives.
  • Reason-constant string values are renamed from
    OAuth2UpstreamWithoutUserInfo /
    AllUpstreamsHaveUserInfo to
    OAuth2UpstreamWithoutIdentityResolution /
    AllUpstreamsHaveIdentityResolution. The Go identifiers are
    unchanged.
  • PR description / changelog calls out the reason-constant rename
    as a breaking change in the observable Kubernetes API surface.
  • Status-condition parity holds: both MCPExternalAuthConfig and
    VirtualMCPServer controllers emit byte-identical condition
    messages.
  • New test cases cover:
    • An OAuth2 upstream with identityFromToken set (and no userInfo)
      flips the condition to False with the new reason.
    • A mixed config where one upstream has identityFromToken and
      another has neither names only the truly synthesis-mode upstream
      in the message.
  • task lint-fix, task operator-test, and task test pass.

Out of Scope

  • Any further audit-log surface improvements (e.g. an upstream_sub
    claim) — separate work, not blocked by this story.

Metadata

Metadata

Assignees

No one assigned

    Labels

    authenhancementNew feature or requestgoPull requests that update go codekubernetesItems related to Kubernetesoperator

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions