FEDERATION.hs: Finish initial writing of the authentication proposals
This commit is contained in:
parent
6f673b3363
commit
f904123d91
1 changed files with 97 additions and 5 deletions
102
FEDERATION.md
102
FEDERATION.md
|
@ -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
|
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.
|
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
|
#### (1) Actor key(s) in a separate document
|
||||||
|
|
||||||
Allow an actor's signing key to be a separate document, rather than embedded in
|
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
|
#### (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
|
#### (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
|
### (B) ActivityPub
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue