Federation: one portal, many back offices
Some MDAs want their own back office: their own staff application, their own API and their own database, perhaps in their own data centre. Citizens, however, should see one government portal. Federation gives both. This lesson explains the three platform roles, what travels between them and the rule that data stays with its owner.
Hub, node and combined
The same code runs in one of three roles, chosen by the setting PLATFORM_ROLE:
| Role | What it is | How many |
|---|---|---|
hub | The national public portal. Serves every e-service of every MDA and must scale horizontally | Exactly one |
node | One MDA's own back office, API and database | One per MDA that runs its own |
combined | Hub and node in one installation | The default; how every installation runs today |
A combined installation is not a shortcut. Federation calls in combined mode go through the same signing, checking and auditing code, handed over in-process instead of over the network. That is why a feature that works in combined mode can be tested to work as hub and node too.
Who owns what
Services are owned and designed on the MDA's own back office. Forms, processes, fees, documents and templates are managed there. The hub receives the catalogue by federation sync and relays applications, status, payments and document verification to the owning node. The hub never becomes the place where a node's service is designed.
Data stays with its owner. The hub keeps only the index data it needs:
| On the hub | On the node |
|---|---|
| Citizen accounts and sign-in | Application answers |
| The catalogue copy | Officer notes and decisions |
| Application numbers and status words | Uploaded documents (after the hand-over) |
| Amounts due | Invoices, receipts and the ZamPay merchant keys |
| Document labels | Issued documents |
Files a citizen uploads on the hub are staged there only until the node acknowledges them, and then deleted.
How hub and node trust each other
- Each installation has a permanent name (
NODE_KEY) and its own signing key, published at/.well-known/jwks.json. - The hub keeps a registry of nodes. Adding or changing a node needs a second administrator (maker-checker), and
suspending a node takes effect at once.
- Every message is signed (ES256), addressed to one receiver, valid for a few minutes and usable once. A replayed
message is refused.
- Answers are signed too, so a forged answer is refused.
- The connection uses mutual TLS with certificates from the federation certificate authority.
The messages form a versioned contract, /fed/v1, described by an OpenAPI file and JSON Schemas. Changing a message is a contract change: it must stay backward compatible (or hub and nodes ship together) and it must be tested with two real instances.
What travels
| Journey | Message (examples) | Direction |
|---|---|---|
| Catalogue | Signed service manifests | Node to hub |
| Applying | submissions.create, with a citizen assertion | Hub to node |
| Status | case.submitted, case.status_changed, action.required | Node to hub |
| Payments | payment.invoiced, payment.settled, payment.refunded | Node to hub |
| Verification | verify.document, verify.lookup | Hub to node |
| Registers | registers.list, registers.lookup (under an agreement) | Between installations |
The citizen assertion
When the hub relays an application, it sends a signed citizen assertion: who the citizen is (a pairwise subject, not a shared identifier), how strongly their identity was proved, and whether their NRC was verified. The node trusts only what the assertion says was verified. A service that needs a verified identity refuses an application whose assertion says the NRC was not verified.
A worked example
A fictional MDA runs its own node, example-mda. A citizen applies for its "Example Water Permit" on the national portal.
- The service appears on the portal because
example-mdapublished its signed manifest; the hub synced it. - The citizen fills the form on the hub. Their two documents are staged on the hub after the usual upload checks.
- On submit, the hub relays the application to
example-mdawith a citizen assertion. - The node verifies the assertion, fetches the staged files through short-lived signed links, creates the case and
answers with its case number. The hub deletes the staged files.
- Officers of
example-mdaprocess the case in their own back office. Each status change is sent to the hub, so thecitizen sees it in "My applications".
- The node raises an invoice on its own ZamPay merchant. The citizen pays through a short-lived checkout link that
leads to the node's ZamPay checkout. The node finalises the payment and tells the hub.
- The node issues the sealed permit. When someone verifies it on the portal, the hub asks the node.
If example-mda is unreachable when the citizen submits, the hub queues the application and retries. After 7 days in the queue it expires, the staged files are deleted and the citizen is told.
Ask the federation question
For every change to the platform, ask: "Does this work when the service lives on another node?" Check each of:
- applying;
- paying;
- notifications;
- documents;
- verification.
A feature that only works in one installation is not finished.
Check your understanding
- What are the three values of
PLATFORM_ROLE, and which is the default? - Where are a federated service's form and process designed?
- Which data does the hub keep about an application on a node?
- What happens to files staged on the hub once the node acknowledges them?
- Why does a node trust the citizen assertion rather than an NRC typed into a form?
Sign in to record your progress.
Previous: Applying, paying and documents Next: Modules and reusable capabilities