What OpenID Connect Adds to a SMART on FHIR Server — and What It Does Not
What OpenID Connect Adds to a SMART on FHIR Server — and What It Does Not
Primary query: OpenID Connect SMART on FHIR id_token
Version: dev
Source revision: 7e036d413940d3978a5042409d387a4d52f2485c
FHIR version: R4 4.0.1
Data: synthetic only
Ilavrita remains a developer preview. Do not use patient data.
Last verified: October 4, 2026
SMART App Launch already depends on OAuth concepts: authorization, scopes, tokens and redirect flows. OpenID Connect adds another question: who authenticated?
At the current Ilavrita revision, OpenID Connect support includes RS256-signed id_token issuance when a sealing/signing key is configured, JWKS publication, discovery, and fhirUser resolution. The README also states an important negative capability: the profile scope remains refused.
That boundary is intentional.
An access token and an ID token answer different questions
An access token is authority presented to an API.
An ID token is an assertion about the authentication event and subject for the client.
Conflating them makes authorization logic harder to review. A client learning who signed in does not automatically gain more FHIR access, and an identity claim should not manufacture a resource permission that the authorization layer never granted.
That is consistent with Ilavrita's SMART scope rule: scopes narrow existing authority; they do not create it.
Discovery makes the contract inspectable
OIDC discovery and JWKS publication let clients discover issuer metadata and obtain the public keys needed to verify signed tokens.
This matters operationally because verification should not depend on a client receiving a private secret from the server. The server signs; the client verifies against published public key material.
The README records OIDC as working only where a sealing key is configured. Configuration is therefore part of the capability boundary, not a footnote.
fhirUser is useful because it points back into FHIR
SMART's fhirUser identity claim can connect the authenticated subject to a FHIR resource representing that user.
That is more useful to a healthcare client than inventing a parallel Ilavrita identity vocabulary at the application boundary.
But resolution is not the same thing as unrestricted access to the referenced resource. Normal authorization rules still matter.
Why refusing profile matters
It is tempting to accept a familiar OIDC scope because a generic library knows its name.
Ilavrita currently refuses profile.
That is preferable to returning an incomplete or misleading standard claim set. A standards surface should describe behavior the implementation actually provides, not behavior adjacent libraries make easy to advertise.
The same evidence-first rule used for FHIR interactions applies to identity protocols.
External conformance is evidence, not certification
Repository documentation records OpenID Connect behavior alongside SMART Inferno results. That is useful evidence about interoperability behavior.
It is not a claim of production security, regulatory compliance, or certification. The project still states that it has not undergone an external security review and is not ready for patient data.
Those limits remain in force even when a protocol test passes.
Documentation drift still matters
The current README describes the implemented authentication, SMART and OIDC surface. The introductory prose in api/openapi.yaml is stale and still contains older claims that authentication is not implemented.
That contradiction was already identified during the October 1 evidence pass. Until corrected, current source/tests and runtime capability metadata should win over that stale introductory prose.
Evidence
- Current dev revision
- OIDC/Inferno documentation commit
- README
- Security documentation
- Known limitations
- OpenAPI description
The useful mental model is simple: OAuth gives a client delegated authority; OpenID Connect gives the client an identity assertion. SMART combines healthcare-specific conventions with those protocols. None of them should silently become permission the authorization system never granted.
