Direct External Authentication | Medplum
Overview
Medplum supports authenticating users directly with an external Identity Provider (IDP) access token, without requiring a token exchange or authorization code flow. This is useful when your application already holds a valid JWT from an external IDP and wants to access the Medplum API directly.
Self-Hosted Deployments Only
This feature requires super admin privileges to configure externalAuthProviders in the server config, which is only available on self-hosted Medplum deployments. If you are using Medplum's cloud-hosted service and need this capability, please contact Medplum support.
Overview
When a user presents a JWT issued by a configured external auth provider, Medplum can:
- Validate the token against the IDP's userinfo endpoint
- Identify the user from claims in the token
- Return Medplum auth credentials for subsequent API access
There are two ways to identify the user from the token:
| Method | JWT Claim | Lookup | Best for |
|---|---|---|---|
| FHIR User | fhirUser |
Profile reference or search | SMART-on-FHIR compliant IDPs |
| Subject | sub |
ProjectMembership.externalId |
Standard OIDC IDPs |
If both fhirUser and sub are present, the fhirUser claim takes precedence.
Server Configuration
Add external auth providers to your Medplum server configuration:
{
"externalAuthProviders": [
{
"issuer": "https://your-idp.example.com",
"userInfoUrl": "https://your-idp.example.com/oauth2/userinfo"
}
]
}
| Field | Description |
|---|---|
issuer |
The iss claim value in JWTs from this IDP |
userInfoUrl |
The IDP's userinfo endpoint, used to validate tokens |
Using the fhirUser Claim
The fhirUser claim contains a FHIR resource reference identifying the user's profile. It can be provided in several formats:
- Direct reference:
Practitioner/abc123 - Search string:
Practitioner?identifier=1234567890 - Absolute URL:
https://idp.example.com/fhir/Practitioner?identifier=1234567890
Some IDPs place custom claims inside an ext block. Medplum also checks ext.fhirUser for compatibility.
How it works
- Medplum extracts the
fhirUserclaim from the JWT - Validates the token against the IDP's userinfo endpoint
- Searches for the FHIR profile resource matching the claim
- Finds the
ProjectMembershipassociated with that profile - Returns auth credentials scoped to that membership
Using the sub Claim
The sub (subject) claim is a standard JWT claim (RFC 7519) present in virtually all JWTs. When no fhirUser claim is present, Medplum uses the sub claim to look up a ProjectMembership by its externalId field.
Setup
- Configure the external auth provider in your server config (see above)
- Invite users with an
externalIdmatching their IDPsubvalue:
curl 'https://BASE_URL/admin/projects/PROJECT_ID/invite' \
-H 'Authorization: Bearer ACCESS_TOKEN' \
-H 'Content-Type: application/json' \
--data-raw '{
"resourceType": "Practitioner",
"firstName": "Jane",
"lastName": "Smith",
"externalId": "IDP_SUBJECT_ID"
}'
Replace BASE_URL, PROJECT_ID, and ACCESS_TOKEN with your actual values.
How it works
- Medplum parses the JWT and finds no
fhirUserclaim - Extracts the
subclaim - Validates the token against the IDP's userinfo endpoint
- Searches for a
ProjectMembershipwhereexternalIdmatches thesubvalue - Returns auth credentials scoped to that membership
Making Requests
Once configured, make requests to the Medplum FHIR API using the external IDP token directly:
curl 'https://${baseUrl}/fhir/R4/Patient' \
-H 'Authorization: Bearer ${externalAccessToken}'
A successful response means that the authentication with the external IDP was successful.
Comparison with Token Exchange
| Direct External Auth | Token Exchange | |
|---|---|---|
| Endpoint | /oauth2/userinfo |
/oauth2/token |
| Configuration | Server-level externalAuthProviders |
Per-ClientApplication identity provider |
| Token format | Uses external JWT directly | Exchanges for Medplum access token |
| User lookup | fhirUser claim or sub / externalId |
Email or sub (via useSubject flag) |
Choose Direct External Auth when you want to use external JWTs directly without an explicit token exchange step. Choose Token Exchange when you need a standard Medplum access token or when the auth flow is scoped to a specific ClientApplication.