Skip to main content

User Management Guide

This guide walks through how to create and manage users via the Medplum App and via API. Medplum supports multiple authentication options, but always maintains a representation of the user identities, and gives developers control over which authentication method to use for an identity, as well as what access controls are applied.

Background: User Model

Medplum has several resources that represent user identities. The following resources are fundamental to building a correctly functioning application. This table describes how identities are represented in the system, and provides links to the administrative settings in the Medplum App.

Users and Projects

ResourceDescriptionMedplum App
UserA resource that represents a user identity. Users exist above the Project level and can only be self-updated.None
ProjectA Project is an isolated set of resources. With the exception of User, resources do not exist across ProjectsProject Admin
ProjectMembershipA ProjectMembership represents granting a user access to the resources within a Project. Inviting a user to a project, and specifying their profile and accessPolicy you can determine what set of resources they can access.Invite (Admins only), Users (Admins only)

Profiles

Within each project, a project member is represented by a specific FHIR resource, known as their profile. The ProjectMembership.profile element links the ProjectMembership to the profile resource.

A user's profile can be one of the three resource types in the table below. Incorporating the resources in the table below into ProjectMembership enable sophisticated access controls, as Access Policies can access the profile of the current user (read more)

ResourceDescriptionMedplum App
PatientPatient is a fundamental FHIR resource and linking it to an identity allows the simple use case of granting access to personal records.Patients
PractitionerPractitioners are staff members of a healthcare organization and generally have access to multiple patients' data.Practitioner
RelatedPersonRelatedPerson is a family member or caregiver of a patient, who may be granted access to a small number of patient recordsRelatedPerson

There are several ProjectMembership.profile resources that are related to programmatic access, which serve as modifiers to the ProjectMembership resource (i.e. ProjectMembership.profile) and do not represent people, but rather applications that access data. This table describes the programmatic access profiles with links on where to set them up in the Medplum App.

ResourceDescriptionMedplum App
ClientApplicationAPI Keys that allow programmatic access to resourcesClient Applications
BotEvent driven custom functionsBots

Creating a new Project

UI

The simplest way to create a project is to visit https://app.medplum.com/register and fill out the new project registration form.

Note

If you are self-hosting, replace app.medplum.com with app.your-base-url.com

API

To create a new Project resource via the API, you will need to create a ClientApplication with super admin privileges.

danger

Super admin features can cause unrepairable damage. We highly recommend adding an Access Policy to this ClientApplication to reduce it's privileges.

With is ClientApplication, you can create a Project resource and invite the a new user as a project admin.

const newProject: Project = await medplum.createResource({
resourceType: 'Project',
name: 'ProjectName',
strictMode: true,
});

await medplum.post('admin/projects/' + newProject.id + '/invite', {
resourceType: 'Practitioner',
firstName: '[firstname]',
lastName: '[lastname]',
email: '[email]',
admin: true,
});

User Administration via Medplum App

Users in Medplum can be members of multiple projects, so cannot be edited directly. You'll need to invite a user to a project in order to grant access. If the user does not exist, it will be created when invited.

Creating Memberships

Only administrators can invite users, and can do so on the Invite page. You can specify a role and AccessPolicy at time of invite. The invite flow will do the following:

  1. Create a User if one does not already exist
  2. Create a FHIR resource (Patient, Practitioner or RelatedPerson)
  3. Create a ProjectMembership that links User, ProfileResource and access policy
  4. (Optional) send an email invite user
Note

Do not delete Patient, Practitioner or RelatedPerson resources that belong to ProjectMemberships. This will cause the login to be non-functional. Do not edit or change the ProjectMembership resources directly.

Removing Memberships

Tor remove users from the existing project navigate to your Project settings and to the Users and Patient tabs respectively. Click on a specific users or patients and click Remove User.

We highly recommend leaving the associated FHIR resource (Patient, Practitioner, etc.) in place for audibility, record keeping and in case the membership needs to be reconstructed for some reason.

Searching for Project Members

You can search for all project members by performing a search for all ProjectMembership resources

Example: Search for all project members

await medplum.searchResources('ProjectMembership');

You can also use the profile-type search parameter to narrow your search

Example: Search for all human members

await medplum.searchResources('ProjectMembership', 'profile-type:not=ClientApplication,Bot');

Example: Search for all project Patients

await medplum.searchResources('ProjectMembership', 'profile-type=Patient');

Example: Search for all project Practitioners

await medplum.searchResources('ProjectMembership', 'profile-type=Practitioner');

Refer to our search documentation for more details on FHIR search

Invite via API

Inviting users can be done programmatically using the /invite endpoint

Prepare JSON payload:

{
"resourceType": "Patient",
"firstName": "Homer",
"lastName": "Simpson",
"email": "homer@example.com",
"sendEmail": false
}

Then POST to the /invite endpoint:

curl 'https://api.medplum.com/admin/projects/${projectId}/invite' \
-H 'Authorization: Bearer ${accessToken}' \
-H 'Content-Type: application/json' \
--data-raw '{"resourceType":"Patient","firstName":"Homer","lastName":"Simpson","email":"homer@example.com", "sendEmail":"false"}'

The /invite endpoint creates a ProjectMembership. The ProjectMembership resource includes additional properties to customize the user experience. The /invite endpoint accepts a partial ProjectMembership in the membership property where you can provide membership details.

For example, use admin: true to make the new user a project administrator:

{
"resourceType": "Practitioner",
"firstName": "Homer",
"lastName": "Simpson",
"email": "homer@example.com",
"membership": {
"admin": true
}
}

Or use the access property to specify a user's AccessPolicy with optional parameters.

{
"resourceType": "Patient",
"firstName": "Homer",
"lastName": "Simpson",
"email": "homer@example.com",
"membership": {
"access": [
{
"policy": { "reference": "AccessPolicy/123" },
"parameter": [
{
"name": "provider_organization",
"valueReference": { "reference": "Organization/abc" }
}
]
},
{
"policy": { "reference": "AccessPolicy/123" },
"parameter": [
{
"name": "provider_organization",
"valueReference": { "reference": "Organization/def" }
}
]
}
]
}
}

See Access Control for more details.

caution

Creating Practitioners via API is an advanced scenario and should be done with extreme caution. If you are planning to do programmatic creation of Practitioners, we highly recommend trying it in a test environment first and ensuring that the logins and associated access controls behave as expected.