FEP-c7d3: Ownership

In this FEP I talk about the concept of ownership in ActivityPub network, and specify authentication and authorization procedures based on it.

2 Likes

Seems fine mostly, but the “first actor is the owner” doesn’t hold up technically. They’re unordered sets. It would be a mistake to make such assumptions based on ordering of the JSON presentation. We currently make the same mistake with the attachment array.

1 Like

I’d prefer an extension (e.g., maybe an explicit owner property?) rather than redefining existing terms.

In the Ownership section, you mention that AS2 defines some of the terms you are using, but then you use a variation of those definitions (or attributedTo, for example). A section that describes differences with the AP/AS2 recs could be useful.

Every activity MUST have an actor property, which describes one or more entities that either performed or are expected to perform the activity. These entities MUST be actors and the first actor is considered the owner of the activity.

Any entity that is the subject of an actor property is an actor, by definition. The MUST seems unnecessary.

1 Like

True, but what could be done about it? The FEP may say that actor and attributedTo values MUST be a single actor, but multi-actor attributedTo values are actually quite common, for example PeerTube uses them.

Yes, ideally it should be a new property, but actor and attributedTo are already used in the way described in this FEP. I think it wouldn’t hurt if we adjust definitions based on the implementation experience.

By variation, do you mean the removal of “The attributed entities might not be Actors” from the original definition?
I could add a note about that.

I’d like to keep that part for completeness.

That (which is significant), and the concept of a “first” item in the actor and attributedTo sets, and that attributedTo is required for every object.

I was saying that it is complete without it. It probably doesn’t hurt to add redundant information, but it might raise questions about whether a specific point is being made.

1 Like

I think you could say an activity is valid as long as it’s signed for by… any of? all of? the “owners”. That could be tricky to authenticate, but it’s where we are. The same issue arises for multiple inReplyTo or multiple context when paired with various control/authorization schemes.

2 Likes

I updated the proposal. Now it requires actor and attributedTo values to contain a single actor, and says in “Implementation notes” section that multiple owners are possible but not covered.

Diff: https://codeberg.org/fediverse/fep/commit/d62f5722801b5824af1464e845ac83785fcff4d4

4 Likes

It was fetched from the server that corresponds to the “origin” part of its owner’s ID.

I found an interesting edge case: object is served from a different subdomain. Traditional same origin policy would prohibit that. I think this FEP should also, if not prohibit then strongly recommend against this. For example, a different subdomain might be used for media uploads, and developer might fail to implement proper media type checks

Also, another interesting question, should object id and its owner be of the same origin? Probably yes

if you wanted to treat all subdomains of a given DNS origin as equal (i.e. www.example.com and asset-storage.example.com or even the exotic {base32-CID}.ipfs-storage.example.com, hehe) you could loosen this requirement to having the same apex domain rather than same origin, maybe?

So, I like the idea behind this FEP a lot! I think it formalizes a new property which adds a lot to the migration conversation, because migration is going to create a lot of new shades of grey between “authenticated” and “unauthenticated,” like “migrated content signed with keys that no longer resolve” and “content signed by keys that require particular trust models to verify”.

Steve’s suggestion that maybe owner could or should be a new property rather than overloading existing terms is interesting, though. More generally, I’m a little confused on the upgrade path/legacy interop aspect here-- while this proposal could formalize the “owner” relationship going forward in a way, how do the implementations that don’t implement it co-exist with the ones that do? In particular, I was confused by the _MUST_s in the Authorization section:

If activity modifies or deletes the object, its owner MUST match the object’s owner.

Are there possible side-effects worth considering, such as a reply thread which includes some servers that DO implement this check (and thus drop an invalid delete request) and other servers that DON’T?

Also, does this mean that I can’t delete a post after migrating and importing it, because my actor id has changed? Or does the destination server supporting Move Actor and movedTo mean the post-migration Actor effectively is the pre-migration Actor, for these purposes? If the latter, maybe this FEP “requires” FEP-7628 and it’s worth calling out the movedTo redirect case?

1 Like

Media is exactly the reason why I want to require full match rather than apex domain match. An attacker could upload malicious AP object as media and circumvent the same origin check, see GHSA-jhrq-qvrm-qr36. Obviously, implementers should verify the media type, but as a hardening measure, security researchers advised server operators to serve media from a different subdomain, and implementers to perform strict same-origin checks.

As far as I know, many existing implementations already perform checks described in this FEP. Those who don’t perform them are likely vulnerable to cache poisoning / impersonation attacks (although in some cases the severity of these vulnerabilities is low).

Servers that don’t implement this check will allow any actor to delete any cached object.

