You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Inconsistent visibility for private/invited users: inaccessible nodes listed in 'last edited', invited module missing from navigation, search and access menu expose users #385
Follow-up to #384. After completing sign-in as a private user (invited via private email, Google sign-in), the portal itself loads and generally looks OK — but node visibility is inconsistent with the user's actual access rights, in both directions (shows too much, and too little).
Problem 1 — 'Last edited' feed lists nodes the user has no access to
The portal's last-edited nodes view shows nodes that the private user cannot access. Access being denied on open is correct — but these nodes should not be listed at all. Showing their existence/titles/paths to an unauthorized user is a metadata leak; row-level security should filter the last-edited feed the same way it filters direct reads.
Problem 2 — Invited module 'Agentic Engineering' does not appear as a node
The user was explicitly invited to the educational module Agentic Engineering, but it does not show up as a node anywhere in the portal (navigation / node listings). Navigating directly via the browser URL works and access is granted as expected — so the permission itself is in place, only the discovery/navigation surface misses it. Invited-to content should be visible in navigation, otherwise invitees can only reach it via out-of-band links.
Problem 3 — Search exposes users of the educational program
When reaching the module via search instead of the direct URL, the search results included user nodes of other participants in the educational program. A private invitee should not be able to see (or enumerate) other users; these should be excluded from their search results entirely.
Problem 4 — Access menu lists all users of the space
The access menu shows the private user all users of the space. A private invitee should not be able to enumerate the space's user base from the access/sharing UI — the user picker / access list should be restricted (e.g. to users they legitimately need to see, or hidden entirely for users without manage-access rights).
Expected behavior
One consistent access model across all surfaces — direct navigation, 'last edited' feed, navigation tree, search, and the access menu should all reflect exactly what the user is entitled to see:
No listing of inaccessible nodes in feeds or search (Problems 1 and 3).
Content the user IS entitled to (invited module) discoverable in navigation, not only via direct URL (Problem 2).
No enumeration of the space's users via the access menu (Problem 4).
Notes
Problems 1, 3 and 4 are the security-relevant half (information disclosure / user enumeration); Problem 2 is a UX/consistency gap.
Suggests the row-level-security filter is applied on direct node reads but not (or differently) on the last-edited query, the navigation tree source, the search index results, and the access-menu user list.
May be worth splitting into separate issues if the fixes land in different components.
Reported by @rsalzmann (observed with a freshly invited private-email account).
changed the title [-]Inconsistent visibility for private/invited users: inaccessible nodes listed in 'last edited', invited module missing from navigation, search exposes program users[/-][+]Inconsistent visibility for private/invited users: inaccessible nodes listed in 'last edited', invited module missing from navigation, search and access menu expose users[/+]on Jul 9, 2026
Shares roots with #471 — see the full RCA there. This issue's four symptoms map to: inaccessible nodes in 'Last edited' = RC3 (the BuildPerSchemaAccessClause public_read-outside-partition-gate outlier at PostgreSqlSqlGenerator.cs:697-700, vs the documented partition_access AND (public_read OR node) invariant); search/access-menu expose users = RC2 (User is WithPublicRead + the auth-mirror route); invited module missing from navigation = RC4 (no query enumerates the caller's cross-partition AccessAssignments). RC2+RC3 land together (same auth path); RC4 is additive. Holding for maintainer greenlight given the access-model blast radius.
Resolved via #536 (merged) + #521. RC3 (inaccessible nodes in 'Last edited' / cross-partition public-read feed leak) fixed by aligning the access clause; RC4 (invited module missing from navigation) shipped as a 'Shared with me' nav tab sourcing the caller's cross-partition AccessAssignments; the search/access-menu user exposure is bounded by the email redaction (#521). The remaining user-enumeration hardening (name-only projection) was consciously declined — see the disposition on #471. Closing.
Activity
[-]Inconsistent visibility for private/invited users: inaccessible nodes listed in 'last edited', invited module missing from navigation, search exposes program users[/-][+]Inconsistent visibility for private/invited users: inaccessible nodes listed in 'last edited', invited module missing from navigation, search and access menu expose users[/+]rbuergi commentedon Jul 18, 2026
Shares roots with #471 — see the full RCA there. This issue's four symptoms map to: inaccessible nodes in 'Last edited' = RC3 (the
BuildPerSchemaAccessClausepublic_read-outside-partition-gate outlier at PostgreSqlSqlGenerator.cs:697-700, vs the documentedpartition_access AND (public_read OR node)invariant); search/access-menu expose users = RC2 (User is WithPublicRead + the auth-mirror route); invited module missing from navigation = RC4 (no query enumerates the caller's cross-partition AccessAssignments). RC2+RC3 land together (same auth path); RC4 is additive. Holding for maintainer greenlight given the access-model blast radius.rbuergi commentedon Jul 18, 2026
Resolved via #536 (merged) + #521. RC3 (inaccessible nodes in 'Last edited' / cross-partition public-read feed leak) fixed by aligning the access clause; RC4 (invited module missing from navigation) shipped as a 'Shared with me' nav tab sourcing the caller's cross-partition AccessAssignments; the search/access-menu user exposure is bounded by the email redaction (#521). The remaining user-enumeration hardening (name-only projection) was consciously declined — see the disposition on #471. Closing.
One partition with no permission table darkened the cross-schema unio…