FEDERATION.hs: Finish initial writing of the authentication proposals

This commit is contained in:
fr33domlover 2019-05-28 08:37:23 +00:00
parent 6f673b3363
commit f904123d91

View file

@ -105,10 +105,6 @@ contains not just the key itself, but also a code specifying the key type. The
Fediverse de-facto standard is RSA, more precisely PKCS#1 v1.5, and used with
the SHA-256 hash algorithm. This is often referred to as RSA-SHA256.
If the `algorithm` is specified in the Signature header, it must match the key
type in the PEM. But `algorithm` isn't required, and we should probably stop
using it.
#### (1) Actor key(s) in a separate document
Allow an actor's signing key to be a separate document, rather than embedded in
@ -273,9 +269,105 @@ Requirements for authentication using a server-scope key:
#### (4) Actor key expiration and revocation
Allow to improve the secure handling of signing keys by supporting expiration
and revocation. Expiration means the key specifies a time at which it stops
being valid, and once that time comes, signatures made by that key are
considered invalid. Revocation similary means the key specifies a time at which
it stops being valid.
`GET /users/aviva/keys/key1`
```json
{ "@context": "https://w3id.org/security/v1"
, "@id": "https://example.dev/users/aviva/keys/key1"
, "@type": "Key"
, "owner": "https://example.dev/users/aviva"
, "created": "2019-01-13T11:00:00+0000"
, "expires": "2021-01-13T11:00:00+0000"
, "publicKeyPem": "-----BEGIN PUBLIC KEY----- ..."
}
```
Requirement: When verifying a signature, compare `expires` and `revoked`, if
one of them or both of them are present, to the current time. If at least one
of the 2 times is the current time or earlier, then consider the signature
invalid. If using a cached version of the key, try to HTTP GET the key and try
to authenticate once more, because it's possible the key has been replaced with
a new valid one.
#### (5) Ed25519 actor keys
#### (6) Key rotation using a pair of server-scope keys
Allows actor keys to be [Ed25519](https://ed25519.cr.yp.to) keys, by allowing
the `publicKeyPem` field to simply contain a PEM encoded Ed25519 public key.
The [HTTP Signatures draft](https://tools.ietf.org/html/draft-cavage-http-signatures-11#appendix-E.2)
lists more algorithms; we could support them too. This proposal just suggests
that we all start supporting Ed25519 in addition to RSA.
#### (6) HTTP Signature draft 11
The draft linked above, from April 2019, makes some changes and
recommendations. This proposal suggests we adopt them:
- For the `algorithm` parameter, use the value `hs2019`, or none, and start
deprecating the old values (such as `rsa-sha256`).
- The new `created` and `expires` parameters seem to be mostly useful to web
browser based clients, while our usage of HTTP Signatures is between servers.
So perhaps they aren't very useful here. But if someone finds them useful,
let's support them.
- Support at least Ed25519 in addition to RSA, see proposal A.5 above.
#### (7) Key rotation using a pair of server-scope keys
Allows to easily and computationally-cheaply perform periodic key rotation.
Rationale:
If you deliver an activity and then rotate the key, the target servers will
want to fetch the old key to verify your signatures, but, the old key has been
replaced, so they will fail to authenticate your requests. When using per-actor
keys, it's possible to try waiting for a time the user is inactive (which is
hopefully common because most people probably sleep for a few hours every day),
and use that as a safer chance to rotate the key. During the quiet time, other
servers will have had enough time to process their activity inbox queues, and
by the time we rotate, nobody will want the old key anymore.
The weakness of that solution is that:
- It's limited to periods of inactivity, which may limit rotation to once per
day or less (what if you want to rotate more often? Hmm is there a good
reason to? I'm not sure, just saying hypothetically)
- It doesn't work for users that don't have inactivity periods, e.g. a user
that uses scheduled activities, automatic responses etc.
- It involves the computation of generating a new key for every user every day
(assuming we don't want to rotate more often), which I suppose can be
somewhat heavy, especially for RSA (but I haven't done any measurements)
- It involves lots of network activity because other servers will be fetching
the new rotated keys all the time, keys can't be cached for days or weeks or
more if they keep being replaced every day or every hour (but I haven't done
measurements of the effect on the amount of network requests)
The proposal:
- Each server has 2 or more server-scope keys. For simplicity of discussion,
let's assume a server has exactly 2 keys, key A and key B.
- The server does periodic rotation, but each time, it rotates one of the keys
and leaves the other intact. It rotates key A, then next time it rotates key
B, next time it rotates key A again, next time it rotates key B again... and
so on.
- When signing HTTP requests, the server always uses the newer key. For
example, if it just rotated key A, it will sign the next requests with key A.
When time comes for the next rotation, it will rotate key B and stop using
key A, switching to using key B for signing requests.
- The time frame suggested here for letting other servers finish processing our
activities in their inbox queues is **one hour**, although this is just a
suggestion and open to discussion. So it's suggested you do periodic rotation
at most once an hour (or at least leave a key available for at least an hour
without change after you stop using it)
That way, when one of the keys is rotated, the other key is still available for
another hour and other servers are able to use it to verify the signatures we
sent. There's no need to wait for users to be inactive, and it's very cheap:
Rotate 1 key per hour. Especially if that key is Ed25519.
### (B) ActivityPub