Federated Login with OpenID Connect
Federated login allows users to authenticate using their existing identity from external identity providers (IdPs) rather than creating new credentials for Haste Health. This is implemented using OpenID Connect (OIDC), an identity layer built on top of OAuth 2.0.
Overview
With federated login, Haste Health acts as a Relying Party (RP) that trusts external Identity Providers to authenticate users. Common identity providers include:
- Enterprise IdPs: Okta, Auth0, Azure AD, Google Workspace
- Healthcare IdPs: Epic MyChart, Cerner Patient Portal
- Social IdPs: Google, Microsoft, Apple
- Government IdPs: Login.gov, ID.me
How Federated Login Works
The federated login flow involves three parties:
- User (Resource Owner): The end user attempting to access Haste Health
- Haste Health (Relying Party/Client): The application requesting authentication
- Identity Provider (Authorization Server): The external system that authenticates the user
OIDC Authorization Code Flow
Assigning access on first sign-in
The first time a user signs in through an identity provider, Haste Health creates a User and a Membership for them. Without an access policy, that user can't read or write anything until an administrator assigns one.
A project can assign policies automatically with Project.identityProviderSetting:
{
"resourceType": "Project",
"id": "my-project",
"name": "My Project",
"fhirVersion": "4.0.1",
"identityProvider": [{ "reference": "IdentityProvider/okta" }],
"identityProviderSetting": [
{
"identityProvider": { "reference": "IdentityProvider/okta" },
"defaultAccessPolicy": [
{ "reference": "AccessPolicyV2/clinician-read" }
]
}
]
}
When a user first signs in through IdentityProvider/okta, one AccessPolicyV2Assignment is created per listed policy, linked to that user's new Membership, in the same transaction that creates the user. The policies apply as soon as the user gets a token.
This runs only when the user is created. Later sign-ins don't change existing assignments, so an assignment an administrator removes is not recreated, and changing defaultAccessPolicy does not affect users who have already signed in.
The identity provider must also be listed in Project.identityProvider; a setting for any other provider is ignored.
Setup Guides
- Okta Integration Guide
- Azure AD Integration Guide
- GCP Integration Guide
- Auth0 Integration Guide
- Keycloak Integration Guide
- Haste Health Integration Guide
Scopes
IdentityProvider.oidc.scopes is sent to the provider's authorization endpoint.
openid is always requested, whether or not it is listed, because the callback
identifies the user from the sub claim of the id token and a provider only
returns an id token for an OIDC request.
The client registered with the provider must also be allowed those scopes. A provider that refuses one of them sends the user back to the callback with an error instead of a code, and the sign-in fails with that error.
Add profile and email to store the user's name and email address on the
User resource. They are read from the id token when the user is first created;
without them the user is created with only its federated id.
Troubleshooting
No id token returned
Error: Identity provider did not return an id token
Solution: Register the provider's client for the openid scope. Some
providers only return an id token when the client is explicitly allowed it.
Token Validation Failed
Error: Token signature verification failed
Solution:
- Verify the JWKS URI is correct and accessible
- Check that the token hasn't expired
- Ensure the issuer and audience claims match expectations
Best Practices
- Use Authorization Code Flow: Most secure for web applications
- Use PKCE: Adds security for public clients