Skip to content

LNC Sessions: Give more granular control to LND Account Macaroons#1282

Open
Liongrass wants to merge 3 commits into
lightninglabs:masterfrom
Liongrass:custom-lnc-sessions
Open

LNC Sessions: Give more granular control to LND Account Macaroons#1282
Liongrass wants to merge 3 commits into
lightninglabs:masterfrom
Liongrass:custom-lnc-sessions

Conversation

@Liongrass

Copy link
Copy Markdown

Disclaimer: This pull request was entirely made with Claude, but tested manually in great detail

Introduction

The command litcli sessions add allows a user to generate an LNC pairing phrase. This allows a user to permission an external application, for example Zeus on their phone, Alby in the browser, Lnget in the command line or a Wasm like Lightning Terminal. Currently, these sessions can be of --type readonly|admin|account|custom

An LND Account is a macaroon with an associated balance. The holder of that macaroon can send and receive, as well as see basic information of the node they are connected to. They cannot open or close channels , and they can only spend funds allocated to their account. Paid invoices created with the Account macaroon are counted towards the Account budget.

Problem

In the current setup, an admin can only create a full LND Account session that can both receive and spend the funds of an LND Account.

While it is possible to create readonly or custom macaroons for an LND Account (see guide here), it is not possible to create an LNC session for it. Most commonly, a user might want to generate an invoice macaroon for their account.

Solution

In this pull request, the flag --account_id no longer requires --type account. Instead, --account_id attenuates any macaroon type defined in --type with lnd-custom account. This allows the creation of LNC sessions for readonly and custom macaroons restricted to a single LND Account.

Testing

I am running this pull request on signet, the created sessions have the expected macaroons with the expected attenuation.

Future Work

Through this change, users can generate LNC sessions for LND Accounts with arbitrary macaroons. This makes new macaroon types easier to create in the future with LND Accounts, such as invoice-only LNC sessions. In the future, the litcli sessions add command could also accept any arbitrary attenuation.

Considerations

The macaroon created with the existing --type account --account_id <account id> differs from that created with --type admin --account_id <account id. While it contains all the admin permissions such as macaroon:generate, LND doesn't accept these actions because of the account_id attenuation.

While it would be possible to adjust the LND Account macaroon to be identical to the status quo, the restrictions of an LND Account macaroon are defined by what litd can handle, not what is specified in the macaroon. The main disadvantage is that applications like Terminal will currently use the heuristics of the present permissions, rather than the lnd-custom account attenuation.

LND Account Macaroon permissions today:

{
    "version": 2,
    "location": "lnd",
    "root_key_id": "18441921394825525203",
    "permissions": [
        "info:read",
        "invoices:read",
        "invoices:write",
        "offchain:read",
        "offchain:write",
        "onchain:read",
        "peers:read"
    ],
    "caveats": [
        "lnd-custom account 0cae57e48e182361",
        "time-before 2026-07-06T05:39:23Z"
    ]
}

LND Account "Admin" Macaroon created through the code of this pull request:

