mirror of
https://code.sup39.dev/repos/Wqawg
synced 2024-12-27 16:24:52 +09:00
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
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in a new issue