An official developer portal of the Government of the Republic of Zambia · Test environmentVerify a certificate
Pamodzi Developer HubBuild, integrate and learn the e-Services framework

Hub and nodes

The Pamodzi e-Services platform serves many ministries, departments and agencies (MDAs) through one national public portal. Behind it, each MDA may run its own back office, API and database. This shape is called the federation. In this lesson you learn the roles an installation can take, who owns what, and what data may live where.

One codebase, three roles

The same image runs in one of three roles, chosen with the environment variable PLATFORM_ROLE:

RolePurpose
combinedThe default. Hub and node in one installation: one database serving every ministry it hosts.
hubThe national portal and aggregation. It signs citizens in, hosts the forms of every service, keeps the node registry and an index of applications, and relays everything else to the owning node.
nodeOne MDA's back office and API. It owns that MDA's services, cases, payments and documents.

There is exactly one hub. It serves every e-Service of every MDA and must scale horizontally: in the per-MDA deployment the hub's portal and API run behind horizontal pod autoscalers. Each node is sized for its own MDA (small, medium or large).

Every instance has a permanent NODE_KEY. The hub's is hub; a node's is a short, lower-case MDA key agreed when the node is created. The NODE_KEY never changes, survives restores and disaster recovery, and a retired key is never reused.

Combined mode is still federated inside

In combined mode, federation calls do not disappear. Each call is signed with the instance's own key and handed to the receiving pipeline in-process by a loopback adapter. The same signature, replay, scope, idempotency, schema, handler and audit code runs as between a real hub and node, only without a network hop. This is why every feature must work in all three roles: the code paths are the same, and the contract tests run against both the loopback and two real instances.

Who owns a service

Services are owned and designed on the MDA's own back office. Forms, processes, fees, required documents and output templates are managed there. The hub receives the catalogue by federation sync and serves it on the national portal.

The hub never becomes the place where a node's service is designed. If someone tries to edit a node's service on the hub, the API answers 409 SERVICE_MANAGED_BY_NODE ("This service is managed by <node> on its own back office"). Hub administrators can read the mirrored service, read-only, under System administration → National catalogue sync.

What lives where

The rule is short: data stays with its owner. The hub keeps only the index data it needs: numbers, status words, amounts due and document labels.

DataHubNode
Citizen account, ZamPass link, contact details, preferences, consentsYesA shadow applicant: a pairwise id plus the claims released per assertion
Service catalogueSigned mirrorSource
Form answers, documents, decisions, case historyOnly while relaying; staged files deleted once the node acknowledgesYes
Invoices, receipts, issued permitsAn index for displayYes; finalised only here
Application index (number, status word, dates, amount due)YesSource
Staff accounts and the audit of case workHub staff onlyYes
Module data (registers, leases, concessions)None for a ministry with its own nodeYes

Three consequences for operators:

  • Answers, notes and documents stay on the node. When a citizen applies on the hub, the answers and files are

    staged on the hub only until the node acknowledges them; then the hub deletes the files and the answers, keeping only hashes.

  • The hub never holds a node's payment keys. Each node raises invoices on its own ZamPay merchant and receives

    ZamPay's callback on its own API.

  • No modules for node ministries on the hub. A ministry listed for an active node in the registry has no module on

    the hub at all (409 MODULE_MDA_ON_NODE); its modules run on its node.

How citizens and staff reach a node

  • Citizens always use the hub's portal. ZamPass sign-in happens only at the hub: on a node, a citizen sign-in

    is refused with 403 FED_HUB_ONLY_CITIZEN_SIGNIN, pointing to the hub's portal. The hub vouches for the citizen to a node with a short-lived, signed citizen assertion (lesson 2).

  • Node staff sign in on their node's back office with a local account and an authenticator app (MFA). Optionally,

    staff single sign-on lets a member of staff signed in on the hub open a node's back office already signed in; it is off by default and never creates an account or grants a role.

The flows in one picture

FlowDirectionContract operation
Publish a servicenode → hubcatalogue.put; the hub also pulls every 15 minutes
Applyhub → nodesubmissions.create
Status, payments, issued documentsnode → hubevents.post (CloudEvents)
Read an application, pay, downloadhub → nodecases.applicantView, payments.get, documents.link
Verify a document or receipthub → nodeverify.document, verify.receipt, verify.lookup
Citizen signed outhub → nodeevents.post with session.revoked
Ministry status cardhub → nodestatus.summary

Every one of these is a signed message on the versioned /fed/v1 contract. Lesson 2 explains how that trust works.

Check your understanding

  • What are the three values of PLATFORM_ROLE, and which one is the default?
  • Why do federation code paths still run in combined mode?
  • Where is a node's service designed, and what does the hub answer if someone edits it there?
  • Which data does the hub keep about a node's application, and which data must never stay on the hub?
  • Where do citizens sign in, and how does a node learn who the citizen is?

Sign in to record your progress.

Next: Trust: signed messages, keys and JWKS