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:
OAuth2UpstreamWithoutUserInfo → OAuth2UpstreamWithoutIdentityResolution
AllUpstreamsHaveUserInfo → AllUpstreamsHaveIdentityResolution
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
Out of Scope
- Any further audit-log surface improvements (e.g. an
upstream_sub
claim) — separate work, not blocked by this story.
Recognise
identityFromTokenin synthesis-mode detectionDescription
Final phase of the Snowflake /
identityFromTokenstory (#5150).PR #5094 added two synthesis-mode-detection sites — an operator status
condition (
IdentitySynthesized) and a runtime WARN at providerconstruction — both of which check only
UserInfo == nil. AfteridentityFromTokenlands, configs that use it instead ofuserInfohave 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.SyntheticIdentityUpstreamsdrives theIdentitySynthesizedadvisory condition published on bothMCPExternalAuthConfigandVirtualMCPServerstatus. The runtimeNewOAuth2ProviderWARN fires once at construction. Both currentlytreat "no userInfo" as the synthesis-mode signal.
When
identityFromTokenis configured, the runtime priority chainhonours it BEFORE considering synthesis, so the upstream is NOT in
synthesis mode. The detection predicates need to also exclude
upstreams that have
identityFromTokenset.The condition messages and the runtime WARN text both need updating
to recommend either
userInfoORidentityFromTokenas theidentity-resolution alternatives — operators encountering the
condition should see the new option.
The reason-constant string values change to reflect the broader
criterion:
OAuth2UpstreamWithoutUserInfo→OAuth2UpstreamWithoutIdentityResolutionAllUpstreamsHaveUserInfo→AllUpstreamsHaveIdentityResolutionThis is a breaking change in the observable Kubernetes API surface of
the
IdentitySynthesizedcondition. PR #5094 just landed with noreleased 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, bothMCPExternalAuthConfigandVirtualMCPServercontrollers must useidentical 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.SyntheticIdentityUpstreamsexcludesupstreams that have
identityFromTokenconfigured (in addition tothe existing
userInfocheck).NewOAuth2Providerruntime WARN at provider constructionfires only when both
userInfoandidentityFromTokenare nil.reference both
userInfoandidentityFromTokenas theidentity-resolution alternatives.
OAuth2UpstreamWithoutUserInfo/AllUpstreamsHaveUserInfotoOAuth2UpstreamWithoutIdentityResolution/AllUpstreamsHaveIdentityResolution. The Go identifiers areunchanged.
as a breaking change in the observable Kubernetes API surface.
MCPExternalAuthConfigandVirtualMCPServercontrollers emit byte-identical conditionmessages.
identityFromTokenset (and no userInfo)flips the condition to False with the new reason.
identityFromTokenandanother has neither names only the truly synthesis-mode upstream
in the message.
task lint-fix,task operator-test, andtask testpass.Out of Scope
upstream_subclaim) — separate work, not blocked by this story.