Skip to content

rpcperms: allow multiple read-only middleware#10611

Draft
calvinrzachman wants to merge 2 commits intolightningnetwork:masterfrom
calvinrzachman:multi-readonly-middleware
Draft

rpcperms: allow multiple read-only middleware#10611
calvinrzachman wants to merge 2 commits intolightningnetwork:masterfrom
calvinrzachman:multi-readonly-middleware

Conversation

@calvinrzachman
Copy link
Collaborator

Change Description

There is validation which requires "read-only" middle ware not specify a caveat name. But when you try to register a second read-only middleware, there's validation which prevents double registration for same caveat (though in this case the caveat name is the empty string).

Update the daemon to permit the registration of multiple read-only rpc middleware.

NOTE: This was motivated by request from a user in Slack asking whether lnd can support multiple read-only RPC middleware. The user is getting this error:

Error: 2 UNKNOWN: error registering middleware: a middleware is already registered for the custom caveat name '': lit-macaroon-firewall-logger

Steps to Test

  • make itest icase=rpc_middleware_interceptor

There is validation which requires "read-only" middle ware
not specify a caveat name. But when you try to register a second
read-only middleware, there's validation which prevents double
registration for same caveat (though in this case the caveat name
is the empty string).

Update the dameon to permit the registration of multiple
read-only rpc middleware.
@gemini-code-assist
Copy link

Summary of Changes

Hello @calvinrzachman, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the RPC middleware system by allowing multiple read-only middlewares to be registered concurrently. Previously, the system prevented the registration of more than one middleware if they shared the same (empty) custom caveat name, which was a constraint for read-only middlewares. This change addresses a user-reported issue, providing increased flexibility for users who need to apply multiple non-modifying interceptors to RPC calls without conflict.

Highlights

  • RPC Middleware Registration: Modified the RegisterMiddleware function to permit the simultaneous registration of multiple read-only RPC middlewares, resolving a previous limitation.
  • Documentation Update: Updated the comments for the RegisterMiddleware function to accurately reflect the new behavior regarding multiple read-only middlewares.
  • Integration Testing: Added a new integration test case (multipleReadOnlyMiddlewareTest) to verify that multiple read-only middlewares can be registered and correctly intercept RPC calls.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • itest/lnd_rpc_middleware_interceptor_test.go
    • Added a new test block to testRPCMiddlewareInterceptor to include the multiple read-only middlewares test case.
    • Implemented the multipleReadOnlyMiddlewareTest function, which registers two read-only middlewares, simulates an RPC call, and asserts that both middlewares successfully intercept the request and response.
  • rpcperms/interceptor.go
    • Updated the docstring for RegisterMiddleware to explicitly state that multiple read-only middlewares are now permitted.
    • Modified the registration logic within RegisterMiddleware to allow multiple read-only middlewares to be registered even if they share the same custom caveat name (which is an empty string for read-only middlewares).
Activity
  • The change was motivated by a user request in Slack, highlighting an issue where multiple read-only RPC middlewares could not be registered.
  • The user encountered an error message: "Error: 2 UNKNOWN: error registering middleware: a middleware is already registered for the custom caveat name '': lit-macaroon-firewall-logger".
  • A new integration test rpc_middleware_interceptor was added to validate the updated behavior.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@lightninglabs-deploy lightninglabs-deploy added the severity-medium Focused review required label Feb 25, 2026
@lightninglabs-deploy
Copy link
Collaborator

🟡 PR Severity: MEDIUM

Automated classification | 1 file (non-test) | 17 lines changed (non-test)

🟡 Medium (1 file)
  • rpcperms/interceptor.go - RPC permission interceptor; not in any explicitly CRITICAL or HIGH package path, classified as MEDIUM (other Go files)
Excluded (test/generated) (1 file)
  • itest/lnd_rpc_middleware_interceptor_test.go - integration test file (itest/*), excluded from severity calculation

Analysis

This PR modifies two files:

  1. rpcperms/interceptor.go — The rpcperms package handles RPC middleware interception and permission checking. While it is security-adjacent (controlling access to RPC methods), it does not fall into any of the explicitly listed HIGH-severity categories (macaroons/*, walletunlocker/*, cert/*). It is classified as MEDIUM as an uncategorized Go file.

  2. itest/lnd_rpc_middleware_interceptor_test.go — Integration test file under itest/*, excluded from both severity classification and line/file counting.

Severity bump evaluation:

  • Non-test/non-generated files: 1 (threshold: >20) → no bump
  • Non-test/non-generated lines changed: 17 (threshold: >500) → no bump
  • Multiple distinct critical packages: no → no bump

Final severity: MEDIUM — focused review by a knowledgeable engineer is appropriate given the security-adjacent nature of RPC permission interceptor changes.


To override, add a severity-override-{critical,high,medium,low} label.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly implements the ability to register multiple read-only RPC middlewares, which was previously not possible due to a check that prevented multiple registrations with the same (empty) caveat name. The logic change in rpcperms/interceptor.go is concise and correct. A new integration test, multipleReadOnlyMiddlewareTest, has been added to verify the new functionality, ensuring that multiple read-only middlewares can be registered and will all receive interception messages. The changes are well-implemented and tested. I have one minor suggestion to improve code clarity by removing an unused parameter in the new test function.

ht.EnsureConnected(alice, bob)
ht.Run("multiple read-only middlewares", func(tt *testing.T) {
multipleReadOnlyMiddlewareTest(
tt, alice, bob, readonlyMac,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The bob argument (for the peer parameter) is unused in multipleReadOnlyMiddlewareTest and should be removed.

Suggested change
tt, alice, bob, readonlyMac,
tt, alice, readonlyMac,

Comment on lines +226 to +227
func multipleReadOnlyMiddlewareTest(t *testing.T, node,
peer *node.HarnessNode, userMac *macaroon.Macaroon) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The peer parameter is unused in this function and can be removed to improve code clarity. The call site will also need to be updated.

Suggested change
func multipleReadOnlyMiddlewareTest(t *testing.T, node,
peer *node.HarnessNode, userMac *macaroon.Macaroon) {
func multipleReadOnlyMiddlewareTest(t *testing.T, node *node.HarnessNode,
userMac *macaroon.Macaroon) {

@saubyk saubyk requested a review from yyforyongyu March 5, 2026 15:20
@saubyk saubyk added this to v0.21 Mar 5, 2026
@saubyk saubyk added this to the v0.21.0 milestone Mar 5, 2026
@saubyk saubyk moved this to In progress in v0.21 Mar 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

severity-medium Focused review required

Projects

Status: In progress

Development

Successfully merging this pull request may close these issues.

3 participants