This post sketches a modern FHIR architecture for healthcare interoperability and identity management at scale. It consists of a SmileCDR FHIR server integrated with Keycloak Identity Provider. Both are running on a Kubernetes cluster.
Interoperability and identity management have become major topics in healthcare. While it gets more obvious that FHIR (Fast Healthcare Interoperability Resources) is set for Europe as the interoperability standard, discussions on appropriate architectures for storing and sharing healthcare-related data have just begun.
FHIR servers, if already in place, are often hosted on single machines inside the hospital. As a result, they are lacking fail safety and making updates and maintenance a nightmare. On the opposite side, the large cloud providers have already built some fully managed solutions on their own. Maintenance is quite simple for managed services but they are strongly integrated into the specific cloud architecture. Additionally, uploading the health data of European customers to cloud solutions of Chinese or US companies might introduce legal concerns. Finally, there is a lack of trust in these vendors by patients and companies in Europe, especially in Germany.
Digital identity management is often built inside proprietary systems of KIS vendors or healthcare apps. This is leading to a scattered heterogeneous landscape of digital hospital identities for the same patient. The Telematik Infrastructure (TI) tries to improve this situation but concepts like the ePA and eRezept are still lacking patient acceptance. Also, even if the TI is based on the OIDC Standard, they only intend it for internal use now.
When looking beyond the healthcare sector there are already well-established concepts for resource management and identity management. For resource management Kubernetes is often a proper choice, allowing for highly available setups with easy development workflows. When it comes to identity management, Keycloak is a widely used identity provider, also allowing for identity sharing using Social Login capabilities. So why don’t we apply those concepts to clinical workloads and healthcare apps?
Sketching an architecture
In this blog post, we will sketch an architecture with a focus on interoperable healthcare data exchange and identity management at scale. It is based on common standards and well-established development concepts. All concepts and products involved are probably worth a book on their own. For the sake of readability, we will just roughly explain their purpose in the current setup for those not familiar with them.
Our example setup consists of a SmileCDR FHIR server running on a Kubernetes cluster. The FHIR Server is integrated with a Keycloak instance, running on the same cluster, as an Identity Provider (IdP).
As a first disclaimer, other FHIR Servers would work as well. Examples would be HAPI FHIR, which is the OpenSource foundation of SmileCDR, and Firely, a commonly used .NET implementation. We were choosing SmileCDR as we have already worked with it and investigated its built-in functionality that integrates nicely with Kubernetes and Keycloak. Note that for using SmileCDR you need to pay licensing fees.
Kubernetes is an open-source container orchestration engine for automating the deployment, scaling, and management of containerized applications. It can be installed on-premise but really shines in cloud-based environments, where you can scale way easier and gain a lot of flexibility.
Kubernetes is a good choice, as it can solve the challenges of high availability and scalability easily. High availability also includes the ability to redeploy the FHIR server without any downtime using rolling updates. Kubernetes also provides strong capabilities for the safe communication of services inside and outside the Kubernetes cluster. Thereby it is a good choice if you plan to build some form of microservice architecture.
Keycloak is an open-source identity and access management solution. Besides managing the whole login workflow securely for you it enables you to share identities and thereby logins to other OIDC-compatible platforms. Combining an OIDC-compliant FHIR Server with Keycloak enables usage of the SMART-on-FHIR specification. This sets the foundation to build SMART-on-FHIR applications with fine granular user permissions down to the FHIR resource level. Thereby it allows sharing information with healthcare professionals inside the hospital as well as with other hospitals and institutions built on a similar architecture.
Why should you build something like this?
High availability and scalability
With the installation of FHIR Servers on a single machine, development and fail safety can be a pain. If you only have your FHIR server running on a single machine, this machine must be permanently available. Thinking about hardware and OS errors, or simple maintenance tasks such as version updates, it becomes obvious that this is an impractical solution. A better approach would be to run multiple instances behind an Application Load Balancer. This way, one of those instances can pass away without your users even noticing. Kubernetes provides a convenient way to manage those server instances as well as an Application Load Balancer. If one instance goes down, it will automatically ramp up a new one. If you make an update, it will make sure that the service will be available all the time.
For simple use cases, where you have a constant load on your server and do not expect any rapid changes over time, running on-premise might be a valid choice. Distributed FHIR server instances would still be a good idea here.
In case you plan to allow patients to interact with your systems, the load might change rapidly. Time-of-the-day and seasonal effects will have a stronger impact and offering new functionalities to your users can lead to a jump in performance requirements. Note, that this usually is a good thing as it implies that patients start using them. At this stage, it might be a good idea to consider cloud-native approaches, as they scale much easier.
Kubernetes is a good fit if you want to build your platform as a microservice architecture.
In this architecture, your FHIR server is acting as a central source of truth for your health data. The Keycloak IdP will handle your identities and access permissions in conjunction with the FHIR server. User-facing applications for patients, doctors, or nurses as well as backend services would be built using the SMART on FHIR Specification. SMART on FHIR makes sure that everybody is authenticated and can just access the permitted data, using an OIDC flavor tailored to the FHIR standard.
Developer wisdom: If you have one containerized distributed environment, you can easily make it two.
In modern software development, it is good practice to have multiple, more or less similar, development environments. Practices like CI/CD heavily rely on such prerequisites. They allow for easy and secure testing of changes or simple things such as version updates before they are facing any customer. In setups with a single development environment, people are often scared of applying updates and changes as they might break existing functionality. This is really a security issue as deprecated software might contain known security issues that were fixed by new versions. Especially with internet-facing FHIR servers, this becomes more important.
In general, it is good practice to design your setup in a way that you can test changes at any time without user impact. Ideally, you can even tear down everything and set it up from scratch easily. That way the fear of breaking something is strongly reduced. As a result, it speeds up the development of new features and improvements rather than getting stuck because everybody is too afraid to touch the running setup.
With a Kubernetes cluster such a deployment process is pretty convenient. Given a proper amount of computing resources, you can deploy a development and a production Kubernetes cluster easily. After testing your changes in the development cluster you can just lift and shift your adopted version to the production cluster. In the production cluster, rolling updates help you to avoid any downtime during the deployment process.
Identity management and sharing
In the past, hospital systems were often designed as closed ecosystems. Almost all data was generated inside the hospital and never left it. At least digitally. With the ePA this started to change. However, usage is not widely adopted and even the ones using it do not share data regularly. To increase adaption it might help to increase usage possibilities of the complex, but of course secure, login flow.
Using Keycloak it is pretty easy to generate login flows with a good trade-off between security and usability, based on your needs. If you have multiple Apps, you can benefit a lot from Single-Sign-On capabilities. This means that users authenticate with Keycloak rather than with the individual application. As a result, your login and also logout flows are synchronized.
Going one step further, you could also use an existing digital identity provided by another IdP to log into your system. For example, the Telematik Infrastructure could serve their trustworthy identities to other IdPs. They are creating a trustworthy digital identity anyway, so why not extend its use? Examples where you might need a login reach from hospital systems for pre- and post-operative guidance to radiological images and finding reports. Just imagine a “log in using ePA“ button on the login screens of these systems.
During development and multiple discussion rounds, we encountered several points that you should think of if you consider building a similar system.
Size of the system
The setup described in this article is designed for large-scale usage. It can be the foundation of KIS systems as well as for Healthcare Applications such as DiGAs (Digitale Gesundheitsanwendungen). However, you should not underestimate the effort and knowledge required to set up and maintain a Kubernetes cluster and a Keycloak. An alternative for Hospitals might be a cloud setup, hosted and managed by a KIS vendor. KIS vendors have the advantage that they can scale the same setup to multiple Hospitals.
Large-scale healthcare applications might want to use a similar setup anyway. Kubernetes is a good choice for their application workload anyway and Keycloak can handle their login process. Thereby it is a good match if they aim for interoperability.
Another group where such a setup might be a good fit is hospital groups. Similar to KIS providers, they can usually afford larger infrastructure teams and have a need for scalable services. Commonly they integrate their hospitals into a single system while preserving virtual borders between them. One easy way to achieve this is by using multiple tenants on the same FHIR server. This leads to a clear separation while being able to enforce data similarity through implementation guides and central identity management.
The setup does not like to be alone
The setup described already solves a lot of common problems in an encapsulated environment. However, it really shines when being integrated with other similar systems. Principles like “Social Login“ in Keycloak allows users to log in using the identity already created in another system. This could be a related healthcare app, a hospital, or in the future maybe even something like a Telematik Infrastructure identity. In addition, the Identity Provider (Keycloak) plus the FHIR server combination enable fine-grained data sharing capabilities. Finally, FHIR as an interoperability standard simplifies the sharing and integration of healthcare data into other systems.
Kubernetes is a nice framework for hosting an FHIR server and a Keycloak instance. However, if these are the only applications running on your Kubernetes cluster it might be a bit complex. Consequently, Kubernetes really starts making sense when you start developing an ecosystem of related microservices around it.
What about the existing setups?
In a developer’s dream, we design your setup on the green field. In reality, you usually have existing systems for storing your healthcare data in place. As a result, you will get two competing persistence locations, your “legacy system“ and your new FHIR Server. In our experience, it is really hard to keep them in sync for a longer period of time. This is why we would recommend getting rid of your legacy system as fast as possible. The same is true for your Identity Provider. If you have some custom identity management system you should consider migrating them to your new Identity Provider.
Migrating identities to Keycloak is probably the easier task, as this is a well-known problem with multiple pre-build solutions at hand. In the first iteration, you could stick to your existing users as they are, using the concept of User Federation. This works by attaching your new Keycloak instance to the existing setup. Existing users might be included using LDAP, an Active Directory, or a database. In general, we would recommend migrating the users into the Keycloak storage. This makes things like Single-Sign-On capabilities much easier.
Migrating healthcare data
Migrating healthcare data is more complex and heavily depends on the storage format of your legacy system. In the best case it already stores FHIR resources and migration should be fairly easy. If you are in a Hospital your legacy system probably works with HL7v2. This is not as easy as FHIR but for example, SmileCDR provides a module to semi-automatically transform HL7v2 to FHIR. Semi-automatically means that the HL7v2 messages will be automatically transformed to FHIR if they are built exactly on standard. As this is rarely the case you probably need some manual processing.
In the worst case, your legacy system has a custom format. Welcome to transformation hell. In our experience, it includes a lot of work, as all transformations need to be designed manually, which takes a lot of time and FHIR expertise. Also, you will probably end up with a lot of custom extensions, as nobody in your legacy systems thought in terms of FHIR resources when designing the data schema. When migration takes too long, your legacy system data schema might even change and you need to reiterate your mapping.
General considerations on migration
In any case, it is important to transparently plan a migration from the beginning and think in terms of persistence locations and ground truth of data. The worst-case scenario is if the developers of your legacy system and your new system are working against each other. Also, migration time should be as short as reasonably possible to avoid divergence of the systems as well as other data governance issues. Just think about the GDPR inquiry and deletion processes in two loosely coupled systems with partially overlapping data.
Can I use a simplified solution?
FHIR will almost certainly be the new standard for healthcare interoperability. Therefore it definitely makes sense to be able to ingest and export data in the FHIR format. Typically, FHIR servers will come with a persistence level which can easily lead to the “where is my ground-truth“ problems sketched above. Especially if you want to keep your existing system, this can get problematic. In such cases, it is probably a better idea to build an FHIR facade in front of your existing system. One example would be a HAPI FHIR facade, which is probably the most advanced Open Source solution at hand.
Kubernetes is a nice setup for a microservice architecture. However, if this is not your goal it is probably a bit too complex for the job. If you just want to have a high-available and somehow dynamic development setup, it is probably sufficient to run multiple containers on different machines behind an Application Load Balancer. In case you have the option to use managed services in the cloud, you could just go for the managed container solution of your choice. This will remove, or at least reduce, the cost of maintaining a cluster on your own.
If you plan to allow users to log in to your system, using a Keycloak is almost never a bad idea. The simple reason is that it is the de-facto Open Source standard and probably more mature than anything you can come up with on your own. In combination with SmileCDR (probably other FHIR servers could do this as well), you get SMART on FHIR capabilities and fine-grained data access permissions on top. This is extremely useful and hard to achieve manually. So if you plan to build apps with access to specific fractions of your healthcare go for SMART on FHIR.
In this blog post, we sketched a modern architecture applicable to hospital setups as well as for large healthcare app development. While the complete setup might be a fit for some use cases, it might be overly complex for many situations. However, thinking about problems of identity management, scalability, high availability, and development workflows will be core in digitizing healthcare. Our wish is that parts or at least thoughts about the components described in this post might help others in building a better system. Digitization of healthcare should be discussed in a broader interdisciplinary community, bringing in concepts from other areas. We think that bridging the gap between healthcare domain experts and modern software developers is probably the best chance we have to build digital healthcare services that really help patients and healthcare professionals.