Repository navigation
fix(kernel): require verified caller identity for the active-tabs bridge - #646
Conversation
|
@claude Please review current head |
49f3cd4 to
32ec172
Compare
|
Claude finished @kshivang's task in 4m 1s —— View job Review of
|
|
@Antriksh1984 Your seven RPC gates correctly protect private tab metadata and tab control, and all original work/author metadata is preserved in the clean dev replay. Current head is The current Claude review found no blocking defect. I addressed its concrete follow-ups: select/create/close now record caller + RPC at INFO without storing URLs or titles; bind and revocation refusals have separate structured stages; the KDoc summary and synchronous capture comment are corrected; the fake now records activeTabs access, and refresh/favicon happy paths are asserted. Earlier reviewer work added unary/live-stream revocation coverage. These are reviewer repairs, excluded from your original contribution score and credited in the description. Current-head local ActiveTabsServiceBridgeTest passes 5/5 with zero failures/errors/skips; ktlint and detekt pass through the mandatory build-lock wrapper. Original-head hosted XML was also verified on Linux/macOS/Windows. Current-head hosted code-quality/compatibility and lightweight checks pass, but Ubuntu/Windows builds are in progress and macOS is queued at this handoff. Prior-head green checks cannot validate this audit/test follow-up. This is a CI scheduling/validation blocker, not an author correctness defect. Next steps: let the current-head required platform builds and summary complete; inspect any actual failure before attributing it; then recheck dev mergeability and the latest review against this small follow-up, and restore ready for serialized dev-only merge. No unresolved substantive source defect is asserted. The review suggestion to log a sanitized URL was satisfied more conservatively by logging attribution without any URL. Shared transport/helper inventory stays separate (#575). No UI delta or native visual test applies. Per the bounded final-disposition instruction, converting to draft while required CI is incomplete. Original score: 9/10, excluding reviewer repairs. No checks bypassed and no unvalidated merge attempted. |
Every ActiveTabsService RPC was reachable by any process able to open a connection to the kernel IPC server, not only the plugins the host itself loaded. watchActiveTabs disclosed every open tab's title and URL across every window with no credential at all, and createBrowserTab could force the browser to navigate to an arbitrary URL; selectTab/closeTab could manipulate what the user is looking at. All seven RPCs now require a verified caller identity, matching the pattern PR risa-labs-inc#505 established for the Secret Service: unary RPCs call authenticatedCallerOrRefuse, and the watchActiveTabs stream captures ProcessIdentityInterceptor.CURRENT_IDENTITY synchronously in the method body (before the flow is collected, on the calling thread the interceptor's context is current on) and re-checks it before every emission, so a revoked caller's stream is refused before an already-held handle could receive a value it should no longer see. Refusals are logged with a bind/revocation stage tag, and the three mutating RPCs (selectTab, createBrowserTab, closeTab) now record an attributed audit line - caller and RPC name only, no URLs or titles. Tested with a real gRPC server plus ProcessIdentityInterceptor: every RPC is refused with no credential and never reaches the provider, an authenticated caller can watch/read/select/create/close tabs, and a revoked caller's live watch stream terminates with PERMISSION_DENIED before receiving a value that arrived after revocation.
cbd2c3a to
0139bcf
Compare
|
Claude finished @kshivang's task in 3m 48s —— View job Review of
|
|
@Antriksh1984 Re-reviewed current head Review reconciliation: This is distinct from #634 and the merged Git/Log/Download/Secret bridges, not a duplicate. Original score remains 9/10 (impact 3, correctness 3, completeness/testing 1, maintainability 2), excluding reviewer repairs. Ready for the serialized dev-only merge after a fresh locked state/mergeability check. |
…dge (#646) Every ActiveTabsService RPC was reachable by any process able to open a connection to the kernel IPC server, not only the plugins the host itself loaded. watchActiveTabs disclosed every open tab's title and URL across every window with no credential at all, and createBrowserTab could force the browser to navigate to an arbitrary URL; selectTab/closeTab could manipulate what the user is looking at. All seven RPCs now require a verified caller identity, matching the pattern PR #505 established for the Secret Service: unary RPCs call authenticatedCallerOrRefuse, and the watchActiveTabs stream captures ProcessIdentityInterceptor.CURRENT_IDENTITY synchronously in the method body (before the flow is collected, on the calling thread the interceptor's context is current on) and re-checks it before every emission, so a revoked caller's stream is refused before an already-held handle could receive a value it should no longer see. Refusals are logged with a bind/revocation stage tag, and the three mutating RPCs (selectTab, createBrowserTab, closeTab) now record an attributed audit line - caller and RPC name only, no URLs or titles. Tested with a real gRPC server plus ProcessIdentityInterceptor: every RPC is refused with no credential and never reaches the provider, an authenticated caller can watch/read/select/create/close tabs, and a revoked caller's live watch stream terminates with PERMISSION_DENIED before receiving a value that arrived after revocation.
Summary
ActiveTabsServiceBridgehad no caller-identity check on any of its seven RPCs. Any process able to open a connection to the kernel IPC server - not only the plugins the host itself loaded - could:watchActiveTabsto see every open tab's title and URL across every window and workspace - browsing history and open documents, disclosed with no credential;createBrowserTabto force the browser to navigate to an arbitrary URL;closeTab/selectTabto manipulate what the user is currently looking at.Gate every RPC behind
authenticatedCallerOrRefuse(), the samePERMISSION_DENIED-on-no-verified-identity patternPluginUIServiceBridgeestablished for BossConsole#53.The one watch stream (
WatchActiveTabs) captures identity synchronously before returning the flow and re-checks it on every emission, so a revoked token stops a live stream rather than only new calls - matching the shape PR #550's review settled on for this bridge's siblings.Test plan
ActiveTabsServiceBridgeTestruns a real gRPC server behindProcessIdentityInterceptor: every RPC refused withPERMISSION_DENIEDfor an anonymous caller and the fake provider never invoked; an authenticated caller can watch/read tabs and select/create/close tabs normally../gradlew :composeApp:compileKotlinDesktop :composeApp:compileTestKotlinDesktop./gradlew :composeApp:desktopTest --tests "ai.rever.boss.kernel.services.ActiveTabsServiceBridgeTest"./gradlew :composeApp:detektReview attribution and current validation
Antriksh (@Antriksh1984) authored the original production change and original tests. The original commits were replayed onto dev to remove conflicts caused by squash-merged shared history; author metadata is preserved. Reviewer follow-up adds unary and deterministic live-stream revocation tests, centralized stream refusal diagnostics and explicit emission-driven revocation documentation. These repairs are not original contributor work. The replayed current head requires its own CI; old-head green checks do not validate the new integration. Idle streams are not proactively disconnected. Shared transport/helper work (#575) remains separate. No UI was changed or visually exercised.
Final disposition (2026-09-14): current head
0139bcff5cc66324fba0e8a466b0deef3f091611passed all ten hosted checks. Downloaded Linux/macOS/Windows artifacts each confirm five bridge tests, zero failures/errors/skips. Current Claude review found no blocking defect; reconciliation is recorded in the review comment. Merged into dev with the shared merge lock and exact-head guard, squash2714a6ab56030c69337c92a5f375865e6ec484f7. No native UI exercise or external-runtime rollout claimed.