github.com/decred/dcrlnd@v0.7.6/docs/macaroons.md (about)

     1  As part of [the `dcrlnd` 0.3-alpha
     2  release](https://github.com/lightningnetwork/lnd/releases/tag/v0.3-alpha), we
     3  have addressed [issue 20](https://github.com/lightningnetwork/lnd/issues/20),
     4  which is RPC authentication. Until this was implemented, all RPC calls to `dcrlnd`
     5  were unauthenticated. To fix this, we've utilized
     6  [macaroons](https://research.google.com/pubs/pub41892.html), which are similar
     7  to cookies but more capable. This brief overview explains, at a basic level,
     8  how they work, how we use them for `dcrlnd` authentication, and our future plans.
     9  
    10  ## What are macaroons?
    11  
    12  You can think of a macaroon as a cookie, in a way. Cookies are small bits of
    13  data that your browser stores and sends to a particular website when it makes a
    14  request to that website. If you're logged into a website, that cookie can store
    15  a session ID, which the site can look up in its own database to check who you
    16  are and give you the appropriate content.
    17  
    18  A macaroon is similar: it's a small bit of data that a client (like `dcrlncli`)
    19  can send to a service (like `dcrlnd`) to assert that it's allowed to perform an
    20  action. The service looks up the macaroon ID and verifies that the macaroon was
    21  initially signed with the service's root key. However, unlike a cookie, you can
    22  *delegate* a macaroon, or create a version of it that has more limited
    23  capabilities, and then send it to someone else to use.
    24  
    25  Just like a cookie, a macaroon should be sent over a secure channel (such as a
    26  TLS-encrypted connection), which is why we've also begun enforcing TLS for RPC
    27  requests in this release. Before SSL was enforced on websites such as Facebook
    28  and Google, listening to HTTP sessions on wireless networks was one way to
    29  hijack the session and log in as that user, gaining access to the user's
    30  account. Macaroons are similar in that intercepting a macaroon in transit
    31  allows the interceptor to use the macaroon to gain all the privileges of the
    32  legitimate user.
    33  
    34  ## Macaroon delegation
    35  
    36  A macaroon is delegated by adding restrictions (called caveats) and an
    37  authentication code similar to a signature (technically an HMAC) to it. The
    38  technical method of doing this is outside the scope of this overview
    39  documentation, but the [README in the macaroons package](../macaroons/README.md)
    40  or the macaroon paper linked above describe it in more detail. The
    41  user must remember several things:
    42  
    43  * Sharing a macaroon allows anyone in possession of that macaroon to use it to
    44    access the service (in our case, `dcrlnd`) to do anything permitted by the
    45    macaroon. There is a specific type of restriction, called a "third party
    46    caveat," that requires an external service to verify the request; however,
    47    `dcrlnd` doesn't currently implement those.
    48  
    49  * If you add a caveat to a macaroon and share the resulting macaroon, the
    50    person receiving it cannot remove the caveat.
    51  
    52  This is used in `dcrlnd` in an interesting way. By default, when `dcrlnd` starts, it
    53  creates three files which contain macaroons: a file called `admin.macaroon`,
    54  which contains a macaroon with no caveats, a file called `readonly.macaroon`,
    55  which is the *same* macaroon but with an additional caveat, that permits only
    56  methods that don't change the state of `dcrlnd`, and `invoice.macaroon`, which
    57  only has access to invoice related methods.
    58  
    59  ## How macaroons are used by `dcrlnd` and `dcrlncli`.
    60  
    61  On startup, `dcrlnd` checks to see if the `admin.macaroon`, `readonly.macaroon`
    62  and `invoice.macaroon` files exist. If they don't exist, `dcrlnd` updates its
    63  database with a new macaroon ID, generates the three files `admin.macaroon`,
    64  `readonly.macaroon` and `invoice.macaroon`, all with the same ID. The
    65  `readonly.macaroon` file has an additional caveat which restricts the caller
    66  to using only read-only methods and the `invoice.macaroon` also has an
    67  additional caveat which restricts the caller to using only invoice related
    68  methods. This means a few important things:
    69  
    70  * You can delete the `admin.macaroon` and be left with only the
    71    `readonly.macaroon`, which can sometimes be useful (for example, if you want
    72    your `dcrlnd` instance to run in autopilot mode and don't want to accidentally
    73    change its state).
    74  
    75  * If you delete the data directory which contains the `macaroons.db` file, this
    76    invalidates the `admin.macaroon`, `readonly.macaroon` and `invoice.macaroon`
    77    files. Invalid macaroon files give you errors like `cannot get macaroon: root
    78    key with id 0 doesn't exist` or `verification failed: signature mismatch
    79    after caveat verification`.
    80  
    81  You can also run `dcrlnd` with the `--no-macaroons` option, which skips the
    82  creation of the macaroon files and all macaroon checks within the RPC server.
    83  This means you can still pass a macaroon to the RPC server with a client, but
    84  it won't be checked for validity.
    85  
    86  Since `dcrlnd` requires macaroons by default in order to call RPC methods, `dcrlncli`
    87  now reads a macaroon and provides it in the RPC call. Unless the path is
    88  changed by the `--macaroonpath` option, `dcrlncli` tries to read the macaroon from
    89  the network directory of `dcrlnd`'s currently active network (e.g. for simnet
    90  `~/.dcrlnd/data/chain/decred/simnet/admin.macaroon`) by default and will error if
    91  that file doesn't exist unless provided the `--no-macaroons` option. Keep this
    92  in mind when running `dcrlnd` with `--no-macaroons`, as `dcrlncli` will error out
    93  unless called the same way **or** `dcrlnd` has generated a macaroon on a previous
    94  run without this option.
    95  
    96  `dcrlncli` also adds a caveat which makes it valid for only 60 seconds by default
    97  to help prevent replay in case the macaroon is somehow intercepted in
    98  transmission. This is unlikely with TLS, but can happen e.g. when using a PKI
    99  and network setup which allows inspection of encrypted traffic, and an attacker
   100  gets access to the traffic logs after interception. The default 60 second
   101  timeout can be changed with the `--macaroontimeout` option; this can be
   102  increased for making RPC calls between systems whose clocks are more than 60s
   103  apart.
   104  
   105  ## Stateless initialization
   106  
   107  As mentioned above, by default `lnd` creates several macaroon files in its
   108  directory. These are unencrypted and in case of the `admin.macaroon` provide
   109  full access to the daemon. This can be seen as quite a big security risk if
   110  the `lnd` daemon runs in an environment that is not fully trusted.
   111  
   112  The macaroon files are the only files with highly sensitive information that
   113  are not encrypted (unlike the wallet file and the macaroon database file that
   114  contains the [root key](../macaroons/README.md), these are always encrypted,
   115  even if no password is used).
   116  
   117  To avoid leaking the macaroon information, `lnd` supports the so called 
   118  `stateless initialization` mode:
   119  * The three startup commands `create`, `unlock` and `changepassword` of `lncli`
   120    all have a flag called `--stateless_init` that instructs the daemon **not**
   121    to create `*.macaroon` files.
   122  * The two operations `create` and `changepassword` that actually create/update
   123    the macaroon database will return the admin macaroon in the RPC call.
   124    Assuming the daemon and the `lncli` are not used on the same machine, this
   125    will leave no unencrypted information on the machine where `lnd` runs on.
   126    * To be more precise: By default, when using the `changepassword` command, the
   127      macaroon root key in the macaroon DB is just re-encrypted with the new
   128      password. But the key remains the same and therefore the macaroons issued
   129      before the `changepassword` command still remain valid. If a user wants to
   130      invalidate all previously created macaroons, the `--new_mac_root_key` flag
   131      of the `changepassword` command should be used! 
   132  * An user of `lncli` will see the returned admin macaroon printed to the screen
   133    or saved to a file if the parameter `--save_to=some_file.macaroon` is used.
   134  * **Important:** By default, `lnd` will create the macaroon files during the
   135    `unlock` phase, if the `--stateless_init` flag is not used. So to avoid
   136    leakage of the macaroon information, use the stateless initialization flag
   137    for all three startup commands of the wallet unlocker service!
   138  
   139  Examples:
   140  
   141  * Create a new wallet stateless (first run):
   142    * `lncli create --stateless_init --save_to=/safe/location/admin.macaroon`
   143  * Unlock a wallet that has previously been initialized stateless:
   144    * `lncli unlock --stateless_init`
   145  * Use the created macaroon:
   146    * `lncli --macaroonpath=/safe/location/admin.macaroon getinfo`
   147  
   148  ## Using Macaroons with GRPC clients
   149  
   150  When interacting with `dcrlnd` using the GRPC interface, the macaroons are encoded
   151  as a hex string over the wire and can be passed to `dcrlnd` by specifying the
   152  hex-encoded macaroon as GRPC metadata:
   153  
   154      GET https://localhost:8080/v1/getinfo
   155      Grpc-Metadata-macaroon: <macaroon>
   156  
   157  Where `<macaroon>` is the hex encoded binary data from the macaroon file itself.
   158  
   159  A very simple example using `curl` may look something like this:
   160  
   161      curl --insecure --header "Grpc-Metadata-macaroon: $(xxd -ps -u -c 1000  $HOME/.lnd/data/chain/decred/simnet/admin.macaroon)" https://localhost:8080/v1/getinfo
   162  
   163  Have a look at the [Java GRPC example](/docs/grpc/java.md) for programmatic usage details.
   164  
   165  ## Creating macaroons with custom permissions
   166  
   167  The macaroon bakery is described in more detail in the
   168  [README in the macaroons package](../macaroons/README.md).
   169  
   170  ## Future improvements to the `dcrlnd` macaroon implementation
   171  
   172  The existing macaroon implementation in `dcrlnd` and `dcrlncli` lays the groundwork
   173  for future improvements in functionality and security. We will add features
   174  such as:
   175  
   176  * Improved replay protection for securing RPC calls
   177  
   178  * Macaroon database encryption
   179  
   180  * Root key rotation and possibly macaroon invalidation/rotation
   181  
   182  * Additional restrictions, such as limiting payments to use (or not use)
   183    specific routes, channels, nodes, etc.
   184  
   185  * Accounting-based macaroons, which can make an instance of `dcrlnd` act almost
   186    like a bank for apps: for example, an app that pays to consume APIs whose
   187    budget is limited to the money it receives by providing an API/service
   188  
   189  * Support for third-party caveats, which allows external plugins for
   190    authorization and authentication
   191  
   192  With this new feature, we've started laying the groundwork for flexible
   193  authentication and authorization for RPC calls to `dcrlnd`. We look forward to
   194  expanding its functionality to make it easy to develop secure apps.