{
    "version": 2,
    "location": "lnd",
    "root_key_id": "18441921394195493058",
    "permissions": [
        "account:read",
        "account:write",
        "actions:read",
        "address:read",
        "address:write",
        "addresses:read",
        "addresses:write",
        "assets:read",
        "assets:write",
        "auction:read",
        "audit:read",
        "auth:read",
        "auth:write",
        "autopilot:read",
        "autopilot:write",
        "channels:read",
        "channels:write",
        "daemon:read",
        "daemon:write",
        "info:read",
        "info:write",
        "insights:read",
        "invoices:read",
        "invoices:write",
        "loop:admin",
        "loop:in",
        "loop:out",
        "macaroon:generate",
        "macaroon:read",
        "macaroon:write",
        "mailbox:read",
        "mailbox:write",
        "message:read",
        "message:write",
        "mint:read",
        "mint:write",
        "offchain:read",
        "offchain:write",
        "onchain:read",
        "onchain:write",
        "order:read",
        "order:write",
        "peers:read",
        "peers:write",
        "privacymap:read",
        "proofs:read",
        "proofs:write",
        "proxy:read",
        "proxy:write",
        "rates:read",
        "recommendation:read",
        "report:read",
        "rfq:read",
        "rfq:write",
        "sessions:read",
        "sessions:write",
        "signer:generate",
        "signer:read",
        "suggestions:read",
        "suggestions:write",
        "supermacaroon:write",
        "swap:execute",
        "swap:read",
        "terms:read",
        "universe:read",
        "universe:write"
    ],
    "caveats": [
        "lnd-custom account 92d17f9e544e1f97",
        "time-before 2026-07-06T05:37:02Z"
    ]
}

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, 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 flexibility of LNC session creation by allowing LND Account binding to be applied to any session type, rather than being limited to a specific 'account' type. This change enables users to generate more specialized macaroons, such as invoice-only sessions, while maintaining strict account-level restrictions. The implementation refactors how session caveats and permissions are processed to ensure consistent behavior during both initial creation and session resumption.

Highlights

  • Decoupled Account ID from Session Type: The --account_id flag is no longer restricted to the account session type, allowing it to be used with readonly and custom sessions.
  • Improved Macaroon Attenuation: Account ID binding is now applied as a general caveat to any session type, enabling more granular control over LND Account permissions.
  • Refactored Session Creation and Resumption: Updated AddSession and resumeSession logic to handle account binding consistently across different session types.

🧠 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.

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.

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.

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

Copy link
Copy Markdown

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 refactors session management to allow binding any session type to a specific account using an optional account ID, rather than restricting this functionality to a dedicated 'account' session type. Key changes include updating the CLI flags, refactoring the AddSession RPC to handle account caveats globally, and ensuring resumeSession applies stored caveats for all session types. Feedback suggests that removing the 'account' type from the CLI is a breaking change and recommends retaining it as a preset. Additionally, the resumption logic for custom sessions should be tightened to fail if the required macaroon recipe is missing.

Comment thread cmd/litcli/sessions.go
"determine the permissions a user has when " +
"connecting with the session; options " +
"include readonly|admin|account|custom.",
"include readonly|admin|custom.",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Removing the account type from the CLI is a breaking change for users who rely on this preset. While the new --account_id flag allows for more granular control, the account type still serves as a useful preset for the standard set of permissions defined in accounts.MacaroonPermissions. It is recommended to keep it as an option.

include readonly|admin|account|custom.",

Comment thread cmd/litcli/sessions.go
Comment on lines 147 to 148
case "custom":
return litrpc.SessionType_TYPE_MACAROON_CUSTOM, nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

Since the account session type is still supported by the RPC server and provides a specific set of permissions, it should remain available in the CLI parser to avoid breaking existing scripts and to provide a convenient preset for users.

Suggested change
case "custom":
return litrpc.SessionType_TYPE_MACAROON_CUSTOM, nil
case "account":
return litrpc.SessionType_TYPE_MACAROON_ACCOUNT, nil
case "custom":
return litrpc.SessionType_TYPE_MACAROON_CUSTOM, nil

Comment thread session_rpcserver.go
Comment on lines +503 to 505
if sess.MacaroonRecipe != nil {
permissions = sess.MacaroonRecipe.Permissions
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

For TypeMacaroonCustom and TypeAutopilot, the session's permissions are stored within the MacaroonRecipe. If the recipe is missing, the session is in an invalid state and should fail to resume, similar to how TypeMacaroonAccount is handled above. Proceeding with empty permissions would result in a session that cannot perform any actions.

Suggested change
if sess.MacaroonRecipe != nil {
permissions = sess.MacaroonRecipe.Permissions
}
if sess.MacaroonRecipe == nil {
return fmt.Errorf("invalid session, expected " +
"recipe to be set")
}
permissions = sess.MacaroonRecipe.Permissions

@lightninglabs-deploy

Copy link
Copy Markdown

@Liongrass, remember to re-request review from reviewers when ready

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