Skip to content

fix: forward field selector to sessions backend#590

Merged
zachsmith1 merged 1 commit intomainfrom
fix/sessions-rest-pass-field-selector
Apr 30, 2026
Merged

fix: forward field selector to sessions backend#590
zachsmith1 merged 1 commit intomainfrom
fix/sessions-rest-pass-field-selector

Conversation

@zachsmith1
Copy link
Copy Markdown
Contributor

Summary

milo's local Sessions REST handler at internal/apiserver/identity/sessions/rest.go:43 was building a fresh empty ListOptions{} and discarding the caller's FieldSelector before delegating to the DynamicProvider backend that proxies to auth-provider-zitadel. The comment said "ignore selectors; self-scoped list delegated to provider" — written before the cross-user lookup pattern landed (#588 / datum-cloud/auth-provider-zitadel#69).

Symptom (observed live in staging)

After #588 merged, the field-selector validation 400 went away — but the request still returned no sessions for the targeted user. Tracing showed:

  • fraud-operator → milo: LIST sessions?fieldSelector=status.userUID=<uid>
  • milo local REST handler → backend: ListOptions{} (selector dropped)
  • backend → auth-provider-zitadel: LIST sessions?timeout=3s (no selector)
  • auth-provider-zitadel REST handler: opts.FieldSelector == nil → falls back to u.GetUID() → caller is system:control@fraud.miloapis.com (service account, no UID) → uid="" → 0 sessions

apiserver logs confirmed the empty UID:

"Listing sessions" uid=""
"ListSessions: found 0 session(s) for userID=""
URI="/apis/identity.miloapis.com/v1alpha1/sessions?timeout=3s"

Fix

Forward opts.FieldSelector (and opts.LabelSelector for completeness) into the metav1.ListOptions passed to Backend.ListSessions. The DynamicProvider backend already preserves the caller identity via X-Remote-* headers (internal/apiserver/identity/sessions/dynamic.go:108-119), so auth-provider-zitadel's REST handler still runs its own SAR check against milo and rejects unauthorized cross-user reads.

Test plan

  • go build ./... clean
  • go test ./internal/apiserver/identity/sessions/... clean
  • Once merged + rolled to staging milo, fraud-operator's Sessions list returns the user's actual sessions instead of 0 session(s) for userID="". Verify via kubectl -n datum-iam-system logs deploy/auth-provider-zitadel-apiserver | grep "Listing sessions" showing uid=<actual-target-uid>.

Related

🤖 Generated with Claude Code

milo's local Sessions REST handler was building a fresh empty ListOptions
and discarding the caller's FieldSelector before delegating to the
DynamicProvider backend that proxies to auth-provider-zitadel. The
"ignore selectors; self-scoped list delegated to provider" comment was
written before the cross-user lookup pattern landed in #588.

This is the missing piece for status.userUID=<uid> lookups: the field
selector now reaches auth-provider-zitadel, where the REST handler runs
its own SAR check against milo using the caller identity (preserved via
X-Remote-* headers in DynamicProvider.dynForUser). Without this, the
handler always saw an empty selector, fell back to the caller's UID
(empty for service accounts), and returned 0 sessions.

Also forwards LabelSelector for completeness.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@joggrbot
Copy link
Copy Markdown
Contributor

joggrbot Bot commented Apr 30, 2026

📝 Documentation Analysis

All docs are up to date! 🎉


✅ Latest commit analyzed: bc9a875 | Powered by Joggr

@zachsmith1 zachsmith1 merged commit 18366dd into main Apr 30, 2026
9 checks passed
@zachsmith1 zachsmith1 deleted the fix/sessions-rest-pass-field-selector branch April 30, 2026 00:15
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.

2 participants