I don’t know, depends on the migration mechanism.

1 Like

Updating the FEP to clarify the meaning of “origin”: #349 - FEP-c7d3: Update proposal - fediverse/fep - Codeberg.org

This PR also includes new requirements for collections (cc @trwnh).

1 Like

Authorization of Delete and Undo activities: #380 - FEP-c7d3: Authorization of Delete and Undo activities - fediverse/fep - Codeberg.org

Delete activity is special because moderators should be able to delete objects that were created on their server. Lemmy allows that (although apparently it goes further and allows deletion of remote objects too - that doesn’t make sense to me and is not compatible with FEP-c7d3).
Therefore, instead of the “same owner” check, recipients of Delete activity should perform the “same origin” check. This reasoning can be applied to other activities too, because the real authority is server, not an actor, but I’d like to keep “same owner” recommendation for now.

Decided to change the “same owner” requirement to SHOULD and add a “same origin” requirement:

If activity modifies or deletes an object, its owner SHOULD match the object’s owner. If owners are different, their IDs MUST have the same origin.

1 Like

I’m changing the requirement from “same owner” to “same origin” in “Authentication” and adding text about ownership of public keys / verification methods: #387 - FEP-c7d3: Update proposal - fediverse/fep - Codeberg.org

The owner of an object MUST be an actor. It MUST NOT change during the lifetime of an object.

This seems like it locks out some potential futures where “ownership” does indeed change. I’m not sure I’m comfy with the idea that ownership is non-transferable.

Also the same-origin check is not necessarily “enough” in all cases. I know that right now because of the way web origins work, you have to trust the web origin instead of trusting the individual actor, but there are potential cases where actors on the same origin do not in fact have control over the entire origin. Example: https://example.com/~alice may have authority to create objects using the prefix https://example.com/~alice/, but not within any other prefix (such as https://example.com/~bob/ or https://example.com/). I don’t think there is a good way currently to express the “prefix” for which an actor has authority, is there?

1 Like

Then this FEP needs to specify how ownership transfer happens. Is it an Update activity? I think Update can be used to transfer ownership within a web origin (i.e. when origin(object.id) == origin(object.attributedTo)) . Transferring ownership to an actor on a different server probably shouldn’t be allowed.

Yes, the same-origin check is a minimal requirement, there might be additional application-specific constraints. I’ll clarify that in the text.

Even in this example, the owner of example.com is still the highest authority who has the power to create and modify any object with any prefix. I think the internal prefix-based permission system used at example.com can be expressed using extension properties (similarly to other permissions, e.g. reply permissions)

1 Like

In the latest commit I added “Identifiers and ownership” and “Ownership transfer” sections:

Identifier of an object and identifier of its owner MUST have the same origin.

When ownership changes, the new owner ID MUST have the same origin as the old owner ID.

I have a few notes.

First, I don’t think it makes sense to say that the object is authentic. Rather, it’s safer to say that the ownership relationship is authentic.

Second, consider an ActivityPub API client that implements a drawing tool. You can create, update, and delete pictures. For an actor https://social.example/user/evan, The client might push Create activities into the actor’s outbox like this:

{
    "@context": "https://www.w3.org/ns/activitystreams",
    "type": "Create",
    "to": "as:Public",
    "object": {
           "type": "Image",
           "id": "https://drawing.example/FJIhGP8Jp7CMWTO5hrjIW",
           "url": {
                 "type": "Link",
                 "mediaType": "image/svg+xml",
                 "href": "https://drawing.example/files/5CvE73Yib6pDJXuZPaGaI.svg"
           }
    }
}

Fetching that drawing might return something like this:

{
       "@context": "https://www.w3.org/ns/activitystreams",
      "attributedTo": "https://social.example/user/evan",
      "to": "as:Public",
     "type": "Image",
      "id": "https://drawing.example/FJIhGP8Jp7CMWTO5hrjIW",
      "url": {
             "type": "Link",
             "mediaType": "image/svg+xml",
             "href": "https://drawing.example/files/5CvE73Yib6pDJXuZPaGaI.svg"
      }
}

This is an authentic ownership relationship, but the domains don’t match.

One way to confirm this ownership is by finding the Create activity in the actor’s outbox. That’s a linear search through a collection of O(10^5) or more, with pages of 20 or 100 items at a time. There’s an issue in AP for making this kind of search faster. membership endpoint · Issue #462 · w3c/activitypub · GitHub

Finally, I think you should change “MUST discard” to “MAY discard”. There may be other ways to determine the owner of an object, besides the one above or the ones listed – for example, a trust metric on the sending server. Leave it open to other uses.

2 Likes