@@ -15,24 +15,93 @@ underlying LDK Node documentation.
1515
1616## Authentication
1717
18- Every gRPC request must include an ` x-auth ` metadata header with an HMAC-SHA256 signature:
18+ Every gRPC request must include a ` macaroon ` metadata header containing a hex-encoded v2
19+ binary macaroon:
1920
21+ ``` text
22+ macaroon: <hex-encoded-macaroon>
2023```
21- x-auth: HMAC <unix_timestamp>:<hmac_hex>
22- ```
2324
24- Where:
25+ Macaroons use the standard HMAC-SHA256 key derivation and signature chain. The server supports
26+ first-party caveats only. It rejects third-party caveats, unknown conditions, malformed tokens,
27+ and tokens larger than 4096 binary bytes (8192 hex characters), with at most 32 caveats.
28+ An optional location field is a routing hint and is never used for authorization.
29+
30+ A macaroon is a bearer credential: anyone who obtains it can use its permitted operations.
31+ TLS is required. There is no per-request signature, body binding, or automatic replay protection.
32+ The old ` x-auth ` HMAC scheme and API keys are no longer accepted. Upgrade clients together with
33+ the server and supply the generated ` macaroons/admin.macaroon ` file or a scoped macaroon.
34+ The old ` api_key ` file is not imported.
35+
36+ ### Caveats and delegation
2537
26- - ` unix_timestamp ` is the current time in seconds since the Unix epoch
27- - ` hmac_hex ` is the hex-encoded result of
28- ` HMAC-SHA256(api_key_bytes, timestamp_be_bytes || grpc_request_body_bytes) `
29- - ` api_key_bytes ` is the API key string encoded as UTF-8 bytes
30- - ` timestamp_be_bytes ` is the timestamp as a big-endian 8-byte unsigned integer
31- - ` grpc_request_body_bytes ` is the raw gRPC request body sent over HTTP/2, including
32- the 5-byte gRPC message frame
38+ All caveats must pass. Supported conditions use these exact forms:
3339
34- The server rejects requests where the timestamp differs from the server's clock by more than
35- ** 60 seconds** .
40+ | Caveat | Meaning |
41+ | --------| ---------|
42+ | ` permissions = node:read,payments:read ` | Permit only these capabilities |
43+ | ` method = GetNodeInfo ` | Permit only this RPC method name |
44+ | ` time-before = 1800000000 ` | Require server Unix time to be strictly less than this value |
45+
46+ Additional permission caveats intersect existing permissions. Adding ` permissions = admin `
47+ to a restricted token does not restore admin access. Additional expiry conditions can only
48+ shorten its lifetime. Unknown or malformed conditions deny access.
49+
50+ Restrict a token locally, without contacting the server:
51+
52+ ``` bash
53+ ldk-server-cli attenuate-macaroon " $MACAROON " \
54+ --caveat ' permissions = node:read' \
55+ --caveat ' method = GetNodeInfo' \
56+ --caveat " time-before = $EXPIRY_UNIX_SECONDS "
57+ ```
58+
59+ The command prints a hex token. The Rust client provides ` macaroon::attenuate_macaroon ` for the
60+ same operation. Give the restricted copy to the application and keep the original private.
61+
62+ Each ` CreateMacaroon ` call creates an independent root ID. Locally restricted copies retain
63+ the parent's ID; revoking that ID invalidates all such copies. To revoke clients independently,
64+ issue a separate macaroon for each client. The server cannot list copies made locally.
65+ Tokens created through the API inherit all the caller's caveats as well as their requested
66+ permissions. They have independent revocation IDs, so revoking the issuing credential does not
67+ revoke those separately issued tokens. Root keys are never returned by the API.
68+
69+ Authorization, including expiry, is checked when a request or event subscription starts.
70+ Revocation and expiry do not close an existing event stream. Reconnecting requires a valid token.
71+
72+ ### Macaroon Permissions
73+
74+ Each macaroon has one or more capabilities. New RPCs are denied to scoped macaroons until they have an
75+ explicit capability mapping. The ` admin ` capability grants unrestricted access and must be used by
76+ itself.
77+
78+ | Capability | Access |
79+ | ------------------------| ---------------------------------------------------------------|
80+ | ` node:read ` | Node information, balances, and pathfinding scores |
81+ | ` onchain:receive ` | Create on-chain receive addresses |
82+ | ` onchain:send ` | Send on-chain funds |
83+ | ` invoices:create ` | Create BOLT11/BOLT12 invoices and incoming refund requests |
84+ | ` payments:read ` | Read payments and forwarded payments |
85+ | ` payments:claim ` | Claim or fail held BOLT11 payments |
86+ | ` payments:send ` | Send BOLT11, BOLT12, spontaneous, unified, and refund payments |
87+ | ` channels:read ` | List channels |
88+ | ` channels:manage ` | Open, configure, or cooperatively close channels |
89+ | ` channels:splice ` | Splice funds in or out, including to an external address |
90+ | ` channels:force_close ` | Force-close channels |
91+ | ` peers:read ` | List peers |
92+ | ` peers:manage ` | Connect or disconnect peers |
93+ | ` messages:sign ` | Sign messages and create BOLT12 payer proofs |
94+ | ` messages:verify ` | Verify message signatures |
95+ | ` graph:read ` | Read network graph data |
96+ | ` utilities:read ` | Decode invoices and offers |
97+ | ` events:read ` | Subscribe to the event stream |
98+ | ` macaroons:manage ` | Create, list, and revoke macaroons without privilege escalation |
99+
100+ Use ` CreateMacaroon ` , ` ListMacaroons ` , ` RevokeMacaroon ` , and ` GetPermissions ` to manage credentials.
101+ ` CreateMacaroon ` returns the hex bearer credential in ` token ` ; list operations return metadata
102+ only. ` GetPermissions ` reports the effective permissions and caveats of the calling token. The CLI also provides ` readonly ` , ` invoice ` , and
103+ ` admin ` presets. MCP exposes the same operations as ` create_macaroon ` , ` list_macaroons ` ,
104+ ` revoke_macaroon ` , and ` get_permissions ` tools.
36105
37106## TLS
38107
@@ -67,9 +136,10 @@ Errors are returned as standard gRPC status codes:
67136| gRPC Code | Meaning |
68137| ---------------------------| ------------------------------------------------------------------|
69138| ` INVALID_ARGUMENT ` (3) | Malformed request or invalid parameters |
139+ | ` PERMISSION_DENIED ` (7) | Valid macaroon without the required capability or with an unsatisfied caveat |
70140| ` FAILED_PRECONDITION ` (9) | Lightning operation error (e.g., insufficient balance, no route) |
71141| ` INTERNAL ` (13) | Server-side bug |
72- | ` UNAUTHENTICATED ` (16) | Missing or invalid ` x-auth ` header |
142+ | ` UNAUTHENTICATED ` (16) | Missing, invalid, or revoked macaroon |
73143
74144The ` grpc-message ` trailer contains a human-readable error description.
75145
@@ -232,6 +302,21 @@ Use events as notifications. After reconnecting, reconcile recoverable state wit
232302` GetPaymentDetails ` , ` ListPayments ` , ` ListForwardedPayments ` , and ` ListChannels ` . Some event fields
233303cannot be recovered through these APIs.
234304
305+ ### Macaroon Management
306+
307+ | RPC | Description |
308+ | ------------------| ---------------------------------------------------------------|
309+ | ` CreateMacaroon ` | Create a scoped macaroon and return its token |
310+ | ` ListMacaroons ` | List root IDs, names, permissions, and inherited caveats |
311+ | ` RevokeMacaroon ` | Revoke a key for new requests |
312+ | ` GetPermissions ` | Return the calling token’s ID, name, effective permissions, and caveats |
313+
314+ The first three RPCs require ` macaroons:manage ` or ` admin ` . A scoped key manager cannot create or
315+ revoke a key with permissions that it does not have. The final admin key cannot be revoked.
316+ Revoking a key blocks new requests, including new event subscriptions. Existing event streams
317+ remain open and continue to receive events until the client disconnects or the server stops.
318+ Authorization is checked only when a subscription starts.
319+
235320### Metrics
236321
237322Metrics are served as a plain HTTP GET endpoint (not gRPC):
0 commit comments