fix(chat): prevent private conversation visibility leak#2018
Open
sriaradhyula wants to merge 12 commits into
Open
fix(chat): prevent private conversation visibility leak#2018sriaradhyula wants to merge 12 commits into
sriaradhyula wants to merge 12 commits into
Conversation
Scope conversation list/search/trash candidates before ReBAC checks so unshared private chats are not considered visible, and keep conversation discovery grants out of everyone public grants. Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
|
✅ No proprietary content detected. This PR is clear for review! |
Contributor
🧪 CAIPE UI Test Results✅ All tests passed 🟠 Overall Coverage: 58%📊 Detailed Coverage
✅ Test Suites
📈 Coverage Thresholds
|
Prebuild Artifacts for `a2f64d8` (archived)Prebuild Artifacts for
|
| Artifact | Image | Tag | Status | CI |
|---|---|---|---|---|
| caipe-ui | ghcr.io/cnoe-io/prebuild/caipe-ui |
fix-private-chat-visibility-2 |
Published | CI |
Docker pull commands
docker pull ghcr.io/cnoe-io/prebuild/caipe-ui:fix-private-chat-visibility-2These prebuild artifacts will be automatically cleaned up when the PR is closed or merged.
Carry sharing metadata into direct-open chat store entries and keep timeline warning details expanded after a turn completes. Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Make sidebar shared badges viewer-aware and preserve conversation access levels from direct chat loads so recipients see shared chat indicators without showing recipient badges to owners. Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Allow chat shares to target teams from the member-visible team endpoint, persist canonical team slugs when available, resolve recipient access through canonical team membership, and write best-effort conversation grants for team recipients. Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Prebuild Artifacts for `af5e227` (archived)Prebuild Artifacts for
|
| Artifact | Image | Tag | Status | CI |
|---|---|---|---|---|
| caipe-ui | ghcr.io/cnoe-io/prebuild/caipe-ui |
fix-private-chat-visibility-5 |
Published | CI |
Docker pull commands
docker pull ghcr.io/cnoe-io/prebuild/caipe-ui:fix-private-chat-visibility-5These prebuild artifacts will be automatically cleaned up when the PR is closed or merged.
Annotate conversation list rows with a viewer-specific shared flag after RBAC filtering and carry it through the chat store. Use that signal in the sidebar so recipients see the shared badge even when owner metadata is missing, while owners stay unbadged. Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Prebuild Artifacts for
|
| Artifact | Image | Tag | Status | CI |
|---|---|---|---|---|
| caipe-ui | ghcr.io/cnoe-io/prebuild/caipe-ui |
fix-private-chat-visibility-6 |
Published | CI |
Docker pull commands
docker pull ghcr.io/cnoe-io/prebuild/caipe-ui:fix-private-chat-visibility-6These prebuild artifacts will be automatically cleaned up when the PR is closed or merged.
Restore the sidebar share affordance for shared conversation recipients without opening owner-only share management. Show shared-by details in the shared badge and recipient share tooltip, with recipient clicks copying the conversation link. Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
Signed-off-by: Sri Aradhyula <sraradhy@cisco.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Fixes a 0.5.x regression where unshared private chat conversations could be included in global/shared visibility paths. The list, search, and trash APIs now build a bounded Mongo candidate set before ReBAC checks:
This also removes
conversation:discoverfrom the publiceveryonegrant allowlist so private conversations cannot be made globally discoverable through the generic grant API.Follow-up UI and sharing fixes in this PR:
owner_id,accessLevel, andsharingmetadata in the client store, so recipients see the shared/public badge.viewer_has_shared_accessandaccess_levelmetadata after ReBAC filtering; the chat store maps them to the sidebar so recipients see the right shared affordance.team_membership_sources, and writes best-effort conversation grants for team recipients.Added regression coverage for the candidate query helper, affected API routes, public/team sharing behavior, service-account grants, direct-open shared chat metadata, recipient-only sidebar shared badges, recipient share affordance behavior, the mocked RBAC Playwright shared-recipient sidebar affordance flows for read-only and edit shares, team share dialog behavior, canonical team recipient access, warning timeline expansion, and the RBAC Playwright flow for recent chats, search/trash, and rejected everyone discover grants.
Authorization Boundary: CAS vs List Metadata
This PR keeps the access decision in the centralized ReBAC path. The conversation list first builds a bounded Mongo candidate set and then calls
filterConversationsByImplicitOrExplicitPermission(...)before returning rows. Detail, message, turn, and share mutation routes continue to userequireConversationAccess(...)for authoritative enforcement.The final
access_levelonGET /api/chat/conversationsis display metadata for sidebar/share-button affordances. It distinguishes owner, shared edit, shared read-only, and admin audit for rows the caller is already allowed to see. Today that effective tier depends on Mongo share metadata (owner_id,owner_subject,sharing_access.permission,sharing.public_permission, andsharing.team_permissions) as well as ReBAC visibility. Calling CAS/OpenFGA per row would reintroduce the N+1 behavior and would still not answer the full "what affordance should the sidebar show?" question without another metadata lookup.A future CAS bulk effective-access API would be the right place to centralize this display tier. Until then, this patch keeps enforcement centralized and derives only already-authorized list metadata locally, so a sidebar badge cannot break listing or weaken read/write/share gates.
Type of Change
Pre-release Helm Charts (Optional)
No chart changes.
Checklist
Validation
npm test -- --runTestsByPath src/lib/rbac/__tests__/conversation-implicit-authz.test.ts src/lib/authz/__tests__/http.test.ts src/app/api/__tests__/chat-conversations-remaining-rbac.test.ts src/app/api/__tests__/chat-sharing-public.test.ts src/app/api/__tests__/chat-sharing-teams.test.ts src/app/api/__tests__/chat-conversations-agent-auth.test.ts src/app/api/__tests__/chat-conversations-sa-grant.test.tsnpm test -- --runTestsByPath src/app/api/__tests__/chat-conversations-client-type.test.ts src/app/api/chat/shared/__tests__/route.test.tsnpm test -- --runTestsByPath src/lib/rbac/__tests__/conversation-implicit-authz.test.ts src/components/layout/__tests__/Sidebar.test.tsx src/store/__tests__/chat-store.test.ts src/app/api/__tests__/chat-conversations-client-type.test.tsnpm test -- --runTestsByPath src/components/layout/__tests__/Sidebar.test.tsx src/components/chat/__tests__/ShareButton.test.tsxRUN_RBAC_REGRESSION=1 npx playwright test --config=playwright.rbac.config.ts e2e/rbac/chat-share-exposed.spec.tsRUN_RBAC_REGRESSION=1 NEXTAUTH_SECRET=rbac-e2e-secret CAIPE_UI_BASE_URL=http://localhost:3100 npx playwright test --config=playwright.rbac.config.ts e2e/rbac/chat-navigation-regression.spec.ts --grep "read-only shared conversation recipients|edit-mode shared conversation recipients"npm test -- --runTestsByPath 'src/app/(app)/chat/[uuid]/__tests__/page.test.tsx' 'src/components/layout/__tests__/Sidebar.test.tsx' 'src/components/chat/__tests__/DynamicAgentTimeline.test.tsx'npm test -- --runTestsByPath src/app/api/__tests__/chat-sharing-teams.test.ts src/app/api/__tests__/chat-sharing-readonly.test.ts src/components/chat/__tests__/ShareDialogPublicToggle.test.tsxnpm test -- ShareButton.test.tsx --runInBandnpm run lint(0 errors; existing warnings remain)npm run lint -- --quietnpm run buildgit diff --check