-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Authentication and restricting read access #55
Comments
The Webauthn spec is cool, but does not and will not support signing data. That unfortunately makes it not a fit for Atomic Data. However, the WebCrypto spec does allow signing, and some are advocating for hardware access. |
I'll go for signing requests. We'll need to prevent MITM attacks by including a timestamp. I suggest we use an HTTP header:
Signature is calulated by signing the URL + timestamp with Agent's ED25519 private key
|
we'll need these headers: const privateKey = agent.privateKey;
const timestamp = getTimestampNow();
const message = `${subject} ${timestamp}`;
const signed = await signToBase64(message, privateKey);
headers.set('x-atomic-public-key', await agent.getPublicKey());
headers.set('x-atomic-signature', signed);
headers.set('x-atomic-timestamp', timestamp.toString());
headers.set('x-atomic-agent', agent?.subject); The agent subject is needed, because the server needs to find whether the public key is actually the one corresponding to that agent. |
We have authentication + authorization for writes (using Commits and signatures), but not for read access.
Issue in atomic-server.
Goals:
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 awrite
right. I could do the same thing forread
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.
The text was updated successfully, but these errors were encountered: