Skip to content

OAuth & Authentication ​

Proxy Smart acts as an OAuth 2.0 / OpenID Connect proxy between SMART apps and Keycloak. All authentication traffic flows through the /auth endpoints, which validate, enrich, and forward requests to the underlying Keycloak realm.

Architecture ​

SMART App  ──►  /auth/authorize  ──►  Keycloak /auth endpoint
                                          │
SMART App  ◄──  redirect with code  ◄────┘
                                          
SMART App  ──►  /auth/token      ──►  Keycloak /token endpoint
                                          │
SMART App  ◄──  access_token     ◄────────┘
                                          
SMART App  ──►  /proxy-smart/…   ──►  FHIR Server (with validated token)

Endpoints ​

Discovery ​

EndpointDescription
GET /auth/.well-known/openid-configurationProxies Keycloak's OIDC discovery metadata
GET /auth/.well-known/oauth-authorization-serverOAuth 2.0 AS Metadata (RFC 8414)
GET /auth/configReturns Keycloak connectivity status and realm info
GET /.well-known/oauth-protected-resourceRFC 9728 Protected Resource Metadata for MCP clients
GET /.well-known/jwks.jsonJSON Web Key Set for token verification

Authorization Flow ​

EndpointDescription
GET /auth/authorizeRedirects to Keycloak's authorization endpoint
GET /auth/loginSimplified login redirect with sensible defaults for UI apps
GET /auth/logoutProxies logout to Keycloak with id_token_hint and redirect
GET /auth/identity-providersPublic list of enabled identity providers for login pages

Token Operations ​

EndpointDescription
POST /auth/tokenProxies token requests to Keycloak (authorization code, refresh, client credentials)
POST /auth/introspectToken introspection with SMART launch context enrichment
GET /auth/userinfoUserInfo endpoint with authorization_details generation

Dynamic Client Registration ​

EndpointDescription
POST /auth/registerRFC 7591 Dynamic Client Registration

Authorization Flow Details ​

SMART App Launch ​

  1. App redirects to /auth/authorize with standard OAuth parameters plus SMART-specific:

    • aud -- the FHIR server URL the app wants to access (validated against configured servers)
    • scope -- SMART scopes like launch/patient patient/*.read openid fhirUser
    • launch -- EHR launch token (for EHR launch flow)
  2. Audience validation -- the proxy validates the aud parameter matches a configured FHIR endpoint, preventing token leakage to unauthorized servers (SMART App Launch 2.2.0 requirement).

  3. Keycloak handles authentication -- user logs in, consents to scopes, Keycloak redirects back with an authorization code.

  4. App exchanges code at /auth/token -- the proxy forwards the token request to Keycloak. The response includes SMART launch context claims (patient, encounter, fhirUser) injected by Keycloak scope mappers.

Supported Grant Types ​

Grant TypeUse Case
authorization_codeStandard SMART App Launch (EHR and standalone)
refresh_tokenToken refresh
client_credentialsBackend Services (with JWT client assertion)
passwordResource Owner Password (admin tools only)
Token Exchange (RFC 8693)Subject token exchange for delegated access

Backend Services ​

For system-to-system access without user interaction:

  • Uses client_credentials grant with client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
  • Client authenticates with a signed JWT containing system/*.read scopes
  • No user context -- suitable for bulk data, analytics, and integration engines

Token Introspection ​

POST /auth/introspect enriches Keycloak's introspection response with SMART-specific fields:

  • Generates authorization_details from token claims and configured FHIR servers
  • Includes FHIR server locations, versions, patient context, and granted scopes
  • Follows the SMART on FHIR authorization details type (smart_on_fhir)

UserInfo ​

GET /auth/userinfo returns the standard OIDC UserInfo response plus authorization_details generated from the token's SMART claims and configured FHIR server endpoints.

Keycloak Unavailability ​

If Keycloak is unreachable when a user tries to authenticate, the proxy returns a friendly HTML error page (HTTP 503) with a retry button instead of a raw browser connection error. This applies to /auth/authorize and /auth/login.

Environment Variables ​

VariableDescriptionDefault
KEYCLOAK_BASE_URLInternal Keycloak URL--
KEYCLOAK_PUBLIC_URLBrowser-facing Keycloak URL (if different from internal)derives from KEYCLOAK_BASE_URL
KEYCLOAK_REALMKeycloak realm name--
KEYCLOAK_ADMIN_CLIENT_IDService account client ID for admin API calls--
KEYCLOAK_ADMIN_CLIENT_SECRETService account client secret--
KEYCLOAK_DOMAINDomain override for public URL generation--

Proxy Smart — Healthcare Interoperability Platform