Back to Codeberg

feat: adr to redefine FederationHost relation #85

forgejo-contrib-federation-pulls-85.md

latest121.0 KB
Original Source

forgejo-contrib/federation

Watch21

Star82

Fork

You've already forked federation

6

CodeIssues 16Pull requests 8Projects 2ActivityActions

feat: adr to redefine FederationHost relation #85

Merged

jergermerged 15 commits from :feat/adr-soften-federation-host-relation into main 2026-06-18 17:12:12 +02:00

Conversation 37Commits 15Files changed 1 +251

jerger commented 2026-01-13 19:20:03 +01:00

Owner

Copy link

No description provided.

jerger added 1 commit 2026-01-13 19:20:04 +01:00

first try 8dc289fd7f

0xllx0 reviewed 2026-01-13 19:29:20 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show outdated Hide outdated

| | | | @ -0,0 +67,4 @@ | | | | | | | | | | | | #### 1.c Consequence | | | | | | | | | | | | We will have to find a reliable algo for resolving the instance actor URL to retrieve. |

0xllx0 commented 2026-01-13 19:29:20 +01:00

Collaborator

Copy link

I think when we don't have an existing FederationHost record for a FederatedUser, we should fetch the InstanceActor record from the remote instance. Then, we can construct the FederationHost from the InstanceActor. We may also want to extend the information we store in FederationHost so that we can reconstruct an InstanceActor when needed.

Alternatively, we could refactor the FederationHost into an InstanceActor, and do all the necessary migrations. Probably more work, but might result in less conceptual context-switching.

I think when we don't have an existing FederationHost record for a FederatedUser, we should fetch the InstanceActor record from the remote instance. Then, we can construct the FederationHost from the InstanceActor. We may also want to extend the information we store in FederationHost so that we can reconstruct an InstanceActor when needed. Alternatively, we could refactor the FederationHost into an InstanceActor, and do all the necessary migrations. Probably more work, but might result in less conceptual context-switching.

silverpill commented 2026-01-14 16:37:07 +01:00

First-time contributor

Copy link

We will have to find a reliable algo for resolving the instance actor URL to retrieve.

There is no reliable way to do it.

Mechanisms like FEP-d556 are not widely implemented, and some software simply don't have a concept of an instance actor. For example: single-user blogs that host a single Person actor.

>We will have to find a reliable algo for resolving the instance actor URL to retrieve. There is no reliable way to do it. Mechanisms like FEP-d556 are not widely implemented, and some software simply don't have a concept of an instance actor. For example: single-user blogs that host a single Person actor.

jerger commented 2026-01-15 09:13:06 +01:00

Author

Owner

Copy link

Exactly at this point of implementation our discussion started. We have the Problems @silverpill is describing.

Exactly at this point of implementation our discussion started. We have the Problems @silverpill is describing.

0xllx0 commented 2026-01-15 17:10:59 +01:00

Collaborator

Copy link

That makes me think we should just keep the FederationHost, and do a best effort to reconstruct an InstanceActor from a FederationHost. It would be less refactoring, and would be a good basis for implementing FEP-d556 in the future (if we decide to).

Do we need to add/store more metadata in FederationHost to reconstruct an InstanceActor?

That makes me think we should just keep the FederationHost, and do a best effort to reconstruct an InstanceActor from a FederationHost. It would be less refactoring, and would be a good basis for implementing FEP-d556 in the future (if we decide to). Do we need to add/store more metadata in FederationHost to reconstruct an InstanceActor?

0xllx0 commented 2026-01-15 23:08:03 +01:00

Collaborator

Copy link

Regarding FEP-d556, I think if we are going to implement something like this FEP-2677 is a much better candidate.

After a discussion with @famfo, we are already using the Application type to represent our instance-wide Actor, and FEP-2677 is more widely implemented. Supporting that FEP is one motivation for my proposal to store more information in the FederationHost structure, so that we can construct a Application Actor. This could potentially enable us to also reconstruct distant instance-wide actors cached in the local DB, though @famfo suggested just re-fetching from the distant server.

Regarding FEP-d556, I think if we are going to implement something like this FEP-2677 is a much better candidate. After a discussion with @famfo, we are already using the Application type to represent our instance-wide Actor, and FEP-2677 is more widely implemented. Supporting that FEP is one motivation for my proposal to store more information in the FederationHost structure, so that we can construct a Application Actor. This could potentially enable us to also reconstruct distant instance-wide actors cached in the local DB, though @famfo suggested just re-fetching from the distant server.

silverpill commented 2026-01-16 22:21:35 +01:00

First-time contributor

Copy link

FEP-2677 is more widely implemented

@0xllx0 The list of FEP-2677 implementations includes only 3 projects, but FEP-d556 has 4 (and it's not complete; there is also WordPress and others).

You can still use Application actor type with FEP-d556, the main difference between two proposals is discovery mechanism: WebFinger vs NodeInfo. I think NodeInfo is not the right choice because it is used mainly for aggregating network stats, and instance operators sometimes want to hide / disable them.

>FEP-2677 is more widely implemented @0xllx0 The list of FEP-2677 implementations includes only 3 projects, but FEP-d556 has 4 (and it's not complete; there is also WordPress and others). You can still use Application actor type with FEP-d556, the main difference between two proposals is discovery mechanism: WebFinger vs NodeInfo. I think NodeInfo is not the right choice because it is used mainly for aggregating network stats, and instance operators sometimes want to hide / disable them.

0xllx0 commented 2026-01-19 20:44:11 +01:00

Collaborator

Copy link

@silverpill wrote in #85 (comment):

The list of FEP-2677 implementations includes only 3 projects, but FEP-d556 has 4 (and it's not complete; there is also WordPress and others)

You're right, I was looking at the list of Application Actor implementations (versus the Instance Actor).

You can still use Application actor type with FEP-d556, the main difference between two proposals is discovery mechanism: WebFinger vs NodeInfo. I think NodeInfo is not the right choice because it is used mainly for aggregating network stats, and instance operators sometimes want to hide / disable them.

I agree that WebFinger is probably the better choice. We already have an implementation of WebFinger that could be expanded, and it seems to have adoption across the ecosystem.

@silverpill wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-9915915: > The list of FEP-2677 implementations includes only 3 projects, but FEP-d556 has 4 (and it's not complete; there is also WordPress and others) You're right, I was looking at the list of Application Actor implementations (versus the Instance Actor). > You can still use Application actor type with FEP-d556, the main difference between two proposals is discovery mechanism: WebFinger vs NodeInfo. I think NodeInfo is not the right choice because it is used mainly for aggregating network stats, and instance operators sometimes want to hide / disable them. I agree that WebFinger is probably the better choice. We already have an implementation of WebFinger that could be expanded, and it seems to have adoption across the ecosystem.

0xllx0 reviewed 2026-01-13 19:37:13 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show resolved Hide resolved

| | | | @ -0,0 +72,4 @@ | | | | | | ### 2. Weaken the relation between FederatedUser and FederationHost | | | | | | | | | | | | 1. The FederatedUser and FederationHost have an Independent lifecycle. | | | | | | 2. Relation FederatedUser - FederationHostis defined by a normalizedhostname+port derived out of UserActorId and InstanceActorId. |

0xllx0 commented 2026-01-13 19:37:13 +01:00

Collaborator

Copy link

The InstanceActorId should be a substring of the UserActorId, right?

For example, on the host https://forgejo.org:

So, it would be strange for an implementation to include a port in one actor ID, and not the other.

Do any of our currently supported platforms (GoToSocial, Mastodon) show this behavior:

The InstanceActorId should be a substring of the UserActorId, right? For example, on the host https://forgejo.org: - InstanceActorId: "https://forgejo.org" - UserActorId: "https://forgejo.org/some-user" - not using this exact path, just an example - could also be "https://forgejo.org/api/v1/actor/some-user" So, it would be strange for an implementation to include a port in one actor ID, and not the other. Do any of our currently supported platforms (GoToSocial, Mastodon) show this behavior: - InstanceActorId: "https://site.tld:443" - UserActorId: "https://site.tld/some-user" - or - InstanceActorId: "https://site.tld" - UserActorId: "https://site.tld:443/some-user"

jerger commented 2026-01-15 09:15:32 +01:00

Author

Owner

Copy link

The InstanceActorId should be a substring of the UserActorId, right?

How to calculate the InstanceActor is not part of AP standard.

So, it would be strange for an implementation to include a port in one actor ID, and not the other.

Agree.

> The InstanceActorId should be a substring of the UserActorId, right? How to calculate the InstanceActor is not part of AP standard. > So, it would be strange for an implementation to include a port in one actor ID, and not the other. Agree.

jerger marked this conversation as resolved

jerger changed title from ** feat: adr to weaken FederationHost relation ** to WIP feat: adr to weaken FederationHost relation 2026-01-14 13:53:56 +01:00

jerger added 1 commit 2026-01-15 09:07:14 +01:00

elaborate on the option 2 b6b99c44b7

jerger added 1 commit 2026-01-15 09:11:37 +01:00

add out of scopes ee3553451f

jerger added 1 commit 2026-01-15 09:16:42 +01:00

Merge branch 'main' of codeberg.org:forgejo-contrib/federation into feat/adr-soften-federation-host-relation 35afd7c91b

jerger commented 2026-01-15 09:18:17 +01:00

Author

Owner

Copy link

@famfo @0xllx0 @silverpill Now I elaborate more what option2 will be.

@famfo @0xllx0 @silverpill Now I elaborate more what option2 will be.

๐Ÿ‘€ 1

jerger changed title from ** WIP feat: adr to weaken FederationHost relation ** to feat: adr to weaken FederationHost relation 2026-01-15 09:18:43 +01:00

jerger added 1 commit 2026-01-15 09:21:47 +01:00

wording c8b514fdc6

famfo reviewed 2026-01-15 09:42:59 +01:00

famfo left a comment

Copy link

I much prefer the second option because, in my opinion, the instance actor is more of an implementation detail than root of trust for an instance. Moderation in the form of domain blocks is still very much possible with the second option because a federation host can easily be derived from the KeyID on a request.

As noted in the consequences already, this simplifies the implementation a lot and ensures that federation is also possible with implementations that do not fall into the more or less narrow implementation to find the instance actor.

I much prefer the second option because, in my opinion, the instance actor is more of an implementation detail than root of trust for an instance. Moderation in the form of domain blocks is still very much possible with the second option because a federation host can easily be derived from the KeyID on a request. As noted in the consequences already, this simplifies the implementation a lot and ensures that federation is also possible with implementations that do not fall into the more or less narrow implementation to find the instance actor.

๐Ÿ‘ 2

architecture/adr/adr-soften-relation-to-federation-host.md

Show resolved Hide resolved

| | | | @ -0,0 +135,4 @@ | | | | | | | | | | | | #### 2.c Consequence | | | | | | | | | | | | 1. We can get rid of normalization of ActorID, normalization of normalizedHostAddress can be well defined. |

famfo commented 2026-01-15 09:33:32 +01:00

Collaborator

Copy link

We can't get rid of this entirely, there are still the cases

  1. supplemented default ports
  2. missing schema for a URL (which should be defaulted to https)

We can't get rid of this entirely, there are still the cases 1. supplemented default ports 2. missing schema for a URL (which should be defaulted to https)

jerger commented 2026-01-15 10:22:19 +01:00

Author

Owner

Copy link

We will need normalization only for calculating the NormalizedHostAddress (used for the * - FederationHost relation).
For being distinct fqdn + port would be sufficient. Scheme will not be mandantory, but maybe it makes sense to keep it in order to use the URL utilities.

We might block some ActorIDs as expressed in the normalization PR but there will be no need to change the ActorID was sent from distant any more.

We will need normalization only for calculating the NormalizedHostAddress (used for the * - FederationHost relation). For being distinct fqdn + port would be sufficient. Scheme will not be mandantory, but maybe it makes sense to keep it in order to use the URL utilities. We might block some ActorIDs as expressed in the normalization PR but there will be no need to change the ActorID was sent from distant any more.

famfo commented 2026-01-15 10:28:14 +01:00

Collaborator

Copy link

Yes, that addressing should be enough for a federation host, just wanted to note it again ^^

We need to decide if we want to store punicode or utf-8 fqdns in tge future though

Yes, that addressing should be enough for a federation host, just wanted to note it again ^^ We need to decide if we want to store punicode or utf-8 fqdns in tge future though

0xllx0 commented 2026-01-15 17:16:14 +01:00

Collaborator

Copy link

@famfo wrote in #85 (comment):

We need to decide if we want to store punicode or utf-8 fqdns in tge future though

We should store whatever signed key ID (IRI) is sent (after validation). So, if we don't currently support storing valid UTF-8, we should.

@famfo wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-9878105: > We need to decide if we want to store punicode or utf-8 fqdns in tge future though We should store whatever signed key ID (IRI) is sent (after validation). So, if we don't currently support storing valid UTF-8, we should.

๐Ÿ‘ 1

famfo commented 2026-01-15 17:54:18 +01:00

Collaborator

Copy link

This is not exactly how domain encoding works. Both "domรคin.example" and "xn--domin-ira.example" are the same domain, one in UTF-8 and one in punycode. These domains should still be comparable so they need to be converted into one or the other for comparison.

This is not exactly how domain encoding works. Both "domรคin.example" and "xn--domin-ira.example" are the same domain, one in UTF-8 and one in punycode. These domains should still be comparable so they need to be converted into one or the other for comparison.

jerger commented 2026-01-15 18:59:02 +01:00

Author

Owner

Copy link

"domรคin.example" and "xn--domin-ira.example"

When we fetch identifiers from distant server, I would expect to get the same representation from InstanceActor & other actors. Why should we ensure cross encoding equivalence ?

The only thing we've to ensure is that we can store all needed chars and that store / load does not change string content.

> "domรคin.example" and "xn--domin-ira.example" When we fetch identifiers from distant server, I would expect to get the same representation from InstanceActor & other actors. Why should we ensure cross encoding equivalence ? The only thing we've to ensure is that we can store all needed chars and that store / load does not change string content.

๐Ÿ‘ 1

0xllx0 commented 2026-01-15 20:55:41 +01:00

Collaborator

Copy link

@jerger wrote in #85 (comment):

Why should we ensure cross encoding equivalence ?

I agree, this is a concern for browsers, not for our purposes. I understand the same domain name can be represented differently, but would find it highly suspicious for an ActivityPub implementation to use one encoding for one actor, and another encoding somewhere else.

If an instance changes which encoding it uses, e.g. from punycode to UTF-8, then I would expect we would see a new signature over IDs with the new encoding. In that case, we would just create new entries, since they wouldn't match what we have in the database.

Until we see this in practice, I do not think it is a big concern.

@jerger wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-9888998: > Why should we ensure cross encoding equivalence ? I agree, this is a concern for browsers, not for our purposes. I understand the same domain name can be represented differently, but would find it highly suspicious for an ActivityPub implementation to use one encoding for one actor, and another encoding somewhere else. If an instance changes which encoding it uses, e.g. from punycode to UTF-8, then I would expect we would see a new signature over IDs with the new encoding. In that case, we would just create new entries, since they wouldn't match what we have in the database. Until we see this in practice, I do not think it is a big concern.

famfo commented 2026-01-15 21:14:42 +01:00

Collaborator

Copy link

I strongly disagree. It is the same thing so why should it be treated differently. There are also cases in which URLs instead of IRIs are used which also requires converting things between different encodings.

I would rather do it correctly now than try to fix it later.

I strongly disagree. It is the same thing so why should it be treated differently. There are also cases in which URLs instead of IRIs are used which also requires converting things between different encodings. I would rather do it correctly now than try to fix it later.

0xllx0 commented 2026-01-15 21:15:53 +01:00

Collaborator

Copy link

Are you actually seeing this, or just trying to think of all possible edge cases?

Are you actually seeing this, or just trying to think of all possible edge cases?

famfo commented 2026-01-15 21:25:56 +01:00

Collaborator

Copy link

I am fairly sure that there was one of these cases. Depending on the implementation, http signature KeyIDs can also be either (it is just a string value as per the specification).

I am fairly sure that there was one of these cases. Depending on the implementation, http signature KeyIDs can also be either (it is just a string value as per the specification).

0xllx0 commented 2026-01-15 22:58:36 +01:00

Collaborator

Copy link

Right, I agree we should support punycode, UTF-8, or any other valid encoding used for IRIs/IDs.

What I'm asking is are you seeing any implementations where a single implementation is using different encodings for Actor types, or different IRI fields in the same Actor?

For example, Mastodon using punycode for an Actor ID, and UTF-8 for a Follower ID?

Right, I agree we should support punycode, UTF-8, or any other valid encoding used for IRIs/IDs. What I'm asking is are you seeing any implementations where a single implementation is using different encodings for Actor types, or different IRI fields in the same Actor? For example, Mastodon using punycode for an Actor ID, and UTF-8 for a Follower ID?

jerger commented 2026-01-16 11:24:26 +01:00

Author

Owner

Copy link

@famfo where/when should happen this cross-encoding normalization & what should be the algo ?

@famfo where/when should happen this cross-encoding normalization & what should be the algo ?

famfo commented 2026-01-16 22:26:46 +01:00

Collaborator

Copy link

We will need consistent encoding for every comparison of a domain, so probably on construction of a federation host and database operation.

We will need consistent encoding for every comparison of a domain, so probably on construction of a federation host and database operation.

famfo commented 2026-01-21 14:21:19 +01:00

Collaborator

Copy link

Resolving this in favor of proposal 3.

Resolving this in favor of proposal 3.

famfo marked this conversation as resolved

jerger added 1 commit 2026-01-15 10:25:11 +01:00

fix NormalizedHostAddress 556d75a778

jerger added 1 commit 2026-01-15 10:26:13 +01:00

add one more out of scope discussion fadbc6419b

jerger added 1 commit 2026-01-15 10:38:22 +01:00

small fix 0264fcf650

silverpill reviewed 2026-01-15 21:35:36 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show outdated Hide outdated

| | | | @ -0,0 +64,4 @@ | | | | | | ### 2. Weaken the relation between FederatedUser and FederationHost | | | | | | | | | | | | 1. The FederatedUser and FederationHost have an Independent lifecycle. | | | | | | 2. Relation FederatedUser - FederationHostis defined by a normalizedhostname+port derived out of UserActorID and InstanceActorID. |

silverpill commented 2026-01-15 21:35:36 +01:00

First-time contributor

Copy link

Sounds reasonable, my implementation also derives hostname from actor ID.

Sounds reasonable, my implementation also derives hostname from actor ID.

0xllx0 commented 2026-01-15 23:01:18 +01:00

Collaborator

Copy link

From a discussion on Matrix with @famfo, I think we should also be storing more information in the FederationHost DB structure.

At a minimum, I think we should store the ActivityPub Actor type, along with the original Actor ID. This might fit better in a separate ADR, though.

From a discussion on Matrix with @famfo, I think we should also be storing more information in the FederationHost DB structure. At a minimum, I think we should store the ActivityPub Actor type, along with the original Actor ID. This might fit better in a separate ADR, though.

jerger commented 2026-01-16 08:21:25 +01:00

Author

Owner

Copy link

@0xllx0 wrote in #85 (comment):

From a discussion on Matrix with @famfo, I think we should also be storing more information in the FederationHost DB structure.

At a minimum, I think we should store the ActivityPub Actor type, along with the original Actor ID. This might fit better in a separate ADR, though.

Yes. The refactoring caused by this discussion will be huge. Let's not add more to this ....

@0xllx0 wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-9893729: > From a discussion on Matrix with @famfo, I think we should also be storing more information in the FederationHost DB structure. > > At a minimum, I think we should store the ActivityPub Actor type, along with the original Actor ID. This might fit better in a separate ADR, though. Yes. The refactoring caused by this discussion will be huge. Let's not add more to this ....

๐Ÿ‘ 1

jerger requested reviews from famfo, 0xllx0 2026-01-16 11:22:46 +01:00

jerger added 1 commit 2026-01-21 09:13:13 +01:00

update reflecting the weekly discussion c5fbd25a04

famfo reviewed 2026-01-21 14:29:02 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md

Show resolved Hide resolved

| | | | @ -0,0 +153,4 @@ | | | | | | 1. The FederationHost is created as soon as the first federatedUser for the defined distant instacne is created. | | | | | | 2. Relation FederatedUser - FederationHostis defined by a normalizedhostname+port derived out of UserActorID and InstanceActorID. | | | | | | 3. As there is no clear definition about instance actors, the FederationHost just represents the instance. Other properties related to an instance actor will be removed from FederationHost. | | | | | | 4. The PublicKey will be allowed to carry the InstanceActor key without realized relation to the actor related, if the actor type is not available in Forgejo. |

famfo commented 2026-01-21 14:29:02 +01:00

Collaborator

Copy link

diff
- 4. The PublicKey will be allowed to carry the InstanceActor key without realized relation to the actor related, if the actor type is not available in Forgejo. 
+ 4. The InstanceActor key will be put into the public key table, even if the actor type is not available in Forgejo.

I think this is a bit more clear?

diff - 4. The PublicKey will be allowed to carry the InstanceActor key without realized relation to the actor related, if the actor type is not available in Forgejo. + 4. The InstanceActor key will be put into the public key table, even if the actor type is not available in Forgejo. I think this is a bit more clear?

๐Ÿ‘ 1

famfo marked this conversation as resolved

jerger added 1 commit 2026-01-22 10:29:15 +01:00

follow famfos comment af878f642f

jerger commented 2026-01-27 17:23:57 +01:00

Author

Owner

Copy link

we choose option3

we choose option3

jerger commented 2026-01-27 17:29:09 +01:00

Author

Owner

Copy link

We use AP as Actor type as model.actorType,
if instance actor has type of application we store the public key only.

We use AP as Actor type as model.actorType, if instance actor has type of application we store the public key only.

jerger commented 2026-01-27 17:34:47 +01:00

Author

Owner

Copy link

we store fqdn as utf8 in database

we store fqdn as utf8 in database

jerger added 1 commit 2026-01-28 08:23:56 +01:00

update adr to reflect our discussion 3853652b9c

jerger added 1 commit 2026-01-28 08:25:45 +01:00

update adr to reflect our discussion b39c645917

jerger changed title from ** feat: adr to weaken FederationHost relation ** to feat: adr to redefine FederationHost relation 2026-01-28 08:26:51 +01:00

jerger added the due date 2026-01-29 2026-01-28 08:28:46 +01:00

famfo approved these changes 2026-01-28 17:07:34 +01:00

0xllx0 reviewed 2026-01-28 17:38:11 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show resolved Hide resolved

| | | | @ -0,0 +95,4 @@ | | | | | | namespace module.forgefed { | | | | | | class ActorID { | | | | | | ID string | | | | | | NormalizedHostAddress string |

0xllx0 commented 2026-01-28 17:38:11 +01:00

Collaborator

Copy link

I don't see a need to store the NormalizedHostAddress in the data structure. If it is necessary for there to be a NormalizedHostAddress for comparison, like we discussed, we could just have a method NormalizedHostAddress that normalizes the address.

Carrying around this extra data which can be recalculated from the ID field is a waste of memory.

I don't see a need to store the NormalizedHostAddress in the data structure. If it is necessary for there to be a NormalizedHostAddress for comparison, like we discussed, we could just have a method NormalizedHostAddress that normalizes the address. Carrying around this extra data which can be recalculated from the ID field is a waste of memory.

jerger commented 2026-01-28 17:56:53 +01:00

Author

Owner

Copy link

As we consider to choose option3 do you want to discuss a more elaborated on option2 ?

As we consider to choose option3 do you want to discuss a more elaborated on option2 ?

0xllx0 commented 2026-01-28 18:35:59 +01:00

Collaborator

Copy link

No, I made this comment before realizing we were going with option 3.

If we are dropping the NormalizedHostAddress field in option 3, you can mark this conversation resolved.

No, I made this comment before realizing we were going with option 3. If we are dropping the NormalizedHostAddress field in option 3, you can mark this conversation resolved.

jerger marked this conversation as resolved

0xllx0 reviewed 2026-01-28 17:39:42 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show resolved Hide resolved

| | | | @ -0,0 +110,4 @@ | | | | | | <<Aggregate Root>> | | | | | | ID int64 | | | | | | ActorID string | | | | | | NormalizedHostAddress string |

0xllx0 commented 2026-01-28 17:39:42 +01:00

Collaborator

Copy link

Same as comment above, but even more important for the models data structures. Since these records will be persisted in the database, we need to be even more concerned about memory footprint.

Same as comment above, but even more important for the models data structures. Since these records will be persisted in the database, we need to be even more concerned about memory footprint.

jerger marked this conversation as resolved

0xllx0 reviewed 2026-01-28 17:42:43 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md

Show resolved Hide resolved

| | | | @ -0,0 +147,4 @@ | | | | | | | | | | | | 1. We can get rid of normalization of ActorID, normalization of NormalizedHostAddress can be well defined. | | | | | | 2. We can get rid of the create FederationHost when creating a FederatedUser side effect. | | | | | | 3. We can get rid of complicated ActorID, PersonId, RepositoryID parsing & validation. |

0xllx0 commented 2026-01-28 17:42:43 +01:00

Collaborator

Copy link

We still want to validate any incoming IRIs, which I'm assuming all of these are IRIs.

So, no we can't "get rid of complicated parsing & validation".

We still want to validate any incoming IRIs, which I'm assuming all of these are IRIs. So, no we can't "get rid of complicated parsing & validation".

jerger commented 2026-01-28 18:00:11 +01:00

Author

Owner

Copy link

I do not intend to drop parsing & validation completely. But I think we can drop the person specific parts & the software specific parts. This will make the code much more lightweight.

What better wording do you propose ?

I do not intend to drop parsing & validation completely. But I think we can drop the person specific parts & the software specific parts. This will make the code much more lightweight. What better wording do you propose ?

0xllx0 commented 2026-01-28 18:10:07 +01:00

Collaborator

Copy link

What better wording do you propose ?

Adding sub list items explaining which parts of parsing + validation are proposed for removal with justifications for why they are no longer needed / do not open security vulnerabilities. For example, is the input already sanitized against relevant attacks, and this additional processing is related to functionality obsoleted by this proposal?

diff
- 3. We can get rid of complicated ActorID, PersonId, RepositoryID parsing & validation.
+ 3. We can remove portions of parsing & validation code that are made obsolete by these proposed changes:
+ - <each ID type>: list of parsing + validation code that can be removed, with justifications.

> What better wording do you propose ? Adding sub list items explaining which parts of parsing + validation are proposed for removal with justifications for why they are no longer needed / do not open security vulnerabilities. For example, is the input already sanitized against relevant attacks, and this additional processing is related to functionality obsoleted by this proposal? diff - 3. We can get rid of complicated ActorID, PersonId, RepositoryID parsing & validation. + 3. We can remove portions of parsing & validation code that are made obsolete by these proposed changes: + - \<each ID type\>: list of parsing + validation code that can be removed, with justifications.

jerger commented 2026-01-29 08:26:46 +01:00

Author

Owner

Copy link

You are talking about option2? Anyhow the consequence is comparable placed in Option3.

I prefer to let this detail open till we come to the implementation.

You are talking about option2? Anyhow the consequence is comparable placed in Option3. I prefer to let this detail open till we come to the implementation.

jerger marked this conversation as resolved

0xllx0 reviewed 2026-01-28 17:46:55 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md

| | | | @ -0,0 +158,4 @@ | | | | | | 1. The FederationHost is created as soon as the first federatedUser for the defined distant instacne is created. | | | | | | 2. Relation FederatedUser - FederationHostis defined by a normalizedhostname+port derived out of UserActorID and InstanceActorID. | | | | | | 3. As there is no clear definition about instance actors, the FederationHost just represents the instance. Other properties related to an instance actor will be removed from FederationHost. | | | | | | 4. The PublicKey will be allowed to carry the InstanceActor key without realized relation to the actor related, if the actor type is not available in Forgejo. |

0xllx0 commented 2026-01-28 17:46:55 +01:00

Collaborator

Copy link

I'm not sure what you mean by this. If we have the key material, and the actor information, what is the purpose of storing the public key but not the actor (and populating the relevant ActorID field in the public key record)?

If the actor type is not available in Forgejo, then we should reject the record with loud logging messages about the failure. Then, we can add support for the actor type. Mangling the database relations like this does not seem like a good idea.

I'm not sure what you mean by this. If we have the key material, and the actor information, what is the purpose of storing the public key but not the actor (and populating the relevant ActorID field in the public key record)? If the actor type is not available in Forgejo, then we should reject the record with loud logging messages about the failure. Then, we can add support for the actor type. Mangling the database relations like this does not seem like a good idea.

jerger commented 2026-01-29 08:33:24 +01:00

Author

Owner

Copy link

Some InstanceActors have the Application type. I see no reason to cache the ApplicationActor in Forgejo.

But the InstanceActors key we should cache.

Is your Argument:

  • We should not store InstanceActors key? This would cause very much traffic to ask the distant server each time.
  • We should cache the Application Type? This would add complexity & demand for storarge without other benefit than just fulfilling the rule that relation to actor is mandantory.

Some InstanceActors have the Application type. I see no reason to cache the ApplicationActor in Forgejo. But the InstanceActors key we should cache. Is your Argument: * We should not store InstanceActors key? This would cause very much traffic to ask the distant server each time. * We should cache the Application Type? This would add complexity & demand for storarge without other benefit than just fulfilling the rule that relation to actor is mandantory.

famfo commented 2026-01-29 14:38:04 +01:00

Collaborator

Copy link

I think it would be a bit clearer to say:

diff
- 4. The PublicKey will be allowed to carry the InstanceActor key without realized relation to the actor related, if the actor type is not available in Forgejo. 
+ 4. PublicKeys of known ActivityPub actor types are stored in Forgejo, even if Forgejo does not have special handling for them yet.

Talking about implementation details, this could be realized by a stub actor table which holds some basic information like ID, type, inbox and outbox, future migrations could move certain types into their respective tables.

I think it would be a bit clearer to say: diff - 4. The PublicKey will be allowed to carry the InstanceActor key without realized relation to the actor related, if the actor type is not available in Forgejo. + 4. PublicKeys of known ActivityPub actor types are stored in Forgejo, even if Forgejo does not have special handling for them yet. --- Talking about implementation details, this could be realized by a stub actor table which holds some basic information like ID, type, inbox and outbox, future migrations could move certain types into their respective tables.

๐Ÿ‘ 1

0xllx0 commented 2026-01-29 20:49:23 +01:00

Collaborator

Copy link

@jerger wrote in #85 (comment):

Some InstanceActors have the Application type. I see no reason to cache the ApplicationActor in Forgejo.

We store a form of the Application Actor in the database in the form of the FederationHost records. I have made the point multiple times that it would be good to store more of the information from the Application Actor, if not just fully storing the Application Actor (in place of the FederationHost).

But the InstanceActors key we should cache.

"Instance" Actors are not a part of the ActivityPub specification, nor of ForgeFed. Application Actors are part of the ActivityPub specification. Please explain your reasoning.

Is your Argument:

* We should not store InstanceActors key? This would cause very much traffic to ask the distant server each time.

No, quit twisting my words. I was very explicit in what I said. If we store the public key of an Actor, we should store the related Actor information in a database record. Currently, the two "Actor" types we store records for are FederatedUser and FederationHost, which are both internal Actor types (not defined in a fediverse specification).

Whether it is an internal Actor representation, or we create records for actually specified Actors, we should store some form of the Actor record in the database. This allows us to reference that other table in the database from the public key table, which your suggestion would break. I think breaking that relation is a bad idea, would require a lot of refactor work, and does not give us any meaningful gains for all of that effort. In fact, I think this change would be a regression.

* We should cache the Application Type? This would add complexity & demand for storarge without other benefit than just fulfilling the rule that relation to actor is mandantory.

We can either store the Application Actor, or convert the Application Actor into a FederationHost. Maybe that means we need to ad some fields to the FederationHost data structure, and some functions to handle the conversion. Since those would be additive refactors, it would be much less work, and would minimally impact storage requirements.

I would prefer, going forward, that we stay as close to the data structures defined in the specifications we are implementing. Doing so makes it much easier to follow along in the code, especially for new-comers.

@jerger wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10244420: > Some InstanceActors have the Application type. I see no reason to cache the ApplicationActor in Forgejo. We store a form of the Application Actor in the database in the form of the FederationHost records. I have made the point multiple times that it would be good to store more of the information from the Application Actor, if not just fully storing the Application Actor (in place of the FederationHost). > But the InstanceActors key we should cache. "Instance" Actors are not a part of the ActivityPub specification, nor of ForgeFed. Application Actors are part of the ActivityPub specification. Please explain your reasoning. > Is your Argument: > > * We should not store InstanceActors key? This would cause very much traffic to ask the distant server each time. No, quit twisting my words. I was very explicit in what I said. If we store the public key of an Actor, we should store the related Actor information in a database record. Currently, the two "Actor" types we store records for are FederatedUser and FederationHost, which are both internal Actor types (not defined in a fediverse specification). Whether it is an internal Actor representation, or we create records for actually specified Actors, we should store some form of the Actor record in the database. This allows us to reference that other table in the database from the public key table, which your suggestion would break. I think breaking that relation is a bad idea, would require a **lot** of refactor work, and does not give us any meaningful gains for all of that effort. In fact, I think this change would be a regression. > * We should cache the Application Type? This would add complexity & demand for storarge without other benefit than just fulfilling the rule that relation to actor is mandantory. We can either store the Application Actor, or convert the Application Actor into a FederationHost. Maybe that means we need to ad some fields to the FederationHost data structure, and some functions to handle the conversion. Since those would be **additive** refactors, it would be much less work, and would minimally impact storage requirements. I would prefer, going forward, that we stay as close to the data structures defined in the specifications we are implementing. Doing so makes it much easier to follow along in the code, especially for new-comers.

0xllx0 commented 2026-01-29 21:38:37 +01:00

Collaborator

Copy link

@famfo wrote in #85 (comment):

Talking about implementation details, this could be realized by a stub actor table which holds some basic information like ID, type, inbox and outbox, future migrations could move certain types into their respective tables.

I think this could be a potential middle-ground. My main concern is that the public key record has an associated record in some form of Actor table, i.e. ActorID or OwnerActorID should be NON NULL. If we were working with a single database backend, we could also strengthen the relationship with a database procedure, but that is not the world we live in.

@famfo wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10248282: > Talking about implementation details, this could be realized by a stub actor table which holds some basic information like ID, type, inbox and outbox, future migrations could move certain types into their respective tables. I think this could be a potential middle-ground. My main concern is that the public key record has an associated record in some form of Actor table, i.e. ActorID or OwnerActorID should be NON NULL. If we were working with a single database backend, we could also strengthen the relationship with a database procedure, but that is not the world we live in.

silverpill commented 2026-01-29 22:18:37 +01:00

First-time contributor

Copy link

I recommend caching all actors. "Instance actors" are not special, most often this is just an actor that signs GET requests when you don't want to make them on behalf of a regular actor (either for privacy reasons, or to avoid deadlocks). Its type is usually Application, but sometimes Service or Person.

I recommend caching all actors. "Instance actors" are not special, most often this is just an actor that signs GET requests when you don't want to make them on behalf of a regular actor (either for privacy reasons, or to avoid deadlocks). Its type is usually Application, but sometimes Service or Person.

๐Ÿ‘ 3

jerger commented 2026-01-30 09:44:42 +01:00

Author

Owner

Copy link

@famfo wrote in #85 (comment):

Talking about implementation details, this could be realized by a stub actor table which holds some basic information like ID, type, inbox and outbox, future migrations could move certain types into their respective tables.

The only reason for having such a stub is storing unknowns actors types ActorID. If we resist to have the owner property stored in PublicKey table.

@famfo wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10248282: > Talking about implementation details, this could be realized by a stub actor table which holds some basic information like ID, type, inbox and outbox, future migrations could move certain types into their respective tables. The only reason for having such a stub is storing unknowns actors types ActorID. If we resist to have the owner property stored in PublicKey table.

jerger commented 2026-02-19 12:41:47 +01:00

Author

Owner

Copy link

Follow @famfo proposal: !85 (commit 6901235e82)

Follow @famfo proposal: https://codeberg.org/forgejo-contrib/federation/pulls/85/commits/6901235e8292ed078407f1ac78af5e70d5f3d00b

0xllx0 reviewed 2026-01-28 17:49:16 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md

| | | | @ -0,0 +242,4 @@ | | | | | | #### 3.c Consequence | | | | | | | | | | | | 1. We can get rid of normalization of ActorID. Normalization of FQDN & port is well defined and will be used to calculate the FederationHost. | | | | | | 2. FederationHost represents just the distant server fqdn & port and is a trust anchor founded on trust in dns system. |

0xllx0 commented 2026-01-28 17:49:16 +01:00

Collaborator

Copy link

We should remove this "trust" relation. It doesn't exist, and DNS is a terrible thing as a foundation of trust.

We should remove this "trust" relation. It doesn't exist, and DNS is a terrible thing as a foundation of trust.

๐Ÿ‘Ž 2

jerger commented 2026-01-29 08:40:19 +01:00

Author

Owner

Copy link

It exists, as most of letsencrypt is based on dns, your http and most of https requests are based on dns (or based on a intransparent organized CDN, which makes things not better) and your email is also.

So this trust is definitely there as we've nothing better.

But I agree, its not a strong und caries many weakness inside.

It exists, as most of letsencrypt is based on dns, your http and most of https requests are based on dns (or based on a intransparent organized CDN, which makes things not better) and your email is also. So this trust is definitely there as we've nothing better. But I agree, its not a strong und caries many weakness inside.

0xllx0 commented 2026-01-29 21:05:20 +01:00

Collaborator

Copy link

@jerger wrote in #85 (comment):

It exists, as most of letsencrypt is based on dns, your http and most of https requests are based on dns (or based on a intransparent organized CDN, which makes things not better) and your email is also.

LetsEncrypt uses PKI and cryptographic certificate chains as the root of trust, not DNS. This is made especially evident in their somewhat recent support for IP address certificates.

DNS is just used for domain resolution, not as a root of trust. The main root of trust that makes HTTP signatures even half-way viable is the fact that we require TLS. Which, again, uses the existing PKI + cryptographic certificate chains provided by Certificate Authorities.

DNSSEC attempts to implement some cryptographic guarantees, but not everyone is going to be using DNSSEC.

There is even a section in the linked article stating that DNS by itself is not secure.

So this trust is definitely there as we've nothing better.

But I agree, its not a strong und caries many weakness inside.

It is not, and we discussed this at length so I don't know why you are saying the opposite now.

The only cryptographic guarantees that we have are for the Actor records, and requests/responses signed with their public keys. Even that trust relationship is on somewhat shaky ground because of the Trust on First Use (TOFU) issue. That is somewhat mitigated, again, by the fact that we only accept records over TLS (outside of testing environments).

@jerger wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10244530: > It exists, as most of letsencrypt is based on dns, your http and most of https requests are based on dns (or based on a intransparent organized CDN, which makes things not better) and your email is also. LetsEncrypt uses PKI and cryptographic certificate chains as the root of trust, not DNS. This is made especially evident in their somewhat recent support for IP address certificates. DNS is just used for domain resolution, not as a root of trust. The main root of trust that makes HTTP signatures even half-way viable is the fact that we require TLS. Which, again, uses the existing PKI + cryptographic certificate chains provided by Certificate Authorities. DNSSEC attempts to implement some cryptographic guarantees, but not everyone is going to be using DNSSEC. There is even a section in the linked article stating that DNS by itself is **not secure**. > So this trust is definitely there as we've nothing better. > > But I agree, its not a strong und caries many weakness inside. It is not, and we discussed this at length so I don't know why you are saying the opposite now. The only cryptographic guarantees that we have are for the Actor records, and requests/responses signed with their public keys. Even that trust relationship is on somewhat shaky ground because of the Trust on First Use (TOFU) issue. That is somewhat mitigated, again, by the fact that we only accept records over TLS (outside of testing environments).

jerger commented 2026-01-30 08:52:48 +01:00

Author

Owner

Copy link

And what's about the different types of challenges to prove the domain ownership?

Most are founded solely on dns in their core (yes with some additional heuristics).

And what's about the different types of challenges to prove the domain ownership? Most are founded solely on dns in their core (yes with some additional heuristics).

0xllx0 commented 2026-01-30 20:46:26 +01:00

Collaborator

Copy link

@jerger wrote in #85 (comment):

And what's about the different types of challenges to prove the domain ownership?

For LetsEncrypt, they solve it using the ACME protocol which performs a cryptographic challenge-response to gain a reasonable assurance the domain belongs to the entity requesting a certificate.

My point is that there is no cross-Actor assurance of ownership, or any kind of root-of-trust relationship. Which we discussed at length in a sync-up call. My take-away from that conversation was that we should treat each Actor independently, since we don't receive Actor information signed by another Actor.

For example, the instance-wide Actor (let's say Application Actor for this example) does not sign Person Actor records (what we call FederatedUser). If implementations used their instance-wide Application Actor key to sign all Actor information issued by that server, then that would be a different story. That situation would be much closer to a cryptographic key chain. Maybe I should make an FEP if one does not already exist.

@jerger wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10258558: > And what's about the different types of challenges to prove the domain ownership? For LetsEncrypt, they solve it using the ACME protocol which performs a cryptographic challenge-response to gain a reasonable assurance the domain belongs to the entity requesting a certificate. My point is that there is no cross-Actor assurance of ownership, or any kind of root-of-trust relationship. Which we discussed at length in a sync-up call. My take-away from that conversation was that we should treat each Actor independently, since we don't receive Actor information signed by another Actor. For example, the instance-wide Actor (let's say Application Actor for this example) does not sign Person Actor records (what we call FederatedUser). If implementations used their instance-wide Application Actor key to sign all Actor information issued by that server, then that would be a different story. That situation would be much closer to a cryptographic key chain. Maybe I should make an FEP if one does not already exist.

jerger commented 2026-02-06 13:31:24 +01:00

Author

Owner

Copy link

Yes and no.

  1. Yes, as every actor stand for his own. In this sense we've no trust relationship
  2. No, as if an instance itself behaves bad (e.g. if there is no moderation and there are many bad actors threating our instance) in this case we would block the whole domain. I would call this also "trust relationship"

Bthw. I do not insist in introduce dns based trust in this context. But seeing this loose chain of

  1. actor having an ID having an dns part to
  2. FederatedHost having the same dns and a port to
  3. dns resolving this FederatedHost

seems to be a implicit chain of trust to me.

Yes and no. 1. Yes, as every actor stand for his own. In this sense we've no trust relationship 2. No, as if an instance itself behaves bad (e.g. if there is no moderation and there are many bad actors threating our instance) in this case we would block the whole domain. I would call this also "trust relationship" Bthw. I do not insist in introduce dns based trust in this context. But seeing this loose chain of 1. actor having an ID having an dns part to 2. FederatedHost having the same dns and a port to 3. dns resolving this FederatedHost seems to be a implicit chain of trust to me.

famfo commented 2026-02-06 17:21:28 +01:00

Collaborator

Copy link

Fwiw, the linked-data basis and ActivityPub itself are implicitly "one instance per domain" (most implementations don't really support other ports and protocols than https / 443). The federation hosts just associates these things with an actor.

This whole thing just boil down to wording again, here is my proposal to try to make it clearer:

diff
- 2. FederationHost represents just the distant server fqdn & port and is a trust anchor founded on trust in dns system. 
+ 2. The FederationHost represents the distant server fqdn & port every actor is associated with.

Fwiw, the linked-data basis and ActivityPub itself are implicitly "one instance per domain" (most implementations don't really support other ports and protocols than https / 443). The federation hosts just associates these things with an actor. This whole thing just boil down to wording again, here is my proposal to try to make it clearer: diff - 2. FederationHost represents just the distant server fqdn & port and is a trust anchor founded on trust in dns system. + 2. The FederationHost represents the distant server fqdn & port every actor is associated with.

๐Ÿ‘ 2

silverpill commented 2026-02-07 19:04:12 +01:00

First-time contributor

Copy link

There is a similar concept, "web origin", which consists of scheme, fqdn and port. ActivityPub spec uses this term several times, for example in 7.1 Delivery:

Note: Activities being distributed between actors on the same origin may use any internal mechanism, and are not required to use HTTP.

It is not clear whether this "origin" and RFC-6454 origin are the same thing, but I think origin is better than host+port because the scheme might be important in some cases.

I also think that the root of trust is origin, not actor, because everything we know about an actor comes from a document served at its origin, and whoever controls the server controls the actor too (I develop this idea further in FEP-fe34: Origin-based security model).

There is a similar concept, "web origin", which consists of scheme, fqdn and port. ActivityPub spec uses this term several times, for example in 7.1 Delivery: > Note: Activities being distributed between actors on the same origin may use any internal mechanism, and are not required to use HTTP. It is not clear whether this "origin" and RFC-6454 origin are the same thing, but I think origin is better than host+port because the scheme might be important in some cases. I also think that the root of trust is origin, not actor, because everything we know about an actor comes from a document served at its origin, and whoever controls the server controls the actor too (I develop this idea further in FEP-fe34: Origin-based security model).

๐Ÿ‘ 1 ๐Ÿ‘€ 1

jerger commented 2026-02-19 12:42:45 +01:00

Author

Owner

Copy link

Follow proposal from @famfo: !85 (commit 6901235e82)

Follow proposal from @famfo: https://codeberg.org/forgejo-contrib/federation/pulls/85/commits/6901235e8292ed078407f1ac78af5e70d5f3d00b

0xllx0 reviewed 2026-01-28 17:51:33 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show resolved Hide resolved

| | | | @ -0,0 +243,4 @@ | | | | | | | | | | | | 1. We can get rid of normalization of ActorID. Normalization of FQDN & port is well defined and will be used to calculate the FederationHost. | | | | | | 2. FederationHost represents just the distant server fqdn & port and is a trust anchor founded on trust in dns system. | | | | | | 3. FederationHost is not connected to the InstanceActor as instanceActor is not defined to represent the distant server, it is not discoverable reliably and there is not trust relationship specified in the AP spec. |

0xllx0 commented 2026-01-28 17:51:33 +01:00

Collaborator

Copy link

Mastodon returns an "Application" Actor, which is defined to represent the distant server. We have also copied this in Forgejo with the /api/v1/activitypub/actor endpoint.

Is there a reason to choose the "Instance" Actor?

Mastodon returns an "Application" Actor, which is defined to represent the distant server. We have also copied this in Forgejo with the /api/v1/activitypub/actor endpoint. Is there a reason to choose the "Instance" Actor?

jerger commented 2026-01-29 08:51:23 +01:00

Author

Owner

Copy link

The name is explained here: https://seb.jambor.dev/posts/understanding-activitypub-part-4-threads/

It is also mentioned in Specs. Do you mean I should search for a reference to justify the name?

The name is explained here: https://seb.jambor.dev/posts/understanding-activitypub-part-4-threads/ It is also mentioned in Specs. Do you mean I should search for a reference to justify the name?

0xllx0 commented 2026-01-29 21:09:50 +01:00

Collaborator

Copy link

Oh no. No no no. If this is coming from some bullshit that threads-dot-net is doing, count me all the way out.

Meta is in the middle of the Embrace, Extend, Extinguish process.

Please keep anything related to their products as far from our implementation as possible. That trash should be nuked from orbit.

Oh no. No no no. If this is coming from some bullshit that threads-dot-net is doing, count me all the way out. Meta is in the middle of the Embrace, Extend, Extinguish process. Please keep anything related to their products as far from our implementation as possible. That trash should be nuked from orbit.

famfo commented 2026-01-29 22:41:00 +01:00

Collaborator

Copy link

The concept of an "Instance Actor" has nothing to do with Threads, it's a consequence of how request verification is done. Further, there is no "Instance" actor type defined, see https://www.w3.org/TR/activitystreams-vocabulary/#actor-types for all types.

The concept of an "Instance Actor" has nothing to do with Threads, it's a consequence of how request verification is done. Further, there is no "Instance" actor type defined, see <https://www.w3.org/TR/activitystreams-vocabulary/#actor-types\> for all types.

๐Ÿ‘ 2

0xllx0 commented 2026-01-30 20:50:16 +01:00

Collaborator

Copy link

@famfo wrote in #85 (comment):

The concept of an "Instance Actor" has nothing to do with Threads

Alright, I just saw it mentioned within the first two paragraphs, and noped out of reading anything further in that article.

Regarding the "Instance Actor", can we find some other way to refer to it? Any time I see "* Actor" I assume we are talking about an actually specified Actor type, not a meta-type used to describe the functionality of a subset of Actor types.

@famfo wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10254028: > The concept of an "Instance Actor" has nothing to do with Threads Alright, I just saw it mentioned within the first two paragraphs, and noped out of reading anything further in that article. Regarding the "Instance Actor", can we find some other way to refer to it? Any time I see "* Actor" I assume we are talking about an actually specified Actor type, not a meta-type used to describe the functionality of a subset of Actor types.

jerger marked this conversation as resolved

0xllx0 reviewed 2026-01-28 17:52:52 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show resolved Hide resolved

| | | | @ -0,0 +244,4 @@ | | | | | | 1. We can get rid of normalization of ActorID. Normalization of FQDN & port is well defined and will be used to calculate the FederationHost. | | | | | | 2. FederationHost represents just the distant server fqdn & port and is a trust anchor founded on trust in dns system. | | | | | | 3. FederationHost is not connected to the InstanceActor as instanceActor is not defined to represent the distant server, it is not discoverable reliably and there is not trust relationship specified in the AP spec. | | | | | | 4. The InstanceActor key will be put into the public key table, even if the actor type is not available in Forgejo. That is true especial for InstanceActors of Application type. These InstanceActors will be represented only by their PublicKey entry in Forgejo. |

0xllx0 commented 2026-01-28 17:52:52 +01:00

Collaborator

Copy link

Again, whichever Actor type we choose, we should add support for it in Forgejo, and tie the public key record to the Actor record in the database.

I'm not a fan of this floating public key record idea.

Again, whichever Actor type we choose, we should add support for it in Forgejo, and tie the public key record to the Actor record in the database. I'm not a fan of this floating public key record idea.

jerger commented 2026-01-29 08:52:23 +01:00

Author

Owner

Copy link

Again, there is no defined AP type for InstanceActors nor there is a well-known path defined.

Again, there is no defined AP type for InstanceActors nor there is a well-known path defined.

0xllx0 commented 2026-01-29 21:14:10 +01:00

Collaborator

Copy link

Which, again, leads to the question of: why are you stuck on supporting Instance Actors?

If it is not specified in ActivityPub, ForgeFed, nor is it widely implemented in fediverse software, what purpose does it serve?

If, instead, we are talking about an instance-wide Actor that is associate with the server itself, then there are a number of actually specified Actor types (Application, Service, etc). Also, one of the main implementations that we support uses the Application Actor, as do we.

Which, again, leads to the question of: why are you stuck on supporting **Instance Actors**? If it is not specified in ActivityPub, ForgeFed, nor is it widely implemented in fediverse software, what purpose does it serve? If, instead, we are talking about an instance-wide Actor that is associate with the server itself, then there are a number of actually specified Actor types (Application, Service, etc). Also, one of the main implementations that we support uses the Application Actor, as do we.

jerger commented 2026-01-30 08:26:02 +01:00

Author

Owner

Copy link

Show me the signed request implementation working without InstanceActor and you will win the price.

Till showing this prove I would consider your argument to be just wrong.

Show me the signed request implementation working without InstanceActor and you will win the price. Till showing this prove I would consider your argument to be just wrong.

0xllx0 commented 2026-01-30 21:03:05 +01:00

Collaborator

Copy link

@jerger wrote in #85 (comment):

Show me the signed request implementation working without InstanceActor and you will win the price.

Till showing this prove I would consider your argument to be just wrong.

The Application Actor signs the request, or some other concrete Actor type. If we are using "Instance Actor" to refer to whatever concrete type (Application, Service, Person, etc.), then I agree that there needs to be an instance-wide Actor type to sign requests that aren't otherwise associated with another Actor.

In our implementation, this "Instance Actor" is already represented by the "FederationHost" for distant Actors, and the Application Actor for our /api/v1/activitypub/actor endpoint.

@jerger wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10258346: > Show me the signed request implementation working without InstanceActor and you will win the price. > > Till showing this prove I would consider your argument to be just wrong. The Application Actor signs the request, or some other concrete Actor type. If we are using "Instance Actor" to refer to whatever concrete type (Application, Service, Person, etc.), then I agree that there needs to be an instance-wide Actor type to sign requests that aren't otherwise associated with another Actor. In our implementation, this "Instance Actor" is already represented by the "FederationHost" for distant Actors, and the Application Actor for our /api/v1/activitypub/actor endpoint.

jerger commented 2026-02-06 13:56:43 +01:00

Author

Owner

Copy link

This relation between FederationHost and InstanceActor key is wrong implemented.

As our discussion clarified, there is no spec covering this releation. As a consequence we have to move the keymaterial away from FederationHost.

This relation between FederationHost and InstanceActor key is wrong implemented. As our discussion clarified, there is no spec covering this releation. As a consequence we have to move the keymaterial away from FederationHost.

๐Ÿ‘ 1

0xllx0 commented 2026-02-18 22:52:54 +01:00

Collaborator

Copy link

That's fine with me, I think staying as close to the concrete names in the ActivityPub spec, and the Actor type returned by the remote host is probably the best approach long-term.

I think this would mean creating records for the "Application" Actor type, and whatever GoToSocial is using (if they use something else).

That's fine with me, I think staying as close to the concrete names in the ActivityPub spec, and the Actor type returned by the remote host is probably the best approach long-term. I think this would mean creating records for the "Application" Actor type, and whatever GoToSocial is using (if they use something else).

jerger marked this conversation as resolved

0xllx0 reviewed 2026-01-28 17:53:09 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show resolved Hide resolved

| | | | @ -0,0 +245,4 @@ | | | | | | 2. FederationHost represents just the distant server fqdn & port and is a trust anchor founded on trust in dns system. | | | | | | 3. FederationHost is not connected to the InstanceActor as instanceActor is not defined to represent the distant server, it is not discoverable reliably and there is not trust relationship specified in the AP spec. | | | | | | 4. The InstanceActor key will be put into the public key table, even if the actor type is not available in Forgejo. That is true especial for InstanceActors of Application type. These InstanceActors will be represented only by their PublicKey entry in Forgejo. | | | | | | 5. We can get rid of complicated ActorID, PersonId, RepositoryID parsing & validation. |

0xllx0 commented 2026-01-28 17:53:09 +01:00

Collaborator

Copy link

No, we don't.

No, we don't.

jerger marked this conversation as resolved

0xllx0 reviewed 2026-01-28 17:54:00 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show outdated Hide outdated

| | | | @ -0,0 +248,4 @@ | | | | | | 5. We can get rid of complicated ActorID, PersonId, RepositoryID parsing & validation. | | | | | | 6. We've the chance to skip need of NodeInfo parsing & dependency on well defined distant software. | | | | | | 7. We've to refactor code relaying on ActorID, PersonId, RepositoryID. | | | | | | 8. We might to refactor property names in FederationPublicKey & sharpen ActorType -> OwnerActorType. |

0xllx0 commented 2026-01-28 17:54:00 +01:00

Collaborator

Copy link

The bikeshed should be blue.

The bikeshed should be blue.

jerger commented 2026-01-30 12:51:42 +01:00

Author

Owner

Copy link

Do not insist on.

Do not insist on.

๐Ÿ‘Ž 1

0xllx0 requested changes 2026-01-28 17:56:27 +01:00

0xllx0 left a comment

Copy link

I'm requesting a number of changes to Proposal 3. I think relaxing the public key relations, and storing key info for unsupported Actor types is the wrong direction.

Removing parsing and validation is opening up a new security vulnerability, and I am very unhappily surprised to see it included in these proposed changes.

I'm requesting a number of changes to Proposal 3. I think relaxing the public key relations, and storing key info for unsupported Actor types is the wrong direction. Removing parsing and validation is opening up a new security vulnerability, and I am very unhappily surprised to see it included in these proposed changes.

0xllx0 reviewed 2026-01-29 21:22:41 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md

Show resolved Hide resolved

| | | | @ -0,0 +224,4 @@ | | | | | | ActorID string | | | | | | FederationHostID int64 | | | | | | KeyID sql.NullString | | | | | | PublicKey sql.Null[sql.RawBytes] |

0xllx0 commented 2026-01-29 21:22:41 +01:00

Collaborator

Copy link

The KeyID and PublicKey fields no longer exist in the FederatedUser models after separating the public key table, same as FederationHost.

The KeyID and PublicKey fields no longer exist in the FederatedUser models after separating the public key table, same as FederationHost.

๐Ÿ‘ 1

jerger commented 2026-02-06 13:58:00 +01:00

Author

Owner

Copy link

Can u fix this in architecture?

My diagram is just a copy & I do not want to mix this pr with not related changes.

Can u fix this in architecture? My diagram is just a copy & I do not want to mix this pr with not related changes.

0xllx0 commented 2026-02-17 02:54:34 +01:00

Collaborator

Copy link

It was updated in #73

It was updated in #73

jerger marked this conversation as resolved

0xllx0 reviewed 2026-01-29 21:28:55 +01:00

architecture/adr/adr-soften-relation-to-federation-host.md Outdated

Show outdated Hide outdated

| | | | @ -0,0 +249,4 @@ | | | | | | 6. We've the chance to skip need of NodeInfo parsing & dependency on well defined distant software. | | | | | | 7. We've to refactor code relaying on ActorID, PersonId, RepositoryID. | | | | | | 8. We might to refactor property names in FederationPublicKey & sharpen ActorType -> OwnerActorType. | | | | | | 9. We use the ActivityPub Type as OwnerActorType in the PublicKey table. |

0xllx0 commented 2026-01-29 21:28:55 +01:00

Collaborator

Copy link

Which would require a mapping between ActivityPub Actor types, and database tables for our internal representation of those Actors.

That would complicate things slightly, since the current field stores the table name directly. Do you have some reason you would like to store the ActivityPub Actor type here, instead of in the table records this field points to?

Which would require a mapping between ActivityPub Actor types, and database tables for our internal representation of those Actors. That would complicate things slightly, since the current field stores the table name directly. Do you have some reason you would like to store the ActivityPub Actor type here, instead of in the table records this field points to?

jerger commented 2026-01-30 08:49:33 +01:00

Author

Owner

Copy link

My reason are:

  1. Actor type is well defined.
  2. We are not limited to the tables, we implement for Actors in forgejo
  3. Change is not really hard, as there is already a mapping forgejo/forgejo#10074/files , changing this mapping should not be hard.

My reason are: 1. Actor type is well defined. 2. We are not limited to the tables, we implement for Actors in forgejo 3. Change is not really hard, as there is already a mapping https://codeberg.org/forgejo/forgejo/pulls/10074/files#diff-45154c15cec913ebe52258a1ff5e9d88f29cc262 , changing this mapping should not be hard.

0xllx0 commented 2026-01-30 21:15:32 +01:00

Collaborator

Copy link

I'm just tired of jumping back and forth across different repos, getting conflicting refactor suggestions, or getting refactor suggestions to only have them later changed to undo the requested refactor. This is tiring.

If you have implementation changes you would like made in #10074, then please leave a review comment there.

Change is not really hard, as there is already a mapping forgejo/forgejo#10074/files , changing this mapping should not be hard.

I'm not saying the change would be difficult, I already said that we could add a function to map between the local federation_key.ActorType, and the main ActivityPub Actor type.

My question was what functional purpose does that serve? With these refactor suggestions you're making FederationPublicKey is quickly turning into a generic Actor table, which undermines the whole purpose of separating out the table in the first place. In my opinion, the ActivityPub Actor type is better suited for the respective Actor table, e.g. FederationHost should have the ActorType field.

I also offered the alternative of switching the ActorType field to be the ActivityPub Actor type (as you are suggesting), and adding another field with the table name. It's an implementation detail, but it has architectural significance. Having the table name stored in the record allows us to do a reverse lookup of the owning entity.

I'm just tired of jumping back and forth across different repos, getting conflicting refactor suggestions, or getting refactor suggestions to only have them later changed to undo the requested refactor. This is tiring. If you have implementation changes you would like made in #10074, then please leave a review comment there. > Change is not really hard, as there is already a mapping forgejo/forgejo#10074/files , changing this mapping should not be hard. I'm not saying the change would be difficult, I already said that we could add a function to map between the local federation_key.ActorType, and the main ActivityPub Actor type. My question was what functional purpose does that serve? With these refactor suggestions you're making FederationPublicKey is quickly turning into a generic Actor table, which undermines the whole purpose of separating out the table in the first place. In my opinion, the ActivityPub Actor type is better suited for the respective Actor table, e.g. FederationHost should have the ActorType field. I also offered the alternative of switching the ActorType field to be the ActivityPub Actor type (as you are suggesting), and adding another field with the table name. It's an implementation detail, but it has architectural significance. Having the table name stored in the record allows us to do a reverse lookup of the owning entity.

jerger commented 2026-02-06 13:59:42 +01:00

Author

Owner

Copy link

agree, will rephrase and leave this detail for the implementation.

agree, will rephrase and leave this detail for the implementation.

jerger commented 2026-02-19 12:43:35 +01:00

Author

Owner

Copy link

see: !85 (commit 6901235e82)

see: https://codeberg.org/forgejo-contrib/federation/pulls/85/commits/6901235e8292ed078407f1ac78af5e70d5f3d00b

jerger commented 2026-01-30 08:31:19 +01:00

Author

Owner

Copy link

@0xllx0 wrote in #85 (comment):

I'm requesting a number of changes to Proposal 3. I think relaxing the public key relations, and storing key info for unsupported Actor types is the wrong direction.

What is the argument ?

Removing parsing and validation is opening up a new security vulnerability, and I am very unhappily surprised to see it included in these proposed changes.

My intent is not to introduce additional threat surface but to get rid of complicated heuristic caused pre signature mitigations.
I resist to discuss this details on architecture level, as there is much room to discuss only hot air. We can solve this question on implementation. I will proceed, you can in the implementation PR.

@0xllx0 wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10235650: > I'm requesting a number of changes to Proposal 3. I think relaxing the public key relations, and storing key info for unsupported Actor types is the wrong direction. What is the argument ? > Removing parsing and validation is opening up a new security vulnerability, and I am very unhappily surprised to see it included in these proposed changes. My intent is not to introduce additional threat surface but to get rid of complicated heuristic caused pre signature mitigations. I resist to discuss this details on architecture level, as there is much room to discuss only hot air. We can solve this question on implementation. I will proceed, you can in the implementation PR.

0xllx0 commented 2026-01-30 21:18:33 +01:00

Collaborator

Copy link

@jerger wrote in #85 (comment):

What is the argument ?

I've made my arguments above, I'm not going to repeat them for you here.

My intent is not to introduce additional threat surface but to get rid of complicated heuristic caused pre signature mitigations.
I resist to discuss this details on architecture level, as there is much room to discuss only hot air.

Nice, so shut down the conversation, and insult me by saying that the change requests I've suggested are "hot air".

@jerger wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10258388: > What is the argument ? I've made my arguments above, I'm not going to repeat them for you here. > My intent is not to introduce additional threat surface but to get rid of complicated heuristic caused pre signature mitigations. > I resist to discuss this details on architecture level, as there is much room to discuss only hot air. Nice, so shut down the conversation, and insult me by saying that the change requests I've suggested are "hot air".

jerger commented 2026-02-06 15:27:30 +01:00

Author

Owner

Copy link

At least I bet, our discussion is much more on point while looking on implementation.

There are obvious benefits in cleaning up the validation.

At least I bet, our discussion is much more on point while looking on implementation. There are obvious benefits in cleaning up the validation.

0xllx0 commented 2026-02-17 02:49:29 +01:00

Collaborator

Copy link

My concerns are over considering "FederationHost" as a root-of-trust.

It is not a cryptographic root-of-trust, and there is no cross-Actor signing of Actor or key information.

So, the only "ownership" relations that make sense are:

  1. instance-wide actor "owns" all Actors issued by that instance
  • following the ownership security model in fep-fe34
  • requires integrity proofs as described in fep-8b32
  • lacking either of those, falling back to the TLS + DNS trust model
    • requires only accepting TLS transport schemes, or transports with similar cryptographic properties
  1. Actors own their key information supplied in their Actor ActivityPub record.
  • an Actor also owns any other Object which it creates an integrity proof for, described by fep-fe34 & fep-8b32
    • fep-8b32 is not implemented in Forgejo (we can, though)
    • nor in any of the supported platforms (Mastodon + GoToSocial).

Given that lack of stronger cryptographic proof of ownership, we can only rely on all Actors provided by an instance belonging to that instance.

No other ownership relations can be verified across instances.

We should be using clear language, and justifications for why we are using that language / establishing those relationships.

I thought we had reached an agreed understanding about the trust-model / security-model of ActivityPub Actors, especially regarding ownership.

We have reliable ways to retrieve instance-wide Actor information from all the planned supported platforms (Forgejo, Mastodon, GoToSocial).

We could also make providing instance-wide Actor information a hard requirement for adding support for additional platforms.

For example, if a platform wants to interoperate with Forgejo via ActivityPub + ForgeFed, these are the required FEP implementations (with a list of required FEPs).

Therefore, I don't think we should relax the requirement that each Actor type we store be associated with a instance-wide Actor ("FederationHost" in our DB).

I think it is important to support as many ActivityPub platforms as possible, however I do not want to get into a situation of special-casing each additional platform. That is part of motivation for building on standards-based protocols, right? Remove as many special-cases as possible.

My concerns are over considering "FederationHost" as a root-of-trust. It is not a cryptographic root-of-trust, and there is no cross-Actor signing of Actor or key information. So, the only "ownership" relations that make sense are: 1. instance-wide actor "owns" all Actors issued by that instance - following the ownership security model in fep-fe34 - requires integrity proofs as described in fep-8b32 - lacking either of those, falling back to the TLS + DNS trust model - requires only accepting TLS transport schemes, or transports with similar cryptographic properties 2. Actors own their key information supplied in their Actor ActivityPub record. - an Actor also owns any other Object which it creates an integrity proof for, described by fep-fe34 & fep-8b32 - fep-8b32 is not implemented in Forgejo (we can, though) - nor in any of the supported platforms (Mastodon + GoToSocial). Given that lack of stronger cryptographic proof of ownership, we can only rely on all Actors provided by an instance belonging to that instance. No other ownership relations can be verified across instances. We should be using clear language, and justifications for why we are using that language / establishing those relationships. I thought we had reached an agreed understanding about the trust-model / security-model of ActivityPub Actors, especially regarding ownership. We have reliable ways to retrieve instance-wide Actor information from all the planned supported platforms (Forgejo, Mastodon, GoToSocial). We could also make providing instance-wide Actor information a hard requirement for adding support for additional platforms. For example, if a platform wants to interoperate with Forgejo via ActivityPub + ForgeFed, these are the required FEP implementations (with a list of required FEPs). Therefore, I don't think we should relax the requirement that each Actor type we store be associated with a instance-wide Actor ("FederationHost" in our DB). I think it is important to support as many ActivityPub platforms as possible, however I do not want to get into a situation of special-casing each additional platform. That is part of motivation for building on standards-based protocols, right? Remove as many special-cases as possible.

famfo commented 2026-02-17 17:10:28 +01:00

Collaborator

Copy link

As I have mentioned previously, with both jerger and you have agreed on with me, the word "root-of-trust" doesn't make sense in the context of actors belonging to an instance. A better formulation would probably be something along the lines of "an actor belongs to an instance".

Ownership of for example an actor or activity by an instance can be derived from the schema, domain and port of the ID and dereferencing it to the underlying object (does the object with that ID exists on the instance?), as outlined in FEP-fe34. In a production setting it makes sense to reject all non-TLS connections, certifying ownership of a domain with TLS certificates.

Integrity proofs only really make sense when, for example, forwarding activities through a third instance, which is something that is currently well out of scope.

I think that I have already sufficiently laid out my position against having an opaque actor for every instance which implicitly owns all other actors on an instance. Even if we know all possible instance actors of the instances are federating with, we still only have the ID of an actor asserting that it belongs to a certain instance. Again, we can also dereference the ID to check if it actually exists on the original instance but this is the best check we can for this, which we also should for the record.

As I have mentioned previously, with both jerger and you have agreed on with me, the word "root-of-trust" doesn't make sense in the context of actors belonging to an instance. A better formulation would probably be something along the lines of "an actor belongs to an instance". Ownership of for example an actor or activity by an instance can be derived from the schema, domain and port of the ID and dereferencing it to the underlying object (does the object with that ID exists on the instance?), as outlined in FEP-fe34. In a production setting it makes sense to reject all non-TLS connections, certifying ownership of a domain with TLS certificates. Integrity proofs only really make sense when, for example, forwarding activities through a third instance, which is something that is currently well out of scope. I think that I have already sufficiently laid out my position against having an opaque actor for every instance which implicitly owns all other actors on an instance. Even if we know all possible instance actors of the instances are federating with, we still only have the ID of an actor asserting that it belongs to a certain instance. Again, we can also dereference the ID to check if it actually exists on the original instance but this is the best check we can for this, which we also should for the record.

๐Ÿ‘ 2

0xllx0 commented 2026-02-17 23:34:50 +01:00

Collaborator

Copy link

@famfo wrote in #85 (comment):

I think that I have already sufficiently laid out my position against having an opaque actor for every instance which implicitly owns all other actors on an instance. Even if we know all possible instance actors of the instances are federating with, we still only have the ID of an actor asserting that it belongs to a certain instance. Again, we can also dereference the ID to check if it actually exists on the original instance but this is the best check we can for this, which we also should for the record.

We're in agreement on this. The next question becomes, should we then maintain or remove the FederationHostID field from FederatedUser (and whatever other Actors we store)? My take-away from this conversation is that we should remove it, since we should only be tracking FederationHost and its related key material for requests signed by the instance-wide Actor.

And yes, we absolutely agree that we only accept TLS connections in production. Non-TLS connections should be strictly reserved for test and dev environments.

@famfo wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10668446: > I think that I have already sufficiently laid out my position against having an opaque actor for every instance which implicitly owns all other actors on an instance. Even if we know all possible instance actors of the instances are federating with, we still only have the ID of an actor asserting that it belongs to a certain instance. Again, we can also dereference the ID to check if it actually exists on the original instance but this is the best check we can for this, which we also should for the record. We're in agreement on this. The next question becomes, should we then maintain or remove the FederationHostID field from FederatedUser (and whatever other Actors we store)? My take-away from this conversation is that we should remove it, since we should only be tracking FederationHost and its related key material for requests signed by the instance-wide Actor. And yes, we absolutely agree that we only accept TLS connections in production. Non-TLS connections should be strictly reserved for test and dev environments.

famfo commented 2026-02-18 00:59:04 +01:00

Collaborator

Copy link

I am against giving special treatment to the instance actor, we do not gain any meaningful information from it and it's more of an implementation detail in my opinion anyway. We however will still need a datastructure representing an instance, both for moderation purposes (instance blocks, both from an administrator or user) and nice to have statistics for example. I don't see why the FederatedUser - Federationhost would become obsolete regardless of the decision on this. I am aware that it could easily be derived from any object we store the ActivityPub ID for, but being able to query for everything from an instance directly in the database is probably going to become useful down the line.

I am against giving special treatment to the instance actor, we do not gain any meaningful information from it and it's more of an implementation detail in my opinion anyway. We however will still need a datastructure representing an instance, both for moderation purposes (instance blocks, both from an administrator or user) and nice to have statistics for example. I don't see why the FederatedUser - Federationhost would become obsolete regardless of the decision on this. I am aware that it could easily be derived from any object we store the ActivityPub ID for, but being able to query for everything from an instance directly in the database is probably going to become useful down the line.

๐Ÿ‘ 2

0xllx0 commented 2026-02-18 22:59:18 +01:00

Collaborator

Copy link

@famfo wrote in #85 (comment):

I am against giving special treatment to the instance actor, we do not gain any meaningful information from it and it's more of an implementation detail in my opinion anyway.

Right, I don't think we should have special handling for the instance actor. I do think we should be consistent. For example, since we have a FederationHostID in the FederatedUser records, that should also carry over to all other ActivityPub + ForgeFed Actor types. If we decide to drop FederationHostID (or whatever we call the instance-wide Actor), we should drop it for the other Actors, too.

It sounds like we're converging on having an instance-wide Actor record and ID associated with all ActivityPub + ForgeFed Actor records.

@famfo wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10680143: > I am against giving special treatment to the instance actor, we do not gain any meaningful information from it and it's more of an implementation detail in my opinion anyway. Right, I don't think we should have special handling for the instance actor. I do think we should be consistent. For example, since we have a FederationHostID in the FederatedUser records, that should also carry over to all other ActivityPub + ForgeFed Actor types. If we decide to drop FederationHostID (or whatever we call the instance-wide Actor), we should drop it for the other Actors, too. It sounds like we're converging on having an instance-wide Actor record and ID associated with all ActivityPub + ForgeFed Actor records.

famfo commented 2026-02-18 23:30:04 +01:00

Collaborator

Copy link

I do think we should be consistent. For example, since we have a FederationHostID in the FederatedUser records, that should also carry over to all other ActivityPub + ForgeFed Actor types.

I fully agree on that, we should probably introduce an user type for all not-yet handled but know Actor types, which we will need for the validation when actually implementing this.

If we decide to drop FederationHostID (or whatever we call the instance-wide Actor), we should drop it for the other Actors, too.

A federation host doesn't represent the instance wide actor right now but rather both the instance AND the instance wide actor. This is exactly what this ADR is about. I think that all objects should be associated with the instance they belong to (which would be the FederationHostID in this case).

I am not sure if we are converging on a position or slightly talk past each other though.

> I do think we should be consistent. For example, since we have a FederationHostID in the FederatedUser records, that should also carry over to all other ActivityPub + ForgeFed Actor types. I fully agree on that, we should probably introduce an user type for all not-yet handled but know Actor types, which we will need for the validation when actually implementing this. > If we decide to drop FederationHostID (or whatever we call the instance-wide Actor), we should drop it for the other Actors, too. A federation host doesn't represent the instance wide actor right now but rather both the instance AND the instance wide actor. This is exactly what this ADR is about. I think that all objects should be associated with the instance they belong to (which would be the FederationHostID in this case). I am not sure if we are converging on a position or slightly talk past each other though.

0xllx0 commented 2026-02-19 11:46:58 +01:00

Collaborator

Copy link

@famfo wrote in #85 (comment):

A federation host doesn't represent the instance wide actor right now but rather both the instance AND the instance wide actor.

Can you explain what you mean by this?

This is exactly what this ADR is about.

I think it would be better to have the rewrite of this ADR with just the proposed change.

The proposed changes are also opposite to what we're talking about.

text
The PublicKey will be allowed to carry the InstanceActor key without realized relation to the actor related, if the actor type is not available in Forgejo.

This is saying that the FederationPublicKey record for instance-wide Actors will not have an associated Actor entry. This is what I have an issue with, and it sounds like we agree. Whether we receive an Application, Person, or Service Actor, we should store some basic record for that Actor if it is signing ActivityPub requests.

I don't really see the point of having a separate record type that "represents the instance" apart from the Application Actor we receive from remote instances, or whatever instance-wide Actor. Even if we just store a reduced set of fields from that Actor, e.g. maybe just the ActorID, inbox, and outbox.

For the purposes of ActivityPub interoperability, I think storing the ActivityPub Actor records is more important than keeping around the "FederationHost that represents the instance, but is separable from the PublicKey for some reason". For moderation purposes, net lookups, instance-wide blocking, we can just use the ActivityPub Actor record.

What is the purpose of the FederationHost?

@famfo wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10728092: > A federation host doesn't represent the instance wide actor right now but rather both the instance AND the instance wide actor. Can you explain what you mean by this? > This is exactly what this ADR is about. I think it would be better to have the rewrite of this ADR with just the proposed change. The proposed changes are also opposite to what we're talking about. The PublicKey will be allowed to carry the InstanceActor key without realized relation to the actor related, if the actor type is not available in Forgejo. This is saying that the FederationPublicKey record for instance-wide Actors will not have an associated Actor entry. This is what I have an issue with, and it sounds like we agree. Whether we receive an Application, Person, or Service Actor, we should store some basic record for that Actor if it is signing ActivityPub requests. I don't really see the point of having a separate record type that "represents the instance" apart from the Application Actor we receive from remote instances, or whatever instance-wide Actor. Even if we just store a reduced set of fields from that Actor, e.g. maybe just the ActorID, inbox, and outbox. For the purposes of ActivityPub interoperability, I think storing the ActivityPub Actor records is more important than keeping around the "FederationHost that represents the instance, but is separable from the PublicKey for some reason". For moderation purposes, net lookups, instance-wide blocking, we can just use the ActivityPub Actor record. What is the purpose of the FederationHost?

jerger added 1 commit 2026-02-19 12:38:45 +01:00

updates according proposals found in discussion

All checks were successful

/ check-reuse (pull_request_target) Successful in 17s

Details

6901235e82

jerger added 1 commit 2026-02-19 12:47:21 +01:00

adjust class diagram

All checks were successful

/ check-reuse (pull_request_target) Successful in 16s

Details

d21a96b4c6

famfo commented 2026-02-21 23:12:20 +01:00

Collaborator

Copy link

The federation host is an abstract object which holds information about a remote instance.

Since this is once again going in circles, actionable thing (ping @jerger):

The federation host is an abstract object which holds information about a remote instance. Since this is once again going in circles, actionable thing (ping @jerger): - Add a table which holds all actors types without specialized handling as stub actors (with id, type, inbox, outbox and preferredUsername according to https://www.w3.org/TR/activitypub/#actor-objects)

๐Ÿ‘ 2

0xllx0 commented 2026-02-22 13:07:39 +01:00

Collaborator

Copy link

@famfo wrote in #85 (comment):

I like this approach, we would probably also want to store the type field to make future migrations easier. For example, if in a future change we have special handling for Application Actors, we could migrate all records in the stub table with an Application type into the new FederationApplication (or whatever we call it) table.

@famfo wrote in https://codeberg.org/forgejo-contrib/federation/pulls/85#issuecomment-10857284: > * Add a table which holds all actors types without specialized handling as stub actors (with id, inbox, outbox and preferredUsername according to https://www.w3.org/TR/activitypub/#actor-objects) I like this approach, we would probably also want to store the type field to make future migrations easier. For example, if in a future change we have special handling for Application Actors, we could migrate all records in the stub table with an Application type into the new FederationApplication (or whatever we call it) table.

famfo commented 2026-02-22 22:45:53 +01:00

Collaborator

Copy link

Yup, forgot about about the type.

Yup, forgot about about the type.

jerger added 1 commit 2026-02-23 08:02:19 +01:00

add discussed consequence

All checks were successful

/ check-reuse (pull_request_target) Successful in 18s

Details

a162121efa

jerger merged commit 765705b1db into main 2026-06-18 17:12:12 +02:00

jerger referenced this pull request from a commit 2026-06-18 17:12:13 +02:00 feat: adr to redefine FederationHost relation (#85)

jerger deleted branch feat/adr-soften-federation-host-relation 2026-06-18 17:12:15 +02:00

Sign in to join this conversation.

Reviewers

No reviewers

famfo

0xllx0

Labels Clear labels No items

No labels

Milestone

Clear milestone

No items

No milestone

Projects

Clear projects

No items

No project

Assignees

Clear assignees

No assignees

4 participants

Notifications Subscribe

Due date

The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

2026-01-29

Dependencies

No dependencies set.

Reference

forgejo-contrib/federation!85

WritePreview

Loadingโ€ฆ

Add table

| Rows | | | Columns | |

CancelOK

Add a link

Url Description Hint: With a URL in your clipboard, you can paste directly into the editor to create a link.

CancelOK

CancelSave

Reference in a new issue

Repository

forgejo-contrib/federation

Title

Body

Create issue

No description provided.

Delete branch ":feat/adr-soften-federation-host-relation"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?

No Yes