Description
We have authentication + authorization for writes (using Commits and signatures), but not for read access.
Goals:
- Secure: Because, what's the point of authentication if it's not?
- Ease of use: Setting up an identity should not require any effort, and proving identity should be minimal effort.
- Anonimity allowed: Users should be able to have multiple identities, some of which are fully anonymous.
- Self-sovereign: No dependency on servers that user's don't control. Or at least, minimise this.
- Dummy-proof: We need a mechanism for dealing with forgetting passwords / client devices losing data.
- Compatible with Commits: Atomic Commits require clients to sign things. Ideally, this functionality / strategy would also fit with the new model.
- Fast: Of course, authentication will slow things down. But let's keep that to a minimum.
Ideas
Signing GET requests
So a couple of methods exist to sign HTTP requests. One is to add a Digest and Authorization HTTP header. Another way is to add a Body with a JWS (or other signature) that contains information about the request, such as the requested resource and some fleeting identifier (timestamp).
WebAuthn
This specification allows browsers to use 2FA devices for signing in - without requiring any password remembering. It works pretty well, but it has some unfortunate limitations for Atomic Data. For one, it can't be used to sign an arbitrary thing, such as an Atomic Commit.
Traversing parents vs explicit rights
As of now, the server determines whether someone can edit something by iterating over parent
relations until it encounters a write
right. I could do the same thing for read
rights.
If a client wants to determine something about the rights of that resource, it will have to perform one or a couple of requests to traverse the graph and get the rights attributes. If rights were more explicit, clients could more easily know whether something should be private or not.
We could also decide to make rights very explicit - every single Resource could describe their own rights. If we were to
Session keys & 2FA
Signing every request with your agent's private key is elegant, but also opens up some attack vectors. For example, a phishing attack for the agent's secret (a login screen that sends the private key to the client, for example) would be devastating. This problem is the same for regular apps that rely on username + password. That's why many apps offer 2FA options.
What we can't do, is sign every single request with a 2FA device - it would ask the user every second to use some app. What we can do, is create a temporary private key used in that session alone. This key can be used to sign the requests.
The downside of this approach, is that Commits will no longer be signed by the public key of the agent, which makes traceability harder.
We could store every Session (and it's public key) as a resource on any server, and let these point to the Agent. These sessions can be signed by the Agent, which proves that the session actually is created by the Agent, and is a legit representative.