A user with the correct permissions (e.g. project creator, or coordinator) needs to be able to add a cloud sync server to the project, and that setting should sync with other members of the project, so that all project members have the option to sync with the cloud sync server when online.
Option A: Project settings configuration
The server URL is stored in the projectSettings record, which syncs with project members. The server public key could be optional. Adding it would allow users to avoid hijacking of DNS records to impersonate the server.
When syncing to the cloud sync server, the mapeo-core sync logic will need to ignore the capabilities check for the server, and instead assign pre-determined capabilities to the server (could be based on a setting in projectSettings).
Option B: Project member / role
A user adds a cloud server as a project member (would need both the URL and the public key to do so). More than one cloud server could be added to a project.
The server URL is stored in the role record, which also contains the public key of the server. This role record syncs with project members.
When syncing to the cloud server, no changes to the capabilities check logic is needed, because project members would treat the cloud sync server like any other peer, validating that it has a valid role to sync with the project.
Implementation vs. UX
The two approaches above use either project settings or project membership / roles. How this is exposed in the UX does not depend on the implementation, e.g. we could present adding a server URL to the user in the project settings screen of the app, but internally we could write a project member record when this is saved. Similarly we could present it as a "add cloud sync server" option in the invite screen, but internally it could be implemented as saving to project settings. If we want to support more than one cloud sync server per project, and more clearly expose to the user which cloud sync servers are part of the project, then it might make more sense to expose the cloud sync server(s) as "project members" rather than something in settings.
Comparison
Option A requires read access to the config namespace in order to sync with the cloud sync server. This means that a "blind" peer (e.g. a peer that only has encryption keys for the auth namespace) would not be able to read the cloud sync server URL.
Option A would require a few extra implementation steps to expose the cloud sync server as a project member, and expose what capabilities it has.
Option B requires the public key of the server, which would be hard to enter manually, so it would require either QR code setup, or online setup (entering the URL, then connecting to the server to get its public key). Option A could set up a server without the public key when offline. This would be a less secure option though.
Adding multiple servers and removing access to a server is more explicit with option B. It could also be done with option A, but requires jumping through a few extra hoops in the code.
Option B could allow a cloud sync server to add additional cloud sync servers (the server could be added with a role that allows it to invite with that role). This could be useful for scaling and creating additional cloud sync servers closer to the users.
Conclusion
I think it makes most sense to go with Option B, since it seems like it involves writing less custom code in the sync capabilities validation and the members API.
User Requirement
A user with the correct permissions (e.g. project creator, or coordinator) needs to be able to add a cloud sync server to the project, and that setting should sync with other members of the project, so that all project members have the option to sync with the cloud sync server when online.
Option A: Project settings configuration
The server URL is stored in the
projectSettings
record, which syncs with project members. The server public key could be optional. Adding it would allow users to avoid hijacking of DNS records to impersonate the server.When syncing to the cloud sync server, the mapeo-core sync logic will need to ignore the capabilities check for the server, and instead assign pre-determined capabilities to the server (could be based on a setting in
projectSettings
).Option B: Project member / role
A user adds a cloud server as a project member (would need both the URL and the public key to do so). More than one cloud server could be added to a project.
The server URL is stored in the
role
record, which also contains the public key of the server. This role record syncs with project members.When syncing to the cloud server, no changes to the capabilities check logic is needed, because project members would treat the cloud sync server like any other peer, validating that it has a valid role to sync with the project.
Implementation vs. UX
The two approaches above use either project settings or project membership / roles. How this is exposed in the UX does not depend on the implementation, e.g. we could present adding a server URL to the user in the project settings screen of the app, but internally we could write a project member record when this is saved. Similarly we could present it as a "add cloud sync server" option in the invite screen, but internally it could be implemented as saving to project settings. If we want to support more than one cloud sync server per project, and more clearly expose to the user which cloud sync servers are part of the project, then it might make more sense to expose the cloud sync server(s) as "project members" rather than something in settings.
Comparison
config
namespace in order to sync with the cloud sync server. This means that a "blind" peer (e.g. a peer that only has encryption keys for theauth
namespace) would not be able to read the cloud sync server URL.Conclusion
I think it makes most sense to go with Option B, since it seems like it involves writing less custom code in the sync capabilities validation and the
members
API.