Federation¶
The "F" in FedMS stands for federation. This page explains what that actually means in practice, what is shared between instances, and what is kept private.
Forward-looking documentation
Federation between FedMS instances is a defining design goal of the
framework, but the transport layer is still being finalized as of
this writing. This page describes the intended federation model;
the open issues page tracks the
specific implementation work in progress. The structural
foundations — group hierarchy, field_gitlab_id on org, the
field_sync markers on events and sessions, and the federation
hooks — are already in place.
What federation means¶
A federated FedMS deployment is one where two or more independent FedMS instances run by different organizations exchange the right slices of their data automatically.
In a simple, non-federated deployment, an organization runs one FedMS instance and manages everything from there.
In a federated deployment, each participating organization runs its own instance, and instances synchronize the data they need to share — typically because they collaborate on the same events.
Why federate¶
There are two common reasons organizations want federation:
Each organization owns its data¶
When a training company delivers a workshop for a client, both organizations want to keep their own records — the trainer for its operational and billing purposes, the client for its L&D reporting and compliance. Neither wants to depend on the other's tenant being available or reliable.
Each organization controls its own users¶
The training company does not want to manage its clients' users — and vice versa. Federation lets each side keep its own user list, with its own SSO, password policies, and audit trail, while still sharing the right slice of an event's reality.
The federation model¶
1 2 3 4 5 6 7 8 | |
Key points:
- The shared event is the same event on both instances — both sides
see the same
field_syncmarker, the same start/end window, the same session structure. - The participating orgs appear on both sides — Amplius appears as a top-level org on its own instance and as a sub-org of Client X on Client X's instance.
- Users, content, and tasks are shared according to federation policy (see below).
- Each side's other orgs stay private — Amplius' other clients never appear on Client X's instance.
What is shared, what is not¶
The default federation policy (subject to refinement) is:
| Item | Shared by default? | Notes |
|---|---|---|
| Event metadata (label, date window, type) | ✅ | Always shared between participating orgs. |
| Session structure (titles, dates, agenda) | ✅ | Same. |
Editorial content (paragraphs on fedms_event / fedms_session) |
✅ | Shared where marked for sync. |
| Attached media (slides, videos, handouts) | ✅ | Where marked for sync, subject to file-size policy. |
| Memberships of the shared event/session | ✅ | But each side's user accounts stay private. |
| Tasks attached to the shared event | ✅ | Assignees resolve to each side's local user accounts. |
| Tasks attached to private events | ❌ | Stay on the originating instance only. |
| User account details (passwords, profile fields) | ❌ | Never shared. |
| Other orgs and their events | ❌ | Stay private to each instance. |
| Custom ECA models, themes, recipes | ❌ | Each instance configures independently. |
The structural foundation in code¶
Federation is already wired into the data model:
- The
orggroup bundle has afield_gitlab_idfield that links the org to its corresponding GitLab project. The GitLab API is the intended transport (other transports may be added later). - The
eventandsessiongroup bundles have afield_syncfield that marks them for synchronization with peer instances. - The
eventandsessiongroup bundles havefield_flag_start_processedandfield_flag_end_processedflags consumed by thetask_apiECA model to drive lifecycle-based behavior — these will be cron-driven via theviews.view.groups_unprocessedview. - The
group_relationshipentity has astatusbase field added byfedms_federationso memberships can be soft-removed and re-activated without losing history. - The
query_entity_reference_alterhook infedms_federationenforces that session pickers only show parent-event members — a server-side, federation-aware constraint.
How federation will work (intended)¶
The implementation work is tracked at
fedms/components/federation,
particularly:
- #22 Activity logging
- #23 Create notifications
- #29 Notification delivery
- #31 Dynamic event/session syncing
Once implemented, the rough flow will be:
- An event is created on Instance A, marked
field_sync = TRUE, and associated with Org B (the partner org). - A federation activity is logged.
- The federation pipeline contacts Instance B (the org's home instance) via the registered transport.
- Instance B receives the event, creates a corresponding event group under its own representation of Org A, and synchronizes content, memberships, and tasks according to policy.
- Subsequent changes on either side trigger delta synchronizations.
This page will be updated to describe the as-built transport once that work lands.
Open questions¶
These are flagged so future iterations on this page have a clear list of things to nail down:
- The transport (GitLab API, dedicated webhook bus, message queue) is not yet finalized.
- The conflict resolution model when both sides edit the same field is not yet defined.
- The user-identity bridging model (how a user on Instance A is recognized as the same person on Instance B) is open.
- The federation discovery model (how Instance A learns Instance
B's address from
field_gitlab_id) is open.
See Roadmap → Open issues for the live list.
Next steps¶
- Organizations — the federation unit.
- Events — what gets federated, in practice.
- Members and roles — what's shared at the membership level.