Metadata Fields and Validation
Table of contents
Field Reference
server_metadata returns a Safire::Protocols::SmartMetadata object. All fields are accessible through readers and retain the representation sent by the server. The types below describe the expected SMART metadata shapes; call valid? to diagnose malformed values.
Always Required
| Field | Type | Description |
|---|---|---|
token_endpoint | String | OAuth2 token endpoint URL |
grant_types_supported | Array | Supported OAuth2 grant types |
capabilities | Array | SMART capabilities list |
code_challenge_methods_supported | Array | Must include "S256", must not include "plain" |
Conditionally Required
| Field | Type | Required when |
|---|---|---|
authorization_endpoint | String | capabilities include launch-ehr or launch-standalone |
issuer | String | capabilities include sso-openid-connect |
jwks_uri | String | capabilities include sso-openid-connect |
Optional
| Field | Type | Description |
|---|---|---|
registration_endpoint | String | Dynamic client registration URL |
scopes_supported | Array | Available OAuth2 scopes |
response_types_supported | Array | Supported response types |
token_endpoint_auth_methods_supported | Array | Token endpoint auth methods (e.g. client_secret_basic, private_key_jwt) |
token_endpoint_auth_signing_alg_values_supported | Array | JWT signing algorithms (e.g. RS384, ES384) — used by asymmetric_signing_algorithms_supported |
introspection_endpoint | String | Token introspection URL |
revocation_endpoint | String | Token revocation URL |
management_endpoint | String | User access management URL |
associated_endpoints | Array | Endpoints sharing this auth server |
user_access_brand_bundle | String | Brand bundle URL for user-facing apps |
user_access_brand_identifier | String | Primary brand identifier |
Example Usage
metadata.token_endpoint # => "https://fhir.example.com/token"
metadata.grant_types_supported # => ["authorization_code", "refresh_token"]
metadata.capabilities # => ["launch-ehr", "client-public", ...]
metadata.code_challenge_methods_supported # => ["S256"]
# Conditionally present
metadata.authorization_endpoint # => "https://fhir.example.com/authorize"
metadata.issuer # => "https://fhir.example.com"
metadata.jwks_uri # => "https://fhir.example.com/.well-known/jwks.json"
# Optional
metadata.registration_endpoint # => "https://fhir.example.com/register"
metadata.scopes_supported # => ["openid", "profile", "patient/*.read", ...]
metadata.token_endpoint_auth_methods_supported # => ["client_secret_basic", "private_key_jwt"]
metadata.token_endpoint_auth_signing_alg_values_supported # => ["RS384", "ES384"]
metadata.introspection_endpoint # => "https://fhir.example.com/introspect"
metadata.revocation_endpoint # => "https://fhir.example.com/revoke"
metadata.management_endpoint # => "https://fhir.example.com/manage"
metadata.associated_endpoints # => [{"url" => "...", "capabilities" => [...]}]
metadata.user_access_brand_bundle # => "https://fhir.example.com/brands"
metadata.user_access_brand_identifier # => "example-brand"
Validation
valid? checks Safire’s selected SMART App Launch 2.2.0 structural diagnostics and logs a warning for each violation. It is not a complete server certification suite and never raises. Deciding whether to block on a failed diagnostic is the caller’s responsibility.
if metadata.valid?
# All required fields present, PKCE compliant
else
# Safire has already logged warnings for each violation
raise 'Server metadata does not meet SMART App Launch 2.2.0 requirements'
end
What valid? checks:
- All always-required fields are present
- Conditional fields present when their capability is advertised
- Array-valued fields are arrays containing values of the documented type
code_challenge_methods_supportedincludes'S256'(SHALL per SMART 2.2.0)code_challenge_methods_supporteddoes not include'plain'(SHALL NOT per SMART 2.2.0)
Discovery does not fail solely because a usable JSON object contains a structurally nonconformant field. valid? reports that defect explicitly. Capability and algorithm helpers treat malformed list advertisements as unsupported rather than using scalar substring matching or raising an unexpected type error.
Example warning output:
WARN: SMART metadata non-compliance: required field 'authorization_endpoint' is missing
WARN: SMART metadata non-compliance: field 'capabilities' must be an array containing only strings
WARN: SMART metadata non-compliance: 'S256' is missing from code_challenge_methods_supported (SMART App Launch 2.2.0 requires S256)
WARN: SMART metadata non-compliance: 'plain' is present in code_challenge_methods_supported (SMART App Launch 2.2.0 prohibits plain)
Example Server Response (SMART App Launch 2.2.0)
{
"issuer": "https://fhir.example.com",
"authorization_endpoint": "https://fhir.example.com/authorize",
"token_endpoint": "https://fhir.example.com/token",
"jwks_uri": "https://fhir.example.com/.well-known/jwks.json",
"grant_types_supported": ["authorization_code", "refresh_token"],
"scopes_supported": ["openid", "profile", "launch", "patient/*.read", "offline_access"],
"response_types_supported": ["code"],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"private_key_jwt"
],
"token_endpoint_auth_signing_alg_values_supported": ["RS384", "ES384"],
"code_challenge_methods_supported": ["S256"],
"capabilities": [
"launch-ehr",
"launch-standalone",
"client-public",
"client-confidential-symmetric",
"client-confidential-asymmetric",
"sso-openid-connect",
"context-ehr-patient",
"context-ehr-encounter",
"context-standalone-patient",
"permission-offline",
"permission-patient",
"permission-user"
]
}