Skip to content

fix(kernel): require verified caller identity for the Secret Service bridge - #598

Closed
Antriksh1984 wants to merge 1 commit into
risa-labs-inc:devfrom
Antriksh1984:fix/secret-bridge-caller-identity
Closed

Antriksh1984 wants to merge 1 commit into
risa-labs-inc:devfrom
Antriksh1984:fix/secret-bridge-caller-identity

Conversation

@Antriksh1984

Copy link
Copy Markdown
Contributor

Summary

SecretServiceBridge proxies the password vault to out-of-process plugins over the kernel's gRPC IPC server - getUserSecrets/getUserSecretsWithSharingInfo return plaintext passwords and TOTP recovery codes, and shareSecret/unshareSecret grant or revoke another user's or role's access to a secret. Continuing the BossConsole#53 caller-identity work, none of this bridge's nine RPCs checked who was calling before this: any process able to open a connection to the kernel IPC server - not only the plugins the host itself loaded - could read or reshare every secret the signed-in user owns.

  • Gate every RPC (GetUserSecrets, GetUserSecretsWithSharingInfo, SearchSecrets, CreateSecret, UpdateSecret, DeleteSecret, GetSecretShares, ShareSecret, UnshareSecret) behind authenticatedCallerOrRefuse(), the same PERMISSION_DENIED-on-no-verified-identity pattern PluginUIServiceBridge established for Remote UI: StreamUI has no plugin identity check — one plugin can bind another's surface #53.
  • A call with no ProcessIdentityInterceptor-verified identity is refused before it ever reaches SecretDataProvider, so a refusal can't leak timing/existence information either.

Test plan

  • New SecretServiceBridgeTest runs a real gRPC server behind ProcessIdentityInterceptor with a real client stub (no mocking of the transport): asserts every RPC is refused with PERMISSION_DENIED for an anonymous caller and that the fake vault provider is never invoked, and that an authenticated caller can still read, create, share, unshare and delete secrets normally.
  • ./gradlew :composeApp:compileKotlinDesktop :composeApp:compileTestKotlinDesktop
  • ./gradlew :composeApp:desktopTest --tests "ai.rever.boss.kernel.services.SecretServiceBridgeTest"
  • ./gradlew :composeApp:ktlintDesktopTestSourceSetCheck
  • ./gradlew :composeApp:detektDesktopMain :composeApp:detektDesktopTest

…bridge

SecretServiceBridge proxies the password vault - plaintext credentials, TOTP
recovery codes, and sharing grants - to any process that can open a
connection to the kernel IPC server, not only the plugins the host itself
loaded. Unlike the bridges already fixed under BossConsole#53, none of its
nine RPCs checked who was calling before this.

Gate every RPC behind authenticatedCallerOrRefuse(), the same
PERMISSION_DENIED-on-no-identity pattern PluginUIServiceBridge established,
and add a real gRPC-server test proving an unauthenticated caller is refused
and never reaches the vault provider, while an authenticated one can still
read, create, share, unshare and delete secrets normally.
@kshivang

Copy link
Copy Markdown
Contributor

@Antriksh1984 Thank you for the Secret Service caller-identity fix. I compared the actual production and test diffs with your earlier #505 at 7bf4f6e0db504495cfebf6e76ba552933d2cce0c.

#505 already covers all nine RPCs in #598: list, list-with-sharing, search, create, update, delete, get shares, share and unshare. Each gate uses the same interceptor-verified identity and refuses before provider access. #505 also preserves mutation attribution and RBAC gates, with explicit anonymous refusal tests for every vault method plus revoked-token and late-registration coverage. The additional positive workflow assertions in #598 exercise unchanged provider mapping; there is no additional production fix to port. Both heads have green CI; #505's prior focused tests and quality checks are recorded in its review thread.

Closing #598 as fully superseded by #505, keeping the older and more complete implementation. The surviving description explicitly credits you, Antriksh (@Antriksh1984), for both submissions and distinguishes previous reviewer repairs. #505 remains open against dev; neither PR is being merged or auto-merged. #550's Supabase/download guards and #575's transport/ownership changes are distinct and are not included in this closure.

@kshivang kshivang closed this Sep 13, 2026
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