v2.4.x -> v2.5 upgrade
- 4ME v2.5 fundamentally changes how clients are identified as it is able to provide service for multiple control rooms
- The upgrade should be a drop in replacement of v2.4 but requires extra care and attention
- 4ME v2.5 lays the ground work for improved security
- 4ME v2.4 enters maintenance mode (only bugfixes, no new features) until v2.5 is rolled out everywhere
The 2.5 release makes it possible for a single 4ME server stack to provide service for clients located in different control rooms.
As of v2.4, a 4ME server stack is only able serve a specific control room. This follows the history of the software, which was built for a specific center, then replicated elsewhere.
The 2.5 release is the first iteration of a fundamental architectural change: a 4ME server stack should be able to simultaneously serve clients from different control rooms.
Changes in client IDs
A fundamental component of 4ME is the ability to filter information based on the requesting client. For instance, a supervisor has different requirements compared to a CWP working sectors X and Y.
To achieve this, each client must uniquely identified.
In 4ME v2.4, the identity of a client was encoded through a numeric
ID. For instance, the CWP #21 in LFEE control room had the ID
21. However, the CWP #21 of the LFMM control room had the same
21 ID. The server stack was configured to run in a specific environment (e.g LFEE). The client attached its
ID to every request to the server and with those pieces, the server could uniquely identify each client.
However, this worked in a single environment. If the server was configured to run in LFEE, it could not handle requests from LFMM clients for instance. Worse, if a request came from the CWP#21(LFMM) client, the server would treat it as coming from CWP#21(LFEE), creating some sort of ID collision.
The v2.5 release introduces a new way to identify clients: a string
globalId which encodes the old ID (called
clientId) and an
environmentId. For instance, CWP#21(LFEE) now has a
With this change, the server is now able to properly differentiate clients from different environments.
Likewise, the same change took place in the client. In v2.4, the
environmentId was pulled from a static configuration file. In v2.5, this piece of information is dynamic and pulled from the authentication process, which we'll cover in the next paragraph.
As you might imagine, this change is far from trivial as IDs are everywhere in the codebase.
Authentication ground work
Authentication is the process of identifying clients reliably and securely. In 4ME, the identification part is based on the IP address of a client. Somewhere in 4ME, we have a table associating ip addresses with client identities (client at IP
a.b.c.d is client
When a client knows its identity, it then forwards this identity to the main 4ME API (the GraphQL component) and the API server just trusts the client.
This provides a seamless user experience. When the client starts, it's automatically identified as the right client and the app is usable without any user interaction. This allows for the client side application to be restarted on demand by users in case a bug happens.
However, this method has a few drawbacks:
First, it creates a dependency between the network configuration and the 4ME stack. In 4ME v2.4, there was no way to add a new 4ME client in a control room without changing the 4ME configuration accordingly.
It's also extremely insecure as anything on the network can claim a specific 4ME identity.
Our main challenge is to implement a secure way of authenticating clients without introducing a complex authentication procedure.
In 4ME v2.5, we've started to implement the ground work of such a system. The authentication is still mostly IP based but we've separated the identification step from the authentication step.
When 4ME v2.5 starts, the application tries to find a hint about its identity. Then, the application tries to authenticate against the authentication server using this hint. In the future, the authentication-server will respond with a secure short lived token (called
access token) which will be attached to every request to the GraphQL server. This client/server authentication method is well known in the software development world and is out of scope of this documentation for now, since this part is not yet implemented in 4ME v2.5.
What's implemented in 4ME v2.5 is the authentication hint selection. In this new version, when the application starts, the following screen is shown to users.
The user is presented with a preview of the identity that the app will use and authenticate with. After a set amount of time without user interaction, or a click on the green button, the app proceeds with the login.
Hints come from 4 different sources, and, if the selected one is wrong for some reason, the user has the option to select a different hint source.
Authentication hints can come from 4 different sources, by order of precedence :
Remote serverwhich consists in the 4ME v2.4 method of IP <-> client association
Static configurationwhich lies in the frontend
Saved datawhich is saved in the browser local storage after each successful authentication attempt (i.e, this is the last identity)
Manual selectionwhich allows the user to pick an identity. This manual selection option can be disabled and controlled though the configuration of the authentication server.
4ME v2.4 was pretty lax about client identities. Anonymous clients were supported, and the server, configured to run for a specific control room, assumed the anonymous client was in the same control room.
As of v2.5, the server does not assume a specific control room and this behavior required a bit of work.
In v2.5, we introduced a special identity for anonymous users. This identity works like the other real identities and can be selected when a particular identity does not exist in an environment, allowing limited read-only functionality in the application.
This identity is selectable through manual selection or IP address association via authentication server configuration.
Upgrade process and backwards compatibility
As stated before, this release introduces fundamental changes about the client identities. Therefore, mixed compatibility between v2.4.x clients and v2.5 server (or vice versa) is NOT implemented.
However, rollback is supported as long as the whole stack is rolled back (clients and server).
In 4ME, there are multiple places where we store client identities in the database. For instance, when a client performs an XMAN action, 4ME "remembers" this action by creating an entry in a specific database table. In v2.4, those entries only contained the old
clientId. When 4ME v2.5 creates such a database entry, v2.5 also includes a
globalId property while still populating the
What happens in v2.5 when 4ME reads a database entry only containing a
clientId property ? Well, remember how v2.4 was dependant on a configuration item stating the environment the stack was running in ? In v2.5 this item is now optional and is only used for this precise case. In other words, when 4ME 2.5 reads an "old" database entry without a
globalId, 4ME will try to fill in the blank using the
FOURME_ENV environment variable.
Therefore, in v2.5, the
FOURME_ENV configuration item for the frontend app is irrelevant and is not used. On the other hand, the
FOURME_ENV configuration item for GraphQL server becomes optional, has the purpose of providing a fallback for old database records.
While v2.5 is able to provide service to multiple control rooms, it's still able to provide service to a single control room. In this case, the upgrade path forward should be a drop in replacement, like any 4ME upgrade before.
As changes are quite extensive, we consider this upgrade to be riskier than the releases before and should require appropriate planning.
Status of v2.4.x
As of 2021-02-02, the v2.4.x enters maintenance mode. No new features will be added, and the version will only be maintained until all sites migrate to v2.5.