Backend Services Workflow
System-to-system access token requests using the OAuth 2.0 client_credentials grant and mandatory JWT assertion authentication — no user interaction, redirect URI, or PKCE required.
Overview
SMART Backend Services enables autonomous server-to-server FHIR access without involving a user. It is defined in the SMART App Launch Backend Services specification.
Instead of a redirect flow, the client:
- Registers with the authorization server following the confidential asymmetric registration steps (required by the spec)
- Builds a signed JWT assertion using its registered private key
- Posts the assertion to the token endpoint with
grant_type=client_credentials - Receives an access token directly — no authorization code, no callback, no PKCE
Suitable for:
- Scheduled data pipelines and batch jobs
- System integrations that run without a logged-in user
- Clinical quality reporting and analytics platforms
- Any server-to-server FHIR workflow
Key Differences from App Launch
| Aspect | App Launch | Backend Services |
|---|---|---|
| Grant type | authorization_code | client_credentials |
| User interaction | Required | None |
| Redirect URI | Required | Not used |
| PKCE | Required | Not used |
| Client auth | Varies by client_type: | JWT assertion always |
| Scopes | patient/, user/, openid | system/ |
| Refresh token | Usually issued | Not issued |
expires_in | Recommended | Required |
Prerequisites: Registration, Keys, and JWKS
Client Registration
Before making any token requests, the client SHALL register with the authorization server following the confidential asymmetric client registration steps defined in the SMART App Launch specification. Registration communicates the client’s public key(s) to the server, either via a JWKS URI or by uploading the JWKS directly. If the server supports RFC 7591, you can automate this step with Safire’s register_client — see the Dynamic Client Registration guide.
Key Pair and JWKS
Backend services use the same RSA or EC key pair infrastructure as the confidential asymmetric app launch flow — key generation, JWKS publishing, and algorithm selection are identical. See the Confidential Asymmetric Client — Prerequisites guide for full details.
Client Setup
redirect_uri and scopes are optional for backend services clients. If scopes is omitted, Safire defaults to ["system/*.rs"] when request_backend_token is called.
config = Safire::ClientConfig.new(
base_url: ENV['FHIR_BASE_URL'],
client_id: ENV['SMART_CLIENT_ID'],
private_key: OpenSSL::PKey::RSA.new(ENV['SMART_PRIVATE_KEY_PEM']),
kid: ENV['SMART_KEY_ID'],
scopes: ['system/Patient.rs', 'system/Observation.rs'] # optional
)
client = Safire::Client.new(config)
client_type:is not used for backend services —request_backend_tokenalways authenticates via JWT assertion regardless ofclient_type.
What’s Next
- Token Request — Requesting a token, scope/credential overrides, flow diagram, validation, error handling, and proactive renewal
- Security Guide — Private key management and rotation
- Confidential Asymmetric Client — The app launch counterpart that shares the same key infrastructure