From bd1d4199128e6c7b693eaea03695fea3a7891e57 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 6 Jun 2023 19:32:59 -0700 Subject: [PATCH] blip-0026: L402 - Lightning HTTP 402 Protocol In this commit, we add a bLIP for the L402 (formerly known as LSAT) protocol. The L402 protocol presents a standardized way of adding LN micropayments to any existing HTTP-REST or gRPC API. The L402 protocol repurposes the HTTP 402 Payment Required error code with the necessary authentication headers required to bind a request's validity to the payment of an LN invoice. Macaroons are used as flexible authentication credentials (supports custom caveats, attenuation, etc) which allow an L402 reverse-proxy to validate an L402 API key without backend LN node interaction for each request (the macaroon commits to the payment hash). --- blip-0026.md | 712 ++++++++++++++++++++++++++++++++++++ blip-0026/e2e-flow.plantuml | 67 ++++ blip-0026/e2e-flow.png | Bin 0 -> 47487 bytes 3 files changed, 779 insertions(+) create mode 100644 blip-0026.md create mode 100644 blip-0026/e2e-flow.plantuml create mode 100644 blip-0026/e2e-flow.png diff --git a/blip-0026.md b/blip-0026.md new file mode 100644 index 0000000..bb17eac --- /dev/null +++ b/blip-0026.md @@ -0,0 +1,712 @@ +``` +bLIP: 26 +Title: L402: The Lightning HTTP 402 Protocol +Status: Active +Author: Olaoluwa Osuntokun + Oliver Gugger + Wilmer Paulino +Created: 2023-06-06 +License: CC0 +``` + +* [Abstract](#abstract) +* [Copyright](#copyright) +* [Motivation](#motivation) + * [The Forgotten HTTP Error Code](#the-forgotten-http-error-code) + * [Authentication and API Payments in a Lightning-Native Web](#authentication-and-api-payments-in-a-lightning-native-web) + * [HTTP + Macaroons + Lightning = L402](#http-+-macaroons-+-lightning-=-l402) + * [Example Applications and Use Cases](#example-applications-and-use-cases) +* [Rationale](#rationale) +* [Specification](#specification) + * [Authentication Flow](#authentication-flow) + * [Detailed authentication flow](#detailed-authentication-flow) + * [L402 HTTP/gRPC Protocol Specification](#l402-http/grpc-protocol-specification) + * [Reusing Credentials](#reusing-credentials) + * [Security Considerations](#security-considerations) + * [HTTP Specification](#http-specification) + * [gRPC Protocol Specification](#grpc-protocol-specification) + * [Macaroon Minting & Verification](#macaroon-minting-&-verification) +* [Macaroon Minting & Verification](#macaroon-minting-&-verification) + * [Minting Macaroons](#minting-macaroons) + * [Macaroon Identifier](#macaroon-identifier) + * [Attenuation Through Caveats](#attenuation-through-caveats) + * [Target Services](#target-services) + * [Service Capabilities](#service-capabilities) + * [Service Constraints](#service-constraints) + * [Macaroon Verification](#macaroon-verification) + * [Macaroon Revocation](#macaroon-revocation) +* [Universality](#universality) +* [Backwards Compatibility](#backwards-compatibility) +* [Reference Implementation](#reference-implementation) + +# Abstract + +L402 is a standard to support the use case of charging for services and +authenticating users in distributed networks. Developed by Lightning Labs, it +combines the strengths of Macaroons, for better authentication, and the +strengths of the Lightning Network, for better payments. L402 API credentials +invigorate the HTTP 402 Payment Required error code by combining the +fine-grained authentication capabilities of Macaroons with Lightning Network +payments, making it easy to charge amounts of any size for an API request, web +page or resource. + +An L402 key is created like a Macaroon. It combines the advantages of bearer +and identity-based authentication systems that can quickly be issued and +verified without requiring access to a central database. + +In addition to a regular Macaroon, an L402 includes a payment hash, which is +presented to the user with a Lightning Network invoice. The user can prove +their successful payment if the preimage matches the payment hash. + +A valid L402 key , meaning a Macaroon issued by the service and the preimage +obtained by the user, is easy to verify by distributed systems. Instead of +looking up cookies or payment details using centralized databases, an L402 key +can be verified using minimal information and basic cryptography. + +This system allows users to automate pricing on the fly and enables a number of +novel constructs such as automated tier upgrades. L402 get its name from the +HTTP status code 402: Payment Required. + +# Copyright + +This bLIP is licensed under the CC0 license. + +# Motivation + +In this document we aim to specify a protocol standard of what we call an +`L402`. `L402` is derived from HTTP status code 402: Payment Required. L402 is +a new standard protocol for authentication and paid APIs developed by Lightning +Labs. An L402 can serve both as authentication, as well as a payment mechanism +\(one can view it as a ticket\) for paid APIs. By leveraging L402, a service or +business is able to offer a new tier of paid APIs that sit between free, and +subscription: pay as you go. + +One can view L402 as a fancy authentication credential or cookie. They differ +from regular cookies in that they're a cryptographically verifiable bearer +credential. An L402 credential _encodes_ all its capabilities within a macaroon +which can only be created by the end service provider. The L402 specification +uses a combating of `HTTP` as well as the Lightning Network to create a +seamless end-to-end payment+authentication flow for the next-generation of paid +APIs built on top of the Lightning Network. + +The system described above isn't a fantasy, L402 is used _today_ by Lightning +Labs to serve as an authentication+payment solution for Lightning Loop, a +non-custodial on/off ramp for the Lightning Network and Lightning Pool, a +non-custodial market place for liquidity in the Lightning Network. Lightning +Labs, has also open sourced `aperture`, a reference L402 aware reverse-proxy +used in production for all our systems. In the remainder of this section, we'll +explore the motivation, lineage, and workflow of L402 at a high level. For a +more detailed speciation, please see the later sections of this specification. + +## The Forgotten HTTP Error Code + +HTTP as we know it today uses a number of _error_ codes to allow developers to +easily consume APIs created by service providers. As an example, the well known +`200 OK` error code indicates a successful HTTP response. The `401 +Unauthorized` is sent when a client attempts to access a page or resource that +requires authentication, and so on. A large number of other error code exist, +with some more commonly used than others. One error code which has widely been +underutilized is: `402 Payment Required`. As the name entails, this code is +returned when a client attempts to access a resource that they haven't _paid +for_ yet. In most versions of the HTTP specification, this code is marked as +being "reserved for future use". Many speculate that it was intended to be used +by some sort of digital cash or micropayment scheme, which didn't yet exist at +the time of the initial HTTP specification drafting. + +However, several decades later, we _do_ have a widely used digital cash system: +Bitcoin! On top of that, a new network oriented around micropayments has also +arisen: the Lightning Network. Early in the lifetime of Lightning Labs, we were +drawn to the potential for paid metered APIs enabled by the Lightning Network. +We'd solved the payment portion with LN itself, the next challenge was to +create a protocol that would be easy to drop into _existing_ APIs in an easy +and extensible manner. Our solution to this is the L402 protocol. + +## Authentication and API Payments in a Lightning-Native Web + +Lightning has the potential to serve as the de-facto payment method to access +services and resources on the web. In this new web, rather than a user being +tracked across the web with invisible pixels to serve invasive ads, or users +needing to give away their emails subjecting themselves to a lifetime of spam +and tracking, what if a user was able to _pay_ for a service and in the process +obtain a ticket/receipt which can be used for future authentication and access? + +In this new web, email addresses and passwords are a thing of the past. Instead +_cryptographic bearer credentials_ are purchased and presented by users to +access services and resources. In this new web, credit cards no longer serve as +a gatekeeper to all the amazing experiences that have been created. L402 +enables the creation of a new more global, more private, more developer +friendly web. + +At this point, curious users may be wondering: How would such a scheme work? +Are the payment and receipt steps atomic? Why can't a user just forge one of +these "tickets"? + +## HTTP + Macaroons + Lightning = L402 + +An L402 is essentially a ticket obtained over Lightning for a particular +service or resource. The ticket itself _encodes_ what resource it's able to +access. It can be copied, or given to a friend so they can access that same +resources. It can also be _attenuated_ to provide a friend access to a slightly +weaker version of that resource \(able to stream video at only 480p as an +example\). On the other end, services can mint special tickets for particular +users, rotate, upgrade, and even revoke the tickets. + +The tickets themselves are actually _macaroons_. Macaroons are a flexible +standard for API credentials which are already used by `lnd` as its default +authentication mechanism. The L402 protocol allows a user to _atomically_ +purchase one of these tickets for sats over the Lightning Network. Partial L402 +are served over HTTP \(or HTTP/2\) when a user attempts to access a resource +that requires payment \(`402 Payment Required`\) along with a Lightning +_invoice_. This _partial_ L402 can then be converted into a _complete_ L402 by +paying the invoice, and obtaining the payment pre-image \(the invoice pays to a +payment hash: `payment_hash = sha256(pre_image)`\). + +With proper integration at end clients, Lightning wallets, mobile application, +browsers \(and extensions\), the above flow has potential to be even more +seamless than the credit card flow users are accustomed to today. It's also +more _private_ as the server doesn't need to know _who_ paid for the ticket, +only that it was successfully paid for. + +## Example Applications and Use Cases + +The L402 standard enables a number of new use cases, pricing models, and +applications to be built, all using the Lightning Network as a primary money +rail. As the standard is also defined over _HTTP/2_, it can be naturally +extended to also support gating access to existing _gRPC_ services. This is +rather powerful as it enables a _strong decoupling_ of authentication+payment +logic from application logic. Today Lightning Loop uses L402s in this very +manner to provide a lightweight authentication mechanism for our users. + +As L402 leverages the Lightning Network for its payment capabilities, they also +enable the easy creation of _metered_ APIs. A metered API is one where the user +is able to pay for the target resource or service as they go rather than +needing to commit to a subscription up front. Developers can use L402 to create +applications that charge users on an on going basis for resources like compute +or disk space. If the user stops paying, then the resource can be suspended, +collected, and re-allocated for another paying user. Once again, as the +standard supports _gRPC_ which supports _bi directional streaming_ APIs, one +could even create a metered streaming video or audio service as well! + +Additionally, L402 also enables innovation at the API _architecture_ level. One +example is automated tier upgrades. Many APIs typically offer several tiers +which allow users to gain access to more or additional resources as they climb +up the ladder. Typically, a user must _manually_ navigate a web-page to request +an upgrade to a higher tier, or downgrade to a lower tier. With the L402 +standard, tier upgrades can easily be automated: the user hits a new endpoint +to obtain an _upgraded_ L402 which _encodes_ additional functionality or +increased resource access compared to the prior tier. Services can even +leverage L402 for A/B Testing by giving subsets of users a distinct L402 which +when submitted to the service, render a slightly different version of the +target resource or service. + + +# Rationale + +# Specification + +## Authentication Flow + +This section explains the high-level authentication flow from the perspective +of a user and their client software. + +The requirements from the user's point of view are simple: They want to be able +to use a service as frictionless as possible. They are perhaps used to the +concept of needing to obtain an API access key first in order to use a service, +but do not necessarily want to register an account with their personal +information to do so. + +A service using the L402 protocol supports exactly that requirement: The use of +an API key without the need for creating an account first. And because no +information needs to be input, the process of obtaining the API key can happen +transparently to the user, in the background. + +Whenever an L402-compatible client software connects to a server that uses the +protocol, it receives a prompt to pay an invoice over a very small amount \(a +few satoshis\). Once the client software pays that invoice \(which can happen +automatically if the amount does not exceed a user-defined threshold\), a valid +API key or authentication token can be constructed. That credential is stored +by the client's software and will be used for all future requests. + +### Detailed authentication flow + +The following steps describe the diagram further below. It is the flow of calls +that take place for a client software that wants to access a protected resource +that is secured by an authentication server. + +As an example, we will look at the `loopd` client that wants to do a loop out +swap with the Lightning Lab's loop server. + +**First time looping out**: + +1. A loop user wishes to perform a swap with the loop server. They type the + command `loop out ` and hit return. + +2. The `loopd` client program contacts the loop server to initiate the swap. + +3. The call from the client must always go through the authentication server + reverse proxy, which in this example is `aperture`. The authentication proxy + notices that the client didn't send an L402 and therefore cannot be granted + access to the loop server. + +4. `aperture` instructs its own `lnd` instance to create an invoice over a + small amount that is required to acquire a fresh credential. + +5. In addition to the invoice, `aperture` also creates a fresh access + credential that is tied to the invoice. The credential is cryptographically + constructed in a way that it is only valid once the invoice has been paid. + +6. The credential and the invoice are sent back to the client in the previously + unused HTTP header `402 Payment Required`. + +7. The `loopd` understands this returned error code, extracts the invoice from + it and automatically instructs its connected `lnd` instance to pay the + invoice. + +8. Paying the invoice results in the `loopd` client now possessing the + cryptographic proof of payment \(the pre-image\). This proof is stored in + the client's local storage, together with the access credential. + +9. The combination of the access credential and the pre-image yields a fully + valid L402 that can be cryptographically verified. + +10. The client now repeats the original request to the loop server, now + attaching the L402 to the request. + +11. The authentication server intercepts the request, extracts the L402 and + validates it. Because the L402 is valid, the request is forwarded to the + actual loop server that then initiates the swap. + +12. The answer of the swap server is returned to the client and the swap is now + initiated. + +13. The whole process is fully transparent to the user. The only thing they + might notice is a short delay of a few seconds on the first ever loop. Each + successive loop will use the same credential and will not be delayed at + all. + +![e2e flow sequence diagram](bip-00026/e2e-flow.png) + +**All further loops**: + +1. For every new request to the server, the client now automatically attaches + the credential that is stored locally. + +2. As long as the credential has not expired, the steps 9-13 above will be + followed. If/when the credential expires, the server will start over at + step 4 and instruct + the client to obtain a fresh credential. + + +## L402 HTTP/gRPC Protocol Specification + +This section defines the "L402" authentication scheme, which transmits +credentials as `:` pairs, where the preimage is encoded +as hex and the Macaroon is encoded as base64. Multiple Macaroons are base64 +encoded individually and listed comma separated before the colon. This scheme +is not considered to be a secure method of user authentication unless used in +conjunction with some external secure system such as TLS, as the Macaroon and +preimage are passed over the network as cleartext. + +The L402 authentication scheme is based on the model that the client needs to +authenticate itself with a Macaroon and invoice preimage for each backend +service it wants to access. The server will service the request only if it can +validate the Macaroon and preimage for the particular backend service +requested. + +The L402 authentication scheme utilizes the Authentication Framework specified +in [_RFC 7235_](https://tools.ietf.org/html/rfc7235) as follows. + +In challenges: the scheme name is "L402". Note that the scheme name is +case-insensitive. For credentials, the syntax is: + +`macaroons` → [_<base64 encoding>_](https://tools.ietf.org/html/rfc3548#section-3), comma separated if multiple Macaroons are present +`preimage` → [_<hex encoding>_](https://tools.ietf.org/html/rfc3548#section-6) +`token` → macaroons ":" preimage + +Specifically, the syntax for "token" specified above is used, which can be +considered comparable to the [_"token68" +syntax_](https://tools.ietf.org/html/rfc7235#section-2.1) used for HTTP basic +auth. + +### Reusing Credentials + +L402 is intended to be reused until they are revoked and the server issues a +new challenge in response to a client request containing a newly invalid L402. +Possible revocation conditions include: expiry date, exceeded N usages, volume +of usages in a certain time period necessitating a tier upgrade, and +potentially others \(discussed further in the higher-level design document\). + +L402 could be configured for use on a per-backend-service basis or for all +Lightning Labs services. I.e., it’s flexible whether an L402 could apply to +both the Bos score API _and_ a loop-in, or just one of them. This flexibility +is afforded because all services are going to be gated by the same L402 proxy, +which verifies all Macaroons for all backend services. + +### Security Considerations + +If a client’s L402 is intercepted by Mallory, which is possible if the +transmission is not encrypted in some way such as TLS, the L402 can be used by +Mallory and the L402 proxy would not be able to distinguish this usage as +illicit. + +L402 authentication is also vulnerable to spoofing by counterfeit servers. If a +client slightly mistypes the URL of a desired backend service, they become +vulnerable to spoofing attacks if connecting to a server that maliciously +stores their L402 and uses it for their own purposes. This attack could be +addressed by requiring the user of the L402 to have a specific IP address. +However, there are downsides to this approach; for example, if a user switches +WiFi networks, their credential becomes unusable. + +### HTTP Specification + +In this section, we specify the protocol for the HTTP portion of the L402 +proxy. + +Upon receipt of a request for a URI of an L402-proxied backend service that +lacks credentials or contains an L402 that is invalid or insufficient in some +way, the server should reply with a challenge using the 402 \(Payment +Required\) status code. **Officially, in the HTTP RFC documentation, status +code 402 is** [_**"reserved for future +use"**_](https://tools.ietf.org/html/rfc7231#section-6.5.2) **-- but this +document assumes the future has arrived.** + +Alongside the 402 status code, the server should specify the `WWW-Authenticate` +header \([_\[RFC7235\], Section +4.1_](https://tools.ietf.org/html/rfc7235#section-4.1)\) field to indicate the +L402 authentication scheme and the Macaroon needed for the client to form a +complete L402. + +For instance: + +```text + HTTP/1.1 402 Payment Required + +Date: Mon, 04 Feb 2014 16:50:53 GMT + +WWW-Authenticate: L402 macaroon="AGIAJEemVQUTEyNCR0exk7ek90Cg==", invoice="lnbc1500n1pw5kjhmpp5fu6xhthlt2vucmzkx6c7wtlh2r625r30cyjsfqhu8rsx4xpz5lwqdpa2fjkzep6yptksct5yp5hxgrrv96hx6twvusycn3qv9jx7ur5d9hkugr5dusx6cqzpgxqr23s79ruapxc4j5uskt4htly2salw4drq979d7rcela9wz02elhypmdzmzlnxuknpgfyfm86pntt8vvkvffma5qc9n50h4mvqhngadqy3ngqjcym5a" +``` + +where `"AGIAJEemVQUTEyNCR0exk7ek90Cg=="` is the Macaroon that the client must +include for each of its authorized requests and `"lnbc1500n1pw5kjhmpp..."` is +the invoice the client must pay to reveal the preimage that must be included +for each of its authorized requests. + +In other words, to receive authorization, the client: + +1. Pays the invoice from the server, thus revealing the invoice’s preimage +2. Constructs the L402 by concatenating the base64-encoded Macaroon\(s\), a single + + colon \(":"\), and the hex-encoded preimage. + +Since the Macaroon and the preimage are both binary data encoded in an ASCII +based format, there should be no problem with either containing control +characters or colons \(see "CTL" in [_Appendix B.1 of +\[RFC5234\]_](https://tools.ietf.org/html/rfc5234#appendix-B.1)\). If a user +provides a Macaroon or preimage containing any of these characters, this is to +be considered an invalid L402 and should result in a 402 and authentication +information as specified above. + +If a client wishes to send the Macaroon `"AGIAJEemVQUTEyNCR0exk7ek90Cg=="` +\(already base64-encoded by the server\) and the preimage +`"1234abcd1234abcd1234abcd"` \(already hex encoded by the payee's Lightning +node\), they would use the following header field: + +```text +Authorization: L402 AGIAJEemVQUTEyNCR0exk7ek90Cg==:1234abcd1234abcd1234abcd +``` + +### gRPC Protocol Specification + +This section defines the "L402" gRPC authentication scheme, which, similarly to +the HTTP version, transmits credentials as `:` pairs +where the preimage is encoded as hex and the Macaroon is encoded as base64. +Multiple Macaroons are base64 encoded individually and listed comma separated +before the colon. As above, this scheme is not considered to be a secure method +of user authentication unless used in conjunction with some external secure +system such as TLS, as the Macaroon and preimage are passed over the network as +cleartext. + +The L402 proxy will determine whether an incoming HTTP request is gRPC by +checking whether the Content-Type header begins with application/grpc, +therefore gRPC clients must set this header in all requests. + +Note that the L402 proxy must be HTTP/2 compatible to accommodate requests for +gRPC backend services, since the gRPC client expects to be talking to a server +that "speaks" HTTP/2. + +Upon receipt of a request for a URI of an L402-proxied backend service that +lacks L402 credentials, the server should reply with a challenge encoded in the +grpc-status-details-bin HTTP header as a serialized gRPC Status proto message, +to be deserialized on the client side. Once deserialized, the proto will look +roughly like this object: + +```javascript +{ + code: 402, + message: "missing L402", + details: { + type_url: "type.googleapis.com/google.rpc.QuotaFailure", + value: { + macaroon: "", + invoice: "" + } + } +} +``` + +Note that deserialization is language-dependent. In Go, it looks something like +this: + +```go +_, err := client.AccessBackendService(ctx, &pb.BackendServiceRequest{}) +If err != nil { + st, _ := status.FromError(err) + message := st.Message() // get message + code := st.Code() // get code + for _, detail := range st.Details() { + switch t := detail.(type) { + case *errdetails.QuotaFailure: + for _, violation := range t.GetViolations() { + // parse macaroon from "macaroon:<mac>" format + // parse invoice from "invoice:<inv>" format +… +``` + +Serialization is similarly language-dependent. + +Depending on the context, QuotaFailure may not be the most descriptive error +message, but it fits a scenario where a user has exceeded their free "trial +period" for a backend service. + +Alongside the serialized status details, the server should specify status code +`200 OK`, the `Content-Type` header, and the following trailers: `grpc-message` +and `grpc-status`. + +For instance: + +```text +HTTP/2 200 OK +Date: Mon, 04 Feb 2014 16:50:53 GMT +Content-Type: application/grpc +… +Grpc-Message: missing L402 +Grpc-Status: 402 +Grpc-Status-Details-Bin: CJIDEgxtaXNzaW5nIExTQVQaeQ… +``` + +Where `"CJIDEgxtaXNzaW5nIExTQVQaeQ…"` is the serialized gRPC status proto. + +Once the client has deserialized the proto and extracted the Macaroon and +invoice, they may pay the invoice and construct the L402 identically to the +HTTP specification, i.e. by concatenating the base64-encoded Macaroon, a single +colon \(":"\), and the hex-encoded preimage. + +If a client wishes to send the Macaroon `"AGIAJEemVQUTEyNCR0exk7ek90Cg=="` +\(already base64-encoded by the server\) and the preimage +`"1234abcd1234abcd1234abcd"` \(already hex encoded by the payee's Lightning +node\), they would use the following header field: + +```text +Authorization: L402 AGIAJEemVQUTEyNCR0exk7ek90Cg==:1234abcd1234abcd1234abcd +``` + +Note this is the same as the HTTP specification. Other gRPC headers and +trailers are required; more information can be found in the [_gRPC over HTTP2 +specification_](https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md). + + +## Macaroon Minting & Verification + +# Macaroon Minting & Verification + +In this section, we outline the specification of the Macaroon component of a +Lightning API key \(L402\). To recap, an L402 is composed of a Macaroon, which +specifies the allowed capabilities of the credential, and a preimage, which +serves as the credential’s proof of payment. Macaroons are perfect candidates +for L402 as they are tamper-proof, support easy rotation, have attributes, and +can even be further attenuated in order for applications that integrate an L402 +enabled service to delegate any additional capabilities. We’ll cover how +Macaroons are created, attenuated, and verified as part of L402. This chapter +will require an understanding of how Macaroons work and how they are useful in +the context of authentication. It may be useful to skim the [introductory +research paper on Macaroons](https://research.google/pubs/pub41892/). + +## Minting Macaroons + +Macaroons have three basic components: a public identifier that maps to a root +key, a list of caveats \(which is how attenuation is achieved\), and a +signature. Minting a new Macaroon only requires the public identifier and the +root key it corresponds to. + +Each Macaroon must have its own cryptographically random root key that must not +be disclosed to prevent forgeability of Macaroons. Each root key consists of 32 +bytes, which provides a reasonable tradeoff between entropy and size. Root keys +are essential to the verification of Macaroons, so they must be stored securely +and reliably. + +### Macaroon Identifier + +The key mapping to the secret is the SHA-256 hash of the Macaroon’s public +identifier, which contains static information about the Macaroon itself. In the +initial construction, the public identifier should include the following in the +listed order: + +> Note: All data specified here are encoded in big-endian unless otherwise +> stated. + +* **Version** - A version allows for an iterative Macaroon design. It must be + encoded in 2 bytes unsigned integer. +* **Payment Hash** - A payment hash links an invoice’s payment request to the + Macaroon. Once the payment request is fulfilled, the payer receives its + corresponding preimage as proof of payment. This proof can then be provided + along with the Macaroon to ensure an L402 has been paid for without checking + whether the invoice has been fulfilled. +* **User Identifier** - A unique user identifier allows services to track users + across distinct Macaroons serving useful in the context of service level + metering. A user identifier of 32 random bytes is used instead of the + macaroon's identifier because the latter can be revoked, e.g., in the case of + a service tier upgrade. + + +### Attenuation Through Caveats + +Caveats are predicates that restrict a Macaroon’s authority, as well as the +context in which it may be successfully used. When verifying a Macaroon, each +caveat predicate must be evaluated and hold true. Due to their flexibility, +additional context found within the request to a service may be necessary for +proper evaluation. + +Caveats of a version 0 Macaroon are represented as key-value pairs encoded as a +string where the key and value are separated by a single `=` character. The key +uniquely identifies a caveat and provides context as to how it should be +evaluated, while the value provides context for the evaluation itself. There +aren't any further restrictions on how caveats should be formed, but Lightning +Labs services will mostly impose three types of caveats which are covered +below. + +#### Target Services + +The target services the Macaroon is allowed to access is represented as a +caveat. The caveat key is `services`, while the value consists of a +comma-separated list of target services. Each target service is composed of a +two-tuple consisting of the service name and its tier. Tiers are service +specific and must start from 0, which serves as the base tier. If a specific +service tier has its capabilities and/or constraints updated, there needs to be +a way to detect when a Macaroon of the same tier with the now outdated +capabilities and/or constraints is being used. By committing to the service +tier, it is possible to detect such cases and seamlessly upgrade the stale +Macaroon \(assuming it is valid\) by revoking it and minting a new Macaroon +with the newer capabilities and/or constraints. + +When verifying this caveat, if a Macaroon is attempting to access a service +that it does not commit to, then it should be considered invalid. If multiple +services caveats exist, then verification should ensure each occurrence of the +caveat restricts more access than the previous. + +#### Service Capabilities + +Each service can further be restricted by the capabilities the service provides +and these are also represented as another caveat. These caveats have a key +ending in `_capabilities` that is prefixed with the service name, while the +value consists of a comma-separated list of the allowed service capabilities. +This type of caveat allows certain Macaroons to only have access to a subset of +a service's features. + +If a capabilities caveat for a particular service is not present, then the +Macaroon is able to access any capability of the service. If multiple +capabilities caveats exist for the same service, then verification should +ensure each occurrence of the caveat restricts more access than the previous. + +#### Service Constraints + +Each service can define its own set of constraint caveats for a given tier to +further restrict the capabilities of a Macaroon. Each constraint takes the form +of a caveat, where the key is prefixed with the service capability it applies +to, and the remainder of the key includes context for the service on how to +evaluate the constraint. The caveat value specifies the parameters for the +constraint evaluation. + +If multiple caveats of the same constraint are found within a Macaroon, then +verification should ensure each occurrence of the constraint restricts more +access than the previous. + +As an example, a base tier Lightning Loop Macaroon with access to a 2 BTC +monthly volume for Loop Out and unlimited volume for Loop In would look like: + +```text +identifier: + version = 0 + user_id = fed74b3ef24820f440601eff5bfb42bef4d615c4948cec8aca3cb15bd23f1013 + payment_hash = 163102a9c88fa4ec9ac9937b6f070bc3e27249a81ad7a05f398ac5d7d16f7bea +caveats: + services = lightning_loop:0 + lightning_loop_capabilities = loop_out,loop_in + loop_out_monthly_volume_sats = 200000000 +``` + +Due to the flexibility of the design, a Macaroon holder is able to further +attenuate a Macaroon if they wish to share it with a third party under more +restrictive permissions. Following the example above, the Macaroon holder can +restrict the Macaroon’s capabilities to only allow access to Loop In \(and not +Loop Out\) with a monthly volume of 1 BTC by adding the following caveats: + +```text +lightning_loop_capabilities = loop_in +loop_in_monthly_volume_sats = 100000000 +``` + +### Macaroon Verification + +Verifying a Macaroon consists of a three step process and involves two parties: +the minter of the Macaroon and the authorizer, which is the service the +Macaroon targets. The minter of the Macaroon performs signature checks to +ensure the Macaroon is valid, while the authorizer ensures the Macaroon has the +required permissions to access the service. + +The first step ensures a Macaroon was minted by the minter and it has not been +tampered with. This is done by computing the HMAC chain of the Macaroon, +starting from its root key and identifier, and including any further +attenuation through its caveats to arrive at the terminal signature of the +Macaroon. If these do not match, the Macaroon is invalid. If there isn’t a +valid root key corresponding to the Macaroon, it is also considered invalid. + +The second step ensures a Macaroon has provided a valid proof of payment +\(preimage\) and is performed by the minter as well. Since Macaroons commit to +the payment hash of an invoice, this is a trivial step. + +The final step ensures a Macaroon is authorized to access a service. This is +done by ensuring the service-specific caveat predicates of a Macaroon hold true +for the service being accessed. If only one of these caveats doesn’t hold true, +then the Macaroon is invalid. In the case of an unknown caveat, its evaluation +must be skipped by the authorizer as the Macaroon holder can further attenuate +the Macaroon for other applications. + +### Macaroon Revocation + +To prevent abusers of a Macaroon-based authenticated service, a Macaroon should +be able to be revoked. This can be achieved by having the minter remove the +Macaroon’s corresponding root key. By doing so, the minter will never be able +to verify the signature of a revoked Macaroon, ensuring it will never reach its +targeted service. + +Revocation also serves useful when performing a service tier upgrade on a +Macaroon. The prior Macaroon is revoked to ensure only the upgraded one can be +used going forward. + +# Universality + +# Backwards Compatibility + +The `L402` protocol was formerly known as `LSAT`. In order to preserve +backwards compatibility with clients, anywhere `L402` is used within HTTP +headers or requests, a valid protocol flow with the string `LSAT` should also +be accepted. + + +# Reference Implementation + +* [Aperture: A gRPC/HTTP authentication reverse proxy using L402s](https://github.com/lightninglabs/aperture) + +* [A utility library for working with L402s](https://github.com/Tierion/lsat-js) + +* [boltwall: Nodejs middleware-based authentication using L402s](https://github.com/tierion/boltwall) diff --git a/blip-0026/e2e-flow.plantuml b/blip-0026/e2e-flow.plantuml new file mode 100644 index 0000000..aa9cde8 --- /dev/null +++ b/blip-0026/e2e-flow.plantuml @@ -0,0 +1,67 @@ +` Generate image using plantuml +` http://plantuml.com/sequence-diagram + +@startuml + +title High-level end-to-end LSAT authentication flow + +participant "Client " as client +participant "Client lnd " as clnd #cccccc +participant "Auth server " as auth +participant "Auth server lnd " as alnd #cccccc +participant "Protected resource " as res #ff6666 + +group First time user + + activate client + client -> auth: GET /protected + activate auth + + auth -> auth: Check token,\nno token found + + auth -> alnd: Generate invoice + activate alnd + + alnd --> auth: Invoice + deactivate alnd + + auth -> auth: Create token \n+ invoice + + auth --> client: 402: Payment Required,\ntoken + invoice + deactivate auth + + client -> clnd: Pay invoice + activate clnd + + clnd -> alnd: Pay invoice + activate alnd + + alnd --> clnd: Preimage + deactivate alnd + + clnd --> client: Preimage + deactivate clnd + + client -> client: Add preimage to \ntoken +end + +group User with a token + + client -> auth: GET /protected,\ntoken + preimage + activate auth + + auth -> auth: Check token,\nvalidate payment + + auth -> res: GET /protected + activate res + + res --> auth: Protected content + deactivate res + + auth --> client: Protected content + deactivate auth + + deactivate client +end + +@enduml \ No newline at end of file diff --git a/blip-0026/e2e-flow.png b/blip-0026/e2e-flow.png new file mode 100644 index 0000000000000000000000000000000000000000..e495569a7062978f152a70d7fac2f4c1ace05863 GIT binary patch literal 47487 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

rx4()t1k*{*WTucm_;YTB~&QzDDkF!;Xc0*{`m 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 XKmYcK$%p<2N-}u5`njxgN@xNA==Epn literal 0 HcmV?d00001