/ macaroons / README.md
README.md
  1  # macaroons
  2  
  3  This is a more detailed, technical description of how macaroons work and how
  4  authentication and authorization is implemented in `lnd`.
  5  
  6  For a more high-level overview see
  7  [macaroons.md in the docs](../docs/macaroons.md).
  8  
  9  ## Root key
 10  
 11  At startup, if the option `--no-macaroons` is **not** used, a Bolt DB key/value
 12  store named `data/macaroons.db` is created with a bucket named `macrootkeys`.
 13  In this DB the following two key/value pairs are stored:
 14  
 15  * Key `0`: the encrypted root key (32 bytes).
 16    * If the root key does not exist yet, 32 bytes of pseudo-random data is
 17      generated and used.
 18  * Key `enckey`: the parameters used to derive a secret encryption key from a
 19    passphrase.
 20    * The following parameters are stored: `<salt><digest><N><R><P>`
 21      * `salt`: 32 byte of random data used as salt for the `scrypt` key
 22        derivation.
 23      * `digest`: sha256 hashed key derived from the `scrypt` operation. Is used
 24        to verify if the password is correct.
 25      * `N`, `P`, `R`: Parameters used for the `scrypt` operation.
 26    * The root key is symmetrically encrypted with the derived secret key, using
 27      the `secretbox` method of the library
 28      [btcsuite/golangcrypto](https://github.com/btcsuite/golangcrypto).
 29    * If the option `--noseedbackup` is used, then the default passphrase
 30      `hello` is used to encrypt the root key.
 31  
 32  ## Generated macaroons
 33  
 34  With the root key set up, `lnd` continues with creating three macaroon files:
 35  
 36  * `invoice.macaroon`: Grants read and write access to all invoice related gRPC
 37    commands (like generating an address or adding an invoice). Can be used for a
 38    web shop application for example. Paying an invoice is not possible, even if
 39    the name might suggest it. The permission `offchain` is needed to pay an
 40    invoice which is currently only granted in the admin macaroon.
 41  * `readonly.macaroon`: Grants read-only access to all gRPC commands. Could be
 42    given to a monitoring application for example.
 43  * `admin.macaroon`: Grants full read and write access to all gRPC commands.
 44    This is used by the `lncli` client.
 45  
 46  These three macaroons all have the location field set to `lnd` and have no
 47  conditions/first party caveats or third party caveats set.
 48  
 49  The access restrictions are implemented with a list of entity/action pairs that
 50  is mapped to the gRPC functions by the `rpcserver.go`. 
 51  For example, the permissions for the `invoice.macaroon` looks like this:
 52  
 53  ```go
 54  	// invoicePermissions is a slice of all the entities that allows a user
 55  	// to only access calls that are related to invoices, so: streaming
 56  	// RPCs, generating, and listening invoices.
 57  	invoicePermissions = []bakery.Op{
 58  		{
 59  			Entity: "invoices",
 60  			Action: "read",
 61  		},
 62  		{
 63  			Entity: "invoices",
 64  			Action: "write",
 65  		},
 66  		{
 67  			Entity: "address",
 68  			Action: "read",
 69  		},
 70  		{
 71  			Entity: "address",
 72  			Action: "write",
 73  		},
 74  	}
 75  ```
 76  
 77  ## Constraints / First party caveats
 78  
 79  There are currently two constraints implemented that can be used by `lncli` to
 80  restrict the macaroon it uses to communicate with the gRPC interface. These can
 81  be found in `constraints.go`:
 82  
 83  * `TimeoutConstraint`: Set a timeout in seconds after which the macaroon is no
 84    longer valid.
 85    This constraint can be set by adding the parameter `--macaroontimeout xy` to
 86    the `lncli` command.
 87  * `IPLockConstraint`: Locks the macaroon to a specific IP address.
 88    This constraint can be set by adding the parameter `--macaroonip a.b.c.d` to
 89    the `lncli` command.
 90  
 91  ## Bakery
 92  
 93  As of lnd `v0.9.0-beta` there is a macaroon bakery available through gRPC and
 94  command line.
 95  Users can create their own macaroons with custom permissions if the provided
 96  default macaroons (`admin`, `invoice` and `readonly`) are not sufficient.
 97  
 98  For example, a macaroon that is only allowed to manage peers with a default root
 99  key `0` would be created with the following command:
100  
101  ```shell
102  $  lncli bakemacaroon peers:read peers:write
103  ```
104  
105  For even more fine-grained permission control, it is also possible to specify
106  single RPC method URIs that are allowed to be accessed by a macaroon. This can
107  be achieved by passing `uri:<methodURI>` pairs to `bakemacaroon`, for example:
108  
109  ```shell
110  $  lncli bakemacaroon uri:/lnrpc.Lightning/GetInfo uri:/verrpc.Versioner/GetVersion
111  ```
112  
113  The macaroon created by this call would only be allowed to call the `GetInfo` and
114  `GetVersion` methods instead of all methods that have similar permissions (like
115  `info:read` for example).
116  
117  If you need a macaroon file with rights similar to `admin.macaroon` for a
118  custom use case, you can create one as shown in the following example.
119  Note that a macaroon created in this way will have extensive rights, allowing
120  it to create macaroons with more permissions than the original one.
121  ```shell
122  $  lncli bakemacaroon --save_to lnbits.macaroon \
123     address:read address:write \
124     info:read info:write \
125     invoices:read invoices:write \
126     macaroon:generate macaroon:read macaroon:write \
127     message:read message:write \
128     offchain:read offchain:write \
129     onchain:read onchain:write \
130     peers:read peers:write \
131     signer:generate signer:read
132  ```
133  
134  A full list of available entity/action pairs and RPC method URIs can be queried
135  by using the `lncli listpermissions` command.
136  
137  ### Upgrading from v0.8.0-beta or earlier
138  
139  Users upgrading from a version prior to `v0.9.0-beta` might get a `permission
140  denied ` error when trying to use the `lncli bakemacaroon` command.
141  This is because the bakery requires a new permission (`macaroon/generate`) to
142  access.
143  Users can obtain a new `admin.macaroon` that contains this permission by
144  removing all three default macaroons (`admin.macaroon`, `invoice.macaroon` and
145  `readonly.macaroon`, **NOT** the `macaroons.db`!) from their
146  `data/chain/<chain>/<network>/` directory inside the lnd data directory and
147  restarting lnd.
148  
149  
150  ## Root key rotation
151  
152  To manage the root keys used by macaroons, there are `listmacaroonids` and
153  `deletemacaroonid` available through gPRC and command line.
154  Users can view a list of all macaroon root key IDs that are in use using:
155  
156  ```shell
157  $  lncli listmacaroonids
158  ```
159  
160  And remove a specific macaroon root key ID using command:
161  
162  ```shell
163  $  lncli deletemacaroonid root_key_id
164  ```
165  
166  Be careful with the `deletemacaroonid` command as when a root key is deleted,
167  **all the macaroons created from it are invalidated**.