You don’t have to bring the notion in normatively but i’m always a fan of non-normatively
but explicitly mentioning places where divergent prior art has been observed, i.e. “how this applies to unattributed objects is out of scope of this FEP, but implicit attribution to server actors, implicit attribution to group actors, or implementation-specific behavior in cases of no attribution all have benefits and drawbacks.” Just so that readers don’t notice one implementation of this FEP doing X and not realize Y and Z are also possible, or assume X will be the case in all counterparties
I would prefer to say that relationship between objects can be trusted. Opened a PR that adds an explanation of the same-origin policy with a note saying that trust can be eastablished by other means. Perhaps this FEP should be renamed to “Trust and Authority” or something similar, because “ownership” doesn’t seem to be the main theme anymore.
If the embedded and the containing objects have owners with different origins, the authenticity of the embedded object MUST be verified independently either by fetching it from the server of origin, or by verifying its FEP-8b32 integrity proof.
Couldn’t the consumer optionally interpret as if the object were anonymous, instead? To give an extreme example, producers could assign an id
to an endpoints
object, but I think most consumers would simply ignore the id
and assume that the embedded representation is authentic.
I think that explains what Misskey is doing for embedded Emoji
objects:
Consumers may trust unauthenticated data if the risk is deemed acceptable (I should probably add this to the FEP). The effect of trusting unauthenticated embedded object would be the same as the effect of interpreting that object as anonymous, but I think the semantic difference is important: we are not disrespecting the producer’s intent, but relaxing our security checks for the sake of efficiency.
I added a note about acceptable risks to the FEP: #433 - FEP-c7d3: Update proposal - fediverse/fep - Codeberg.org
Also added a new section, “Access control”.
This is probably the last update, because I’m planning to publish a re-written version of this proposal under a different name, “Origin-based security model”. It seems that for authentication, “owner” doesn’t actually matter, and one should look at id
instead.
Can we have an “unowned” object - a gift to the commons object, a shared object?
A “dumb” question to bring up a complex issue.
“Owner” could be a Group
actor.
FEP-fe34: Origin-based security model has been published.
In this FEP authentication doesn’t depend on ownership. Instead, verifier compares origins of object IDs.
I’m withdrawing FEP-c7d3: Ownership in favor for FEP-fe34. I am now certain that origin-based model is correct and actor-centric view of ActivityPub is not.
This topic has been renamed.
FEP-fe34 is updated too: #509 - FEP-fe34: Update proposal - fediverse/fep - Codeberg.org
- Added “Implicit ownership” section.
- Added reference to FEP-2277.
This is a very contentious claim. Can you expand on it?
See the “Authentication” section of FEP-fe34.
Authentication doesn’t depend on actors. Only object id
matters (and its web origin).
That section has always been confusing to me (because of the terminology). Do you mean an activity is valid when you write that it’s authentic. I’m guessing not exactly that because an activity could be invalid for reasons not related to web origin.
RFC6554 (The Web Origin Concept) doesn’t use the words “authentic”, “authentication”, or “ownership”. They discuss “trust relationships” and “authority” (to access resources at the web origin). Does authentic, as used in the FEP, maybe mean trusted in some sense?
In any case, I think there’s another issue with that section.
When a signed activity is posted to the inbox, the web origin should be based on the owner URI of the key used to sign the activity rather than the key URI. We’ve discussed this before, but there’s no requirement for the key to have the same origin as the owner URI (e.g., in a key server scenario).
Yes, “trusted” is another word for it, but “authentic” seems more accurate to me (meaning “not forged”). Some authors use “valid”, but as you correctly noted, activity could be invalid for other reasons.
By authentication I mean the process of establishing the identity of a message sender (in FEP-c7d3 it was an actor, in FEP-fe34 it is a server).
The concept of ownership (and its relation to authorization) comes from the ActivityPub specification. For example, 6.6 Add Activity :
the
target
is not owned by the receiving server, and thus they are not authorized to update it.
Retrieving the key by its id
is enough. When it happens, a trusted relationship is established between the key and the server. Cryptographic signature creates a trusted relationship between the key and the signed object. These relationships are transitive, so verifier can trust the object.
owner
value still matters in authorization context, because an actor can’t own a key from another server.
There is an alternative to same-origin check, a bi-directional verification:
Key.owner
points toActor
.Actor.publicKey.id
points toKey
.
In that case the actor and the key can be on different origins. I don’t find this interesting, because this method requires additional HTTP requests, whereas same-origin check is a simple string comparison. As a note in the “Origin” section says:
There might be other ways to establish trust, but they are not covered by this document.
@stevebate I added a section discussing cross-origin relationships: #526 - FEP-fe34: Cross-origin relationships - fediverse/fep - Codeberg.org
It includes the example with keys that you put forward.
Definitions of “authentication” and “authorization” were added as well.
Authentication is the process of verifying the origin of an object.
Authorization is the process of verfying permission to create, read, update or delete an object.
Updated: #563 - FEP-fe34: Clarify scope - fediverse/fep - Codeberg.org
This PR clarifies the scope of the FEP: HTTP(S) identifiers and server-managed actors.
Further clarifications: #589 - FEP-fe34: Update proposal - fediverse/fep - Codeberg.org
- Servers MUST NOT store invalid objects received from clients.
- Servers MUST NOT allow clients to create objects representing public keys.
- Servers MUST NOT share secret keys with clients.
Why not?
What defines validity?
If clients are allowed to create public key objects with the server’s origin, they can generate a secret key, publish a corresponding public key object, and then produce an arbitrary signed object that satisfies authentication condition (3):
[Object] contains a valid FEP-8b32 integrity proof created using a key whose ID has the same origin as the object ID.
That signed object might not be valid according to the server of origin, but a malicious actor may trick other servers into accepting it.

What defines validity?
The server. It must not store (and serve) any objects until they are validated, because other servers assume that all objects served at the origin are valid (as long as authentication condition (1) is satisfied).

satisfies authentication condition (3):
Is this not an indication that the condition is incorrect? The origin of the key is not what you should be basing the decision on, you should be basing the decision on the controller
(or owner
) and whether that resource declares a backlink to the same key via some verificationMethod
(or publicKey
, or something more specific like authentication
or assertionMethod
or capabilityInvocation
, etc).
If you have a bidirectional link and between a key resource and a controller resource, then the controller can demonstrate proof of possession of the secret, and that proof can be used to associate the controller and the key for the declared purpose. So the only conditions that MUST be established are:
- Key points to controller
- Controller points to key
- Controller uses key secret to generate proof, and proof is valid (verifiable by the key)
At no point in this process does the origin of the key matter. You have demonstrated proof of possession, which is sufficient to fulfill some purpose (the predicate linking the controller to the key).

The server. It must not store (and serve) any objects until they are validated, because other servers assume that all objects served at the origin are valid (as long as authentication condition (1) is satisfied).
This doesn’t fully define validity. For example, you can serve a resource at an origin and it can be invalid due to syntax reasons.

Is this not an indication that the condition is incorrect?
It is correct given the assumptions listed in the FEP.
The bi-directional verification is covered in the Cross-origin relationships section. It can be used within an origin too, I will probably elaborate on that later. This type of verification is only useful for special cases, and currently I don’t see the need for special-casing signature verification.

This doesn’t fully define validity. For example, you can serve a resource at an origin and it can be invalid due to syntax reasons.
In the context of authentication, “valid” means “trusted”. Untrusted documents shouldn’t be served.