Skip to content

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
   Amplius Partners FedMS instance              Client X FedMS instance
   ────────────────────────────────             ──────────────────────────────
   Org: Amplius (id=1)                          Org: Client X (id=1)
   ├── Org: Client X (id=42)                    ├── Org: Amplius (id=17)
   │   └── Event: Leadership Program ╶ ╶ ╶ ╶ ╶ ╶│   └── Event: Leadership Program
   │       └── Sessions, members, tasks         │       └── Sessions, members, tasks
   ├── Org: Client Y                            └── (no other orgs)
   └── …

Key points:

  • The shared event is the same event on both instances — both sides see the same field_sync marker, 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 org group bundle has a field_gitlab_id field that links the org to its corresponding GitLab project. The GitLab API is the intended transport (other transports may be added later).
  • The event and session group bundles have a field_sync field that marks them for synchronization with peer instances.
  • The event and session group bundles have field_flag_start_processed and field_flag_end_processed flags consumed by the task_api ECA model to drive lifecycle-based behavior — these will be cron-driven via the views.view.groups_unprocessed view.
  • The group_relationship entity has a status base field added by fedms_federation so memberships can be soft-removed and re-activated without losing history.
  • The query_entity_reference_alter hook in fedms_federation enforces 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:

Once implemented, the rough flow will be:

  1. An event is created on Instance A, marked field_sync = TRUE, and associated with Org B (the partner org).
  2. A federation activity is logged.
  3. The federation pipeline contacts Instance B (the org's home instance) via the registered transport.
  4. 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.
  5. 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