When an #ActivityPub server implements authorized fetch (aka secure mode), how does it associate the keyId in an HTTP request with the actual actor? I know major implementations (like Mastodon) use a fragment appended to the actor IRI as a keyId, but in theory a keyId could be any IRI that seems unrelated to the actor IRI, right? Should I maintain a table of actor–keyIds somewhere in the server?
Conversation
Notices
-
Embed this notice
洪 民憙 (Hong Minhee) (hongminhee@todon.eu)'s status on Thursday, 11-Apr-2024 11:19:55 JST 洪 民憙 (Hong Minhee) -
Embed this notice
洪 民憙 (Hong Minhee) (hongminhee@todon.eu)'s status on Thursday, 11-Apr-2024 19:24:53 JST 洪 民憙 (Hong Minhee) @twilliability The problem is that in addition to POST requests with an activity, GET requests can also be signed. When you receive a GET request, you have no way of knowing which actor the signed key belongs to. I asked the same question at the Fediverse Developer Network in Matrix, and we concluded that the only way to do this is to maintain a separate actor–keyId table in the server.
-
Embed this notice
gábor ugray (twilliability@genart.social)'s status on Thursday, 11-Apr-2024 19:24:54 JST gábor ugray @hongminhee It's still an assumption that actor URL is a prefix of the key ID, but it works with the systems I'm seeing.
I haven't found any clear requirement about this in the AP specs.
I'm a little unhappy about parsing the message content before verifying the signature b/c it messes up the logical order of things, and because I'm not sure if it entails any security risk. (But I'm skeptical about the HTTPsig approach as a whole so it adds little extra doubt.)
-
Embed this notice
gábor ugray (twilliability@genart.social)'s status on Thursday, 11-Apr-2024 19:24:55 JST gábor ugray @hongminhee In RSS Parrot I first just took the part before #main-key to be the actor URL. That failed with GoToSocial because it actually uses /main-key.
I ended up parsing the activity before checking they key, and retrieving the actor URL from there. Then I retrieve the actor, which includes the key.
I check that the actor URL is a prefix of the key ID from the signature.
-
Embed this notice
洪 民憙 (Hong Minhee) (hongminhee@todon.eu)'s status on Thursday, 11-Apr-2024 20:27:32 JST 洪 民憙 (Hong Minhee) @twilliability The pragmatic heuristics you mentioned is great, but I'm building a framework called Fedify, and I needed a more general way of doing things. 🤔
-
Embed this notice
gábor ugray (twilliability@genart.social)'s status on Thursday, 11-Apr-2024 20:27:33 JST gábor ugray @hongminhee Hmmm, that's right! In that case though, you'd need a whole regime of keeping that info up-to-date (why couldn't keys change?), and also you cannot serve a request from an actor you haven't seen before... This sounds like a mess :(((
(This is where the pragmatist in me would most definitely take drastic shortcuts and just say, works with the keyId schemas I've seen so far, and I'll just add new ones as they show up in the wild...)
-
Embed this notice
silverpill (silverpill@mitra.social)'s status on Friday, 12-Apr-2024 02:24:56 JST silverpill @hongminhee In theory locations of public key and actor object can be different, but in practice this feature only makes software more complicated for no reason, and you can make Fediverse more friendly to developers by not supporting it. Almost everyone already uses fragment IDs, so you can either ignore projects that contribute to protocol decay or add special rules for them
-
Embed this notice
洪 民憙 (Hong Minhee) (hongminhee@todon.eu)'s status on Friday, 12-Apr-2024 10:30:02 JST 洪 民憙 (Hong Minhee) @mariusor Yes, I just realized that the key object has an owner property! Of course, the owner property of a key object is just a claim, so I'll have to dereference the onwer IRI to see if it actually owns the key.
-
Embed this notice
marius (mariusor@metalhead.club)'s status on Friday, 12-Apr-2024 10:30:04 JST marius @hongminhee the object that you get when you access a KeyId should have the owner IRI included.
-
Embed this notice
洪 民憙 (Hong Minhee) (hongminhee@todon.eu)'s status on Friday, 12-Apr-2024 10:34:31 JST 洪 民憙 (Hong Minhee) @silverpill I heard that GoToSocial constructs keyId as a subpath instead of a fragment. Anyway, I'm building a framework and I need to derive an actor object from a keyId, so I needed a more general method. Finally, I realized that key objects have an owner property, so I'm going to use that method.
-
Embed this notice
silverpill (silverpill@mitra.social)'s status on Friday, 12-Apr-2024 10:56:30 JST silverpill @hongminhee Yes, GtS uses /main-key path. This is the only project I know of that does it differently
-
Embed this notice