Medplum supports three primary authentication integration patterns, summarized by the following diagram. Each has its own use case, and is supported by various authentication methods. An implementation can use multiple or all patterns for different use cases.
This diagram shows a high level summary of the three common patterns. The Medplum Typescript SDK can (optionally) be used in all three patterns.
There are 3 primary domains of authentication for a Medplum healthcare app:
- **Client-side: ** A user facing application, typically running in a web browser or native app
- Server-side: A back-end web server acting as a proxy to Medplum, operating in a trusted environment
- Device / Host: A non-web enabled device, such as lab analyzer or on-premise host machine
Client side authentication is when a user facing application connects directly to Medplum to request, create or update data. These applications typically operate in untrusted environments, such as web browsers or native mobile applications, and have users (providers or patients) provide user credentials to verify their identity.
Rate limits will be enforced for client authentication, as it is assumed that traffic is coming from end users.
When implementing client side authentication, developers must choose an identity provider. Developers can either use Medplum as their primary identity provider, or use an external identity provider such as Auth0, Okta, or AWS Cognito.
Medplum as Identity Provider
When using Medplum as an identity provider, the recommended client side authentication pattern is to use the OAuth2 Auth Code flow.
You can initiate this in the Medplum Client using the
External Identity Provider
Another option developers have integrating an external identity provider, such as Auth0, Okta, or AWS Cognito, to authenticate users. This is valuable in creating SSO (single sign on) experiences or when implementing alternative log-in flows (passwordless, SMS, biometric, etc.) .
When integrating an external identity provider, developers have a few additional decisions to make:
Application-level vs. Domain-level
Most implementations integrate identity providers at the client application level. This allows different applications to use different identity providers. For example, a patient-facing application may use google auth, but the provider-facing application may use the company's Okta account.
However, in some cases implementers would like all users with a given domain (e.g. @myhospital.org) to sign in with a given identity provider regardless of which application they are logging into. Medplum offers domain level identity provider integration for these use cases.
Medplum Managed Token vs. Token Exchange
Logging in with an external identity provider will produce an access token issued by that provider (e.g. an Auth0 access token). To use this token with Medplum APIs, your application will need to exchange the identity provider's access token for a Medplum access token.
If your application only accesses Medplum APIs, you can handle this token-exchange purely on the server side using federated identity login. The benefit of this approach is that your application only needs to maintain a single access token. Our External Identity Providers guide describes how to set up this log in flow, and you can use the
signInWithExternalAuth SDK function to initiate the log in flow from your application.
In some situations, your application might need to store the external access token as well as the Medplum token. This commonly occurs when migrating an existing application onto Medplum. In these cases, you can use the token exchange method to exchange the external token for the Medplum token from the client. While this approach is simpler to implement, it requires your application to maintain two separate access tokens in the browser. The corresponding SDK method for this approach is
When integrating with external identity providers, Medplum needs some way to map users from the external provider to Medplum users (see the User Management Guide for more details). By default, Medplum matches users in both systems using their email addresses.
For login flows that don't use email address (e.g. phone number login), Medplum allows you to use an external ID supplied by the identity provider as the user's unique ID. See our guide on Using External IDs for more information.
Server side authentication is when a user facing application proxies through a host to connect to Medplum. This integration can be useful when adding Medplum functionality to a legacy application.
For server side authentication, developers should set up a
ClientApplication to identify the server (see this guide on Creating a Client Application). When looking at resource history and AuditEvents for this type of implementation, actions will be taken on behalf of the
ClientApplication that the server is using to connect.
The Client Credentials flow is the recommended authentication pattern for this kind of integration. Each server can manage credentials and tokens, and use the Medplum SDK to authenticate. Using the Typescript SDK, maintain an instance of
MedplumClient as part of your running application and use the startClientLogin call to start an active login. The client will continue to refresh the connection if it is in active use, storing the access token in memory on the server.
Client credentials access token should be stored in session state and reused. Client credential flow is rate limited, so frequently requesting tokens will lead to service degradation. This may not be possible in some stateless server environments, and Medplum supports Basic Auth to support these use cases.
Device authentication is designed for true machine connectivity, for example connecting a laboratory analyzer machine, or a CI/CD pipeline to Medplum. This is distinct from server side authentication, in which the server a proxy for a user facing application.
If OAuth2 client credentials based authentication is not an option due to device limitations, Basic Authentication can be used to connect to Medplum. In general, OAuth2 is preferred to basic authentication. Consuming webhooks is an example application where Basic Authentication makes sense.
Security Best Practices
All three implementations types will have tokens or client credentials with system access, and edge systems should follow best practices. Below are examples of security best practices for each implementation type.
The practices below are only suggestions. Please consult your compliance and legal team to ensure that your devices are HIPAA compliant.
- Use strong passwords - NIST Guidelines suggest passwords should be a minimum of 8 characters that are easy to remember and which have been tested against a "blocked list" of unacceptable passwords.
- When possible, users should set up two-factor authentication on their devices.
- Local disk should be encrypted.
- Workstation should be password locked.
- Consider disabling local storage on device for shared workstations or in accordance with institution policy.
- Organizations with mobile devices or laptops should enable a Mobile Device Management (MDM) solution for workstations
- IP restrictions can be enabled when especially sensitive data, such as personal health information (PHI), is being accessed.
- Run with as strict an access policy as possible. following the principle of least privileges.
- Encrypt hard disk.
- Restrict access to host via VPC or other mechanism - do not allow access from general internet.
- Use a secrets management to store access keys - do not store credentials on disk.
- Ensure host is patched and has security updates applied regularly.
- Run with extremely an limited access policy. For example: read-only access to a specific Bot.
- Restrict network access to the host - do not allow access from the general internet.
- Ensure host is patched and has security updates applied regularly.