Token response format
The most common SMART implementation mistake
Most SMART implementations put the launch context (patient, encounter) inside the JWT access token payload. This is wrong per the SMART v2.2 spec.
The spec (§7.1) is explicit:
The EHR authorization server SHALL provide launch context values as top-level fields in the JSON token response body.
The AJ Auth Server does this correctly:
HTTP/1.1 200 OK
Content-Type: application/json
{
"access_token": "eyJhbGciOiJSUzI1NiI...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "launch openid patient/Patient.rs",
"patient": "GOLDEN-00441",
"encounter": "enc-441-br01",
"need_patient_banner": true,
"id_token": "eyJhbGciOiJSUzI1NiI..."
}
Why it matters
A SMART client may not have access to the JWKS endpoint at token receipt time — especially in EHR-embedded iframe contexts where the client launches before full network access is available. The client must be able to read patient and encounter without decoding the JWT.
The id_token
The id_token is a separate RS256 JWT containing:
{
"iss": "http://authserver:9000",
"sub": "Practitioner/pr-perera-001",
"fhirUser": "Practitioner/pr-perera-001",
"aud": "client-id",
"iat": 1749734400,
"exp": 1749738000
}
The fhirUser claim identifies the clinician as a FHIR Practitioner reference — verifiable against the JWKS public key at http://authserver:9000/oauth2/jwks.