diff --git a/README.md b/README.md index a07955a..f24271f 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ The Identity project is composed by a web-app and two servers. In the future, Do 2. Run `yarn` to install the dependencies. * You may need to [enable Corepack](https://nodejs.org/api/corepack.html). 3. Run `yarn start` to start the server. + * **Note:** The `asset-api` server **must** be running before this command is run. [More info](./docs/asset-implementation.md). 4. You're ready to go! You will need to restart the server manually when you make changed (unless you use something like [Nodemon](https://www.npmjs.com/package/nodemon)). ### `asset-api` diff --git a/docs/asset-implementation.md b/docs/asset-implementation.md new file mode 100644 index 0000000..6766912 --- /dev/null +++ b/docs/asset-implementation.md @@ -0,0 +1,66 @@ +# Asset implementation + +Storing and serving user-generated assets is a difficult task due to potential abuse and the complexities of the web ecosystem. +To overcome some of these shortcomings, there are two distinct services in the Identity project: `identity-api` (user data), and +`asset-api` (user-generated assets). + +This document explains how both of these services communicate and potential improvements that may be implemented in the future. + +## Introduction to the M2M mechanism + +The basis of the M2M mechanism are the following: +* `asset-api` generates a pubkey pair. The public key is exposed to the public. +* `identity-api` loads the `asset-api`'s public key at intervals. +* `identity-api` exposes some M2M routes that perform actions such as: retrieving the account of a given user, associating assets to +an user account, etc. + +Each request performed by `asset-api` to `identity-api` is signed using the pubkey pair, which allows the `identity-api` to verify +that the requester is the `asset-api` using the retrieved public key. (Implementation: [$/identity-api/src/m2m.js](../identity-api/src/m2m.js)) + +The request body is signed in a PGP-like manner, this can be seen by accessing the index page of the `asset-api` +([http://localhost:3001/](http://localhost:3001/) in default local environments). + +## Actions +### Uploading an asset + +1. The client requests a `session_key` (_the Key_ from now on) to the `identity-api`, the Key allows the `asset-api` to perform +limited actions on the account of the user. +2. The client sends a request to the `asset-api` with the asset and the Key. +3. The `asset-api` retrieves the limits that apply to the account by requesting them to the `identity-api` using the Key. +4. After some preconditions are met, the asset is stored and a unique ID is generated and linked to the stored asset. +5. The `asset-api` adds the unique ID to the user's asset list by sending a request to the `identity-api` using the Key. +6. The client receives an OK response from the `asset-api`. +7. The client rotates the Key. + +### Retrieving an asset + +1. The client requests a `session_key` (_the Key_ from now on) to the `identity-api`, the Key allows the `asset-api` to perform +limited actions on the account of the user. +2. The client sends a request to the `asset-api` with the asset ID and the Key. +3. The `asset-api` retrieves the user's asset list by requesting it to the `identity-api` using the Key. +4. After some preconditions are met, the asset is sent back to the client. +5. The client receives the asset from the `asset-api`. +6. The client rotates the Key. + +## Analysis of the current implementation + +The current implementation works fine and it's quite fast. The use of pubkey cryptography allows for an easier handshake and thus +there's less hoops that the `asset-api` has to go through to prove its identity. + +Currently, the `identity-api` obtains the `asset-api`'s public key and algorithm by sending an HTTP(S) request. This simplifies +the infrastructure and allows the `asset-api` to rotate keys on the fly, but it also has the downside that the `identity-api` +**must** trust that the URL to the `asset-api` is not compromised. Using manual key rotation would be more secure in that sense, +but in practice rotation would be much slower, potentially leading to more frequent security problems. + +It is theoretically possible to make the `identity-api` trust third-party keys using techniques such as DNS poisoning, but in +order to execute such a targeted attack the overall infrastructure must already be compromised. + +The use of `session_key`s adds another layer of security: the `asset-api` must prove its identity, **and** the user must have given +consent for that service to perform limited actions on their behalf. The current issue is that `session_key`s are not time-limited, +which means that if a rotation is not performed, a `session_key` could theoretically be completely valid for years. + +That could lead to some theoretical attacks, but the scope of `session_key`s is so limited that they aren't an issue. Still, in +future iterations of the M2M mechanism this issue will be solved. + +Overall, the current implementation is not perfect but it is secure enough for the current use case. In the future, the implementation +of standards like OAuth may be considered more adequate. \ No newline at end of file