Addressing confusion between `Create` and contained object

In section 6.2 of ActivityPub, there’s this snippet:

A mismatch between addressing of the Create activity and its object is likely to lead to confusion. As such, a server SHOULD copy any recipients of the Create activity to its object upon initial distribution, and likewise with copying recipients from the object to the wrapping Create activity.

So as I understand it, a Create activity has addressing fields both on itself but also on its object, i.e. it has both the fields to, cc, bto, bcc but also the nested fields object.to, object.cc, object.bto and object.bcc. The snippet above suggest that these fields should be equal but this is not guaranteed. I suppose this also applies to other activities than Create.

Is there any guidance on what the behavior should be in the situation when the fields are not equal? I can think of a few possibilities:

  1. The addressing on the activity is used and the addressing on the object is ignored.
  2. The addressing on the object is used and the addressing on the activity is ignored.
  3. The addressing of the activity and object are combined, deduplicated and the resulting fields are used.

Option 3 is flexible but I’m worried it might introduce some weird edge cases, could be confusing and it also sounds more complicated to implement. My initial thought is that option 2 sounds most reasonable.

Any idea what approach some established implementations take, if they deal with this problem at all?

The Primer on addressing does not discuss this.

EDIT: A related question which probably has the same answer as the original question: What should happen if the actor of the Create is different than the attributedTo field of the object?

People don’t implement this, as they do not implement ActivityPub Client To Server.

All the nonsensical edge cases (some mentioned above), one could cook up for C2S are one of the reasons, I personally consider C2S unimplementable.

I’m not talking specifically about C2S, this happens for S2S as well (notice I posted this in the S2S category). My server receives a Create from another server with addressing both on the Create and on the object: which one to use?

It looks to me that option 3 is the closest match to the spec recommendation you quoted (two-way copy). That’s the C2S spec guidance.

No guidance for S2S. It could be a good topic for an FEP.

I think this topic is one of the many problem areas in the specification. What do “delivery addresses” mean for a created object? Those objects aren’t directly delivered. Activities are delivered. For S2S, one could argue that Create object-level addresses shouldn’t be allowed. The C2S case where it’s needed is when an object, posted to the outbox endpoint, is automatically wrapped in a Create activity (Section 6.2.1). In that case, I think it would be better to move (not copy) the addresses to the automatic activity before delivering it.

Another aspect of the S2S answer may be that the spec implicitly conflates delivery addressing with access authorization. The object’s “delivery addresses” are often used as a loose and ill-defined form of access control.

AFAIK, the AP spec doesn’t define this behavior either. I’m guessing a common response is to reject the activity as invalid. However, it would just as valid to ignore the object addresses in an S2S context (and derive authorization constraints from the activity addressing).

A more sophisticated authorization implementation might use “also known as” relationships to authorize the activity.

1 Like

I think the answer depends on what type of application you’re building. The addressing on the activity matters when it is POSTed to outbox and you decide where to deliver it. The addressing on the object matters when you decide who can view it and interact with it.

If application only implements S2S, I’d go with option 2.

In origin-based security model, actor and attributedTo must be on the same server. They still can be different actors, but that doesn’t make any sense, so I’d just treat such activities as invalid.

I just learned that Lemmy actually does send activities where the addressing does not match:

{
    "id": "https://lemmy.example/activities/create/ad54f1a4-be61-44fa-8fc2-daae18ba04f1",
    "actor": "https://lemmy.example/u/lemmy",
    "to": [
        "https://www.w3.org/ns/activitystreams#Public"
    ],
    "object": {
        "type": "Page",
        "id": "https://lemmy.example/post/2",
        "attributedTo": "https://lemmy.example/u/lemmy",
        "to": [
            "https://lemmy.example/c/lemmy",
            "https://www.w3.org/ns/activitystreams#Public"
        ],
        "name": "Hello from Lemmy!",
        "cc": [],
        "mediaType": "text/html",
        "attachment": [],
        "sensitive": false,
        "published": "2025-05-21T20:15:31.023976Z",
        "audience": "https://lemmy.example/c/lemmy",
        "tag": [
            {
                "href": "https://lemmy.example/post/2",
                "name": "#lemmy",
                "type": "Hashtag"
            }
        ]
    },
    "cc": [
        "https://lemmy.example/c/lemmy"
    ],
    "type": "Create",
    "audience": "https://lemmy.example/c/lemmy"
}

Note that the outer Create activity has to: ["https://www.w3.org/ns/activitystreams#Public"] and cc: ["https://lemmy.example/c/lemmy"] while the inner Page object has to: ["https://lemmy.example/c/lemmy", "https://www.w3.org/ns/activitystreams#Public"] and cc: [].

@nutomic perhaps this is something you’d like to fix - the spec suggests that the addressing on Create and its contained object should be equal.

Are you referring to Section 6.2 in the AP spec? If so, that’s discussing C2S, not S2S. The last sentence of that section discusses at least one scenario where an activity may have different addressing than the object.


That said, the things that AP delivers are activities so I’d would expect that delivery/audience targeting to take precedence (but the spec is vague about it).

In my opinion, this aspect of the specification has many issues. AP seems to conflate inbox delivery targeting with AS2 audience targeting. The AS2 audience targeting appears to me to be more related to visibility and notification than delivery (there’s no concept of an inbox or delivery in AS2). AP has mixed all three concepts together in a way that’s very confusing (to me, at least). To be fair, delivery and visibility are related in the sense that an authorized remote actor can’t view your object unless it’s been delivered to them (or they dereferenced it).

Personally, I’d consider activity “audience targeting” to be delivery-related and object “audience targeting” to be visibility-related. If so, the example you quoted would be interpreted as being delivered nowhere (as:Public is not a delivery target), but the activity and the object is visible to everyone (maybe on the local server timelines and search since it wouldn’t be delivered elsewhere?).

Sorry what scenario and what sentence? Section 6.2 in ActivityPub is about the Create activity and states:

Any to, bto, cc, bcc, and audience properties specified on the object MUST be copied over to the new Create activity by the server.

Yes, this is specifically talking about C2S but I don’t think it’s a big leap to interpret the clear intention here - that a Create and its contained object should have the same addressing. I think this snippet also makes this intent clear:

A mismatch between addressing of the Create activity and its object is likely to lead to confusion. As such, a server SHOULD copy any recipients of the Create activity to its object upon initial distribution, and likewise with copying recipients from the object to the wrapping Create activity. Note that it is acceptable for the object’s addressing to be changed later without changing the Create’s addressing (for example via an Update activity).

It may not be stated explicitly, but I feel that the “spirit of the spec” here is that the addressing should be equal.

1 Like

I can’t debate your opinion about “the spirit of the spec”, but C2S is not the same as S2S and it has different requirements. The MUST you quoted is specifically about using C2S to create an object without an activity. The activity is automatically created, and since the activity addressing is used for delivery, the object’s addressing is the only source for that. It’s for a very specific C2S requirement (6.2.1).

The spec also discusses cases where an activity addressing may differ from the object (as I mentioned in my earlier message).

I couldn’t find what you are referring to here, could you give me a citation?

Last sentence of Section 6.2…

Note that it is acceptable for the object 's addressing to be changed later without changing the Create 's addressing (for example via an Update activity.

Although this is post-delivery, it does hint that it’s acceptable for activity and object “addressing” to differ, in general.

1 Like