multi: update L402 headers for bLIP-0026 token= spec revision#208
Open
Roasbeef wants to merge 8 commits into
Open
multi: update L402 headers for bLIP-0026 token= spec revision#208Roasbeef wants to merge 8 commits into
Roasbeef wants to merge 8 commits into
Conversation
In this commit, we add two new header constants (`HeaderTokenMD` and `HeaderToken`) per the bLIP-0026 spec revision, which renames the gRPC metadata key from "macaroon" to "token". The `FromHeader` function now checks these current-spec header names first, falling back to the legacy `Grpc-Metadata-Macaroon` and `Macaroon` headers for backwards compatibility. The existing `HeaderMacaroonMD` and `HeaderMacaroon` constants are retained and marked as legacy. Error messages and comments throughout `FromHeader` are updated from "macaroon" to "token" to reflect the spec terminology. The priority order is: Authorization (LSAT/L402), then current-spec metadata headers, then legacy metadata headers.
In this commit, we update `MacaroonCredential.GetRequestMetadata` to send the serialized token under both the current-spec "token" key and the legacy "macaroon" key. Previously only "macaroon" was sent, which meant a strict bLIP-0026 server that only checks for the "token" key would reject gRPC requests from this client. Sending both keys ensures forwards compatibility with new servers while maintaining backwards compatibility with servers that haven't upgraded yet.
In this commit, we update `authHeaderRegex` to accept both the current-spec `token=` key name and the legacy `macaroon=` key name in `WWW-Authenticate` challenge headers. We also handle the optional `version=` parameter prefix introduced in bLIP-0026. The regex now matches all four combinations: `LSAT macaroon=` (oldest), `L402 macaroon=` (transitional), `L402 token=` (current without version), and `L402 version="0", token=` (current with version).
In this commit, we update `FreshChallengeHeader` to emit distinct header formats for the legacy LSAT and current L402 schemes. The L402 header now uses the bLIP-0026 format with `version="0", token=...`, while the legacy LSAT header retains the old `macaroon=...` format. Previously both schemes emitted the same `macaroon=` format string. We also fix a pre-existing bug where a `MarshalBinary` failure was logged but not returned, allowing execution to continue with nil macBytes and produce an invalid challenge header with an empty token field.
In this commit, we update the `MockAuthenticator` to match the real authenticator's behavior after the bLIP-0026 spec revision. The `Accept` method now checks current-spec header names (`Grpc-Metadata-Token`, `Token`) before legacy ones, mirroring the priority order in `l402.FromHeader`. The `FreshChallengeHeader` method now emits distinct formats per scheme: `version="0", token=...` for L402 and `macaroon=...` for legacy LSAT.
In this commit, we add `Grpc-Metadata-Token`, `Token`, and `Macaroon` to the CORS `Access-Control-Allow-Headers` list alongside the existing `Grpc-Metadata-macaroon`. Without this, browser-based L402 clients using the current-spec header names would be blocked by CORS preflight checks.
In this commit, we add comprehensive tests covering the full matrix of
L402 header formats to ensure forwards and backwards compatibility
with the bLIP-0026 spec revision.
The new `l402/header_test.go` covers:
- `FromHeader` parsing all six header variants (Authorization with
LSAT/L402 schemes, Grpc-Metadata-Token, Token, Grpc-Metadata-Macaroon,
Macaroon) with correct preimage extraction in each case.
- Header priority ordering (Authorization > current-spec metadata >
legacy metadata).
- `SetHeader` emitting both LSAT and L402 Authorization values that
are each independently parseable by `FromHeader`.
- The client interceptor regex matching all format combinations:
`LSAT macaroon=` (oldest), `L402 macaroon=` (transitional), `L402
token=` (current without version), `L402 version="0", token=`
(current with version), and future version values. Invalid schemes
and missing invoice fields are rejected.
- `MacaroonCredential.GetRequestMetadata` sending both "token" and
"macaroon" gRPC keys with identical hex-encoded values.
The `auth/authenticator_test.go` gets three new cases testing that
`L402Authenticator.Accept` handles the current-spec `HeaderTokenMD`
and `HeaderToken` header names (valid and invalid).
The `l402/client_interceptor_test.go` assertions are updated to
expect two metadata keys ("token" + "macaroon") per credential, with
both carrying the same value.
In this commit, we fix tokenFromContext to also map the "token" and "macaroon" gRPC metadata keys into the HTTP header struct passed to FromHeader. Previously only the Authorization header was forwarded, which meant the standard MacaroonCredential flow (which sends data under the "token" and "macaroon" metadata keys) was never picked up by the server interceptor. The gRPC transport strips the "Grpc-Metadata-" prefix, so we map "token" to HeaderTokenMD and "macaroon" to HeaderMacaroonMD for FromHeader to find them.
ad5137a to
246610a
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In this PR, we update aperture's L402 header handling to align with the
bLIP-0026 spec revision, which generalizes the protocol from "macaroon"
to "token" terminology. The core change is that the
WWW-Authenticatechallenge header now uses
token=as the key name (with aversion=parameter for forward compatibility), while the legacy
macaroon=format is retained for backwards compatibility with existing clients.
This is the implementation counterpart to
bLIP-0026 PR #26,
which accumulated feedback from reviewers pointing out that the tight
coupling to macaroon terminology was causing potential adopters to
believe macaroons were a hard requirement. The spec now makes clear
that L402 is token-format agnostic (any token that can commit to a
payment hash works), with macaroons as the RECOMMENDED format.
See each commit message for a detailed description w.r.t the
incremental changes.
Server-Side Challenge Header
FreshChallengeHeadernow emits distinct formats per scheme. The L402header uses
version="0", token="<base64>", invoice="<bolt11>"whilethe legacy LSAT header retains the old
macaroon="<base64>", invoice="<bolt11>"format. The LSAT header is still sent first(via
header.Set) because old loop software reads only the firstWWW-Authenticatevalue.Server-Side Header Parsing
FromHeadernow checks six header variants in priority order:Authorization(LSAT/L402),Grpc-Metadata-Token,Token,Grpc-Metadata-Macaroon,Macaroon. Current-spec header names arechecked before legacy ones. The new
HeaderTokenMDandHeaderTokenconstants are added alongside the existing legacy constants (which are
retained and marked as backwards compat).
Client-Side Credential
MacaroonCredential.GetRequestMetadatanow sends the serialized tokenunder both the current-spec
"token"key and the legacy"macaroon"key. This ensures the client works with both new servers (that check
for
"token") and old servers (that only check for"macaroon").Client-Side Challenge Parsing
The
authHeaderRegexin the client interceptor now accepts bothtoken=andmacaroon=key names, with an optionalversion=parameter prefix. This handles all four format combinations a server
might send.
CORS
addCorsHeadersnow includesGrpc-Metadata-Token,Token, andMacaroonin the allowed headers list. Without this, browser-basedclients using spec-compliant header names were CORS-blocked.
Bug Fix
We also fix a pre-existing bug in
FreshChallengeHeaderwhere aMarshalBinaryfailure was logged but not returned, allowingexecution to continue with nil
macBytes.Forwards/Backwards Compatibility Tests
A new
l402/header_test.gocovers the full matrix of header formatsacross all layers:
FromHeaderparsing all six variants with correctpreimage extraction, header priority ordering,
SetHeaderdual-schemeoutput, the client interceptor regex matching all format combinations
(including future version values), and
MacaroonCredentialsendingboth gRPC metadata keys. The existing
auth/authenticator_test.goandl402/client_interceptor_test.goare updated to cover the new headernames and dual-key metadata behavior.