OAuth 2.0 Overview
OAuth 2.0 is the industry standard for allowing external applications access to protected resources. See References for more about OAuth
OAuth 2.0 is a widely adopted standard that provides a secure method for external applications to access protected resources, such as user data, on behalf of the resource owner without needing to expose the user’s credentials. It enables third-party apps to interact with systems like Electronic Health Records (EHRs) while maintaining strict privacy and security standards, especially within healthcare environments. OAuth 2.0 introduces workflows that cater to different use cases, ensuring flexible access management while aligning with specific healthcare and security requirements. These workflows include:
![]() Patient Standalone Launch: This method allows patients to directly authorize applications to access their personal health information through an OAuth 2.0 authorization code flow. It enables a seamless, user-initiated connection between patient applications and the healthcare system PORTAL, granting permission for data access based on defined scopes. |
![]() Physician EHR Launch: Designed for healthcare providers, this workflow supports OAuth access for applications within the EHR that LAUNCH from a patient chart. By integrating with the healthcare provider's systems, practitioners can access and utilize third-party applications directly within their EHR interface, improving workflow efficiency and interoperability. |
![]() SMART Bulk Backend Services: For more extensive data operations, this workflow enables large-scale, system-level access to healthcare data using backend services. It is typically utilized for bulk data transfer, supporting use cases like data analysis, reporting, and research that require programmatic access to large datasets. |
Each method is tailored to specific needs within healthcare, balancing security, patient privacy, and ease of access. These OAuth 2.0 workflows are crucial for creating an interoperable ecosystem that respects data protection principles while empowering healthcare providers and patients with innovative applications.
- Patient
- Shared secret or PKCE for the app
- Session/Bearer token for each patient authorized to a specific app/patient/scope
- Provider
- Provider clicks on a link in the chart. A JWT is created for the provider for the specific patient (signed by the WebChart system)
- Shared secret, Asymmetric client credentials or PKCE for app
- Session/Bearer token for each provider authorized to a specific app/for a specific patient/scope
- Bulk
- A registered JWKS url allows JWTs from the app to be used in accessing pre-authorized system resources
Well Known Endpoint Information
https://URL/.well-known/openid-configuration
The .well-known path is a convention used in web development for serving metadata or configuration information in a standardized way. When working with OpenID Connect (OIDC), a well-known endpoint is often used to expose the OpenID Connect configuration details. Specifically, OpenID Connect defines a .well-known URL path where an identity provider (IdP) exposes its OpenID Connect metadata.
{
"issuer": "https://handle.url.com",
"authorization_endpoint": "https://handle.url.com/authorize",
"token_endpoint": "https://handle.url.com/token",
"revocation_endpoint": "https://handle.url.com/revoke",
"userinfo_endpoint": "https://handle.url.com/userinfo",
"jwks_uri": "https://handle.url.com/jwks",
"introspection_endpoint": "https://handle.url.com/introspect",
"response_types_supported": ["code"],
"grant_types_supported": [
"authorization_code",
"refresh_token",
"client_credentials"
],
"scopes_supported": [
"openid",
"profile",
"fhirUser",
"launch",
"patient/*.*",
"user/*.*",
"system/*.*"
],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"private_key_jwt"
],
"token_endpoint_auth_signing_alg_values_supported": [
"RS256",
"RS384",
"RS512",
"ES256",
"ES384",
"ES512"
],
"code_challenge_methods_supported": ["S256"],
"subject_types_supported": ["public"],
"id_token_signing_alg_values_supported":["RS256"]
}
https://URL/fhir/.well-known/smart-configuration
The smart-configuration is a .well-known endpoint specific to SMART on FHIR, and its main goal is to expose important configuration information about how apps should interact with the healthcare system’s OAuth and FHIR APIs.
{
"issuer": "https://handle.url.com",
"authorization_endpoint": "https://handle.url.com/authorize",
"token_endpoint": "https://handle.url.com/token",
"revocation_endpoint": "https://handle.url.com/revoke",
"userinfo_endpoint": "https://handle.url.com/userinfo",
"jwks_uri": "https://handle.url.com/jwks",
"introspection_endpoint": "https://handle.url.com/introspect",
"registration_endpoint": "https://handle.url.com/register"
"scopes_supported": [...],
"response_types_supported": "code",
"grant_types_supported": [
"authorization_code",
"refresh_token",
"client_credentials"
],
"token_endpoint_auth_methods_supported": [
"client_secret_basic",
"client_secret_post",
"private_key_jwt"
],
"token_endpoint_auth_signing_alg_values_supported": [
"RS256",
"RS384",
"RS512",
"ES256",
"ES384",
"ES512"
],
"code_challenge_methods_supported": ["S256"],
"capabilities": [
"lsunch-standalone",
"launch-ehr",
"client-public",
"client-confidential-symmetric",
"client-confidential-asymmetric",
"sso-openid-connect",
"authorize-post",
"permission-v2",
"permission-v1",
"context-standalone-patient",
"context-standalone-user",
"context-ehr-patient",
"context-ehr-encounter",
"permission-offline",
"permission-patient",
"permission-user",
"context-banner",
"context-style",
],
"code_challenge_methods_supported": ["S256"]
}
App Registration
Automatic Registration
Systems configured to allow App Registration via RFC 7591/7592 should utilize the registration endpoint for app registration.
Public Client
curl -s -X POST "https://handle.url.com/register" \
-H "Content-Type: application/json" \
-d '{
"client_id": "InfernoPub",
"redirect_uris": ["https://inferno.healthit.gov/suites/custom/smart/redirect"],
"token_endpoint_auth_method": "none",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"client_name": "Drummond Inferno Public Client",
"client_uri": "https://inferno.healthit.gov/suites",
"scope": "launch/patient openid fhirUser offline_access patient/*.rs",
"launch_uri": "https://inferno.healthit.gov/suites/custom/smart/launch"
}'
Response:
{
"client_id": "InfernoPub",
"client_id_issued_at": 1768977748,
"token_endpoint_auth_method": "none",
"grant_types": [
"authorization_code",
"refresh_token"
],
"response_types": [
"code"
],
"client_name": "Drummond Inferno Public Client",
"registration_access_token": "TvhrrHOwRm1xo6hWQ_2IGUFQM3n4mby4BY8xZ76TdxE",
"registration_client_uri": "https://handle.url.com/register/InfernoPub",
"redirect_uris": [
"https://inferno.healthit.gov/suites/custom/smart/redirect"
],
"launch_uri": "https://inferno.healthit.gov/suites/custom/smart/launch",
"client_uri": "https://inferno.healthit.gov/suites",
"scope": "launch/patient openid fhirUser offline_access patient/*.rs"
}
Confidential Client
curl -s -X POST "https://handle.url.com/register" \
-H "Content-Type: application/json" \
-d '{
"client_id": "DrummINF",
"redirect_uris": ["https://inferno.healthit.gov/suites/custom/smart/redirect"],
"token_endpoint_auth_method": "client_secret_post",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"client_name": "Drummond Inferno Test Suite",
"client_uri": "https://inferno.healthit.gov/suites",
"scope": "launch/patient openid fhirUser offline_access patient/*.rs user/*.rs",
"launch_uri": "https://inferno.healthit.gov/suites/custom/smart/launch"
}'
Response:
{
"client_id": "DrummINF",
"client_id_issued_at": 1769644710,
"token_endpoint_auth_method": "client_secret_post",
"grant_types": [
"authorization_code",
"refresh_token"
],
"response_types": [
"code"
],
"client_name": "Drummond Inferno Test Suite",
"registration_access_token": "5jp_y0hQBrv33TuNPyQYWXHRQTJ_s-cyeKRToKcBfxg",
"registration_client_uri": "https://handle.url.com/register/DrummINF",
"redirect_uris": [
"https://inferno.healthit.gov/suites/custom/smart/redirect"
],
"client_secret": "mgwYZCVnFAClYRu0hzoHmGfGv7AjEyrNDDTuc0iq0Is",
"client_secret_expires_at": 0,
"launch_uri": "https://inferno.healthit.gov/suites/custom/smart/launch",
"client_uri": "https://inferno.healthit.gov",
"scope": "launch/patient openid fhirUser offline_access patient/*.rs user/*.rs"
}
Asymmetric Client
curl -s -X POST "https://handle.url.com/register" \
-H "Content-Type: application/json" \
-d '{
"client_id": "InfAsym",
"redirect_uris": ["https://inferno.healthit.gov/suites/custom/smart/redirect"],
"token_endpoint_auth_method": "private_key_jwt",
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"],
"client_name": "Drummond Inferno Asymmetric Client",
"client_uri": "https://inferno.healthit.gov/suites",
"scope": "launch/patient openid fhirUser offline_access patient/*.rs",
"launch_uri": "https://inferno.healthit.gov/suites/custom/smart/launch",
"jwks_uri": "https://inferno.healthit.gov/.well-known/jwks.json"
}'
Response:
{
"client_id": "InfAsym",
"client_id_issued_at": 1768977749,
"token_endpoint_auth_method": "private_key_jwt",
"grant_types": [
"authorization_code",
"refresh_token"
],
"response_types": [
"code"
],
"client_name": "Drummond Inferno Asymmetric Client",
"registration_access_token": "EEg6zaFFx0QnAB4fiouV8i2DzEjmhXHiitssFZZmwAE",
"registration_client_uri": "https://handle.url.com/register/InfAsym",
"redirect_uris": [
"https://inferno.healthit.gov/suites/custom/smart/redirect"
],
"client_secret": "_UY8R9rs1iiKblyUw-sS1o_hPzBI4Zx2Q_2GXu5_EDc",
"client_secret_expires_at": 0,
"jwks_uri": "https://inferno.healthit.gov/.well-known/jwks.json",
"launch_uri": "https://inferno.healthit.gov/suites/custom/smart/launch",
"client_uri": "https://inferno.healthit.gov/suites",
"scope": "launch/patient openid fhirUser offline_access patient/*.rs"
}
Bulk Client
curl -s -X POST "https://handle.url.com/register" \
-H "Content-Type: application/json" \
-d '{
"client_id": "BulkFHIR",
"token_endpoint_auth_method": "private_key_jwt",
"grant_types": ["client_credentials"],
"client_name": "Drummond Inferno Bulk Data Client",
"client_uri": "https://inferno.healthit.gov/suites",
"scope": "system/*.rs",
"jwks_uri": "https://inferno.healthit.gov/.well-known/jwks.json"
}'
Response:
{
"client_id": "BulkFHIR",
"client_id_issued_at": 1769115078,
"token_endpoint_auth_method": "private_key_jwt",
"grant_types": [
"client_credentials"
],
"response_types": [
"code"
],
"client_name": "Drummond Inferno Bulk Data Client",
"registration_access_token": "TMD-tfvZI3EtDzbeXiiEmrTSQZ0JIZ7cGub3GSHjDVU",
"registration_client_uri": "https://handle.url.com/register/BulkFHIR",
"client_secret": "RIsehuJPuOYF23jH8jPvK2RCE4A4y0kNjb0aDP0RhMM",
"client_secret_expires_at": 0,
"jwks_uri": "https://inferno.healthit.gov/.well-known/jwks.json",
"client_uri": "https://inferno.healthit.gov",
"scope": "system/*.rs"
}
Applications can also be registered within the Login Trusts editor within the EHR. Contact your implementation specialist for assistance as it requires special permissions to add Login Trusts to a system.
If you have access to the Login Trust screens in your system, use the information below for 3rd party endpoints:
Manually Creating a 3rd party endpoint for FHIR in WebChart
FHIR App Editor
A more FHIR-centric editor also exists:
As well as a complete listing of the available FHIR apps for the system:
And additional metadata about the auto-registered applications:
Legacy Editor
Example screenshot of Create/Edit Login Trust in webchart:
Note: The “allowed options” does not have the checkbox for FHIR. SQL is required to enable FHIR.
Patient Standalone Launch
Registered applications can utilize the OAuth 2.0 authorization code workflow in order to access the EHR.
Utilizing applications conforming to the SMART launch workflow, users will be directed to the EHR’s Scope confirmation page.
Scopes
Typical scope for patients would be:
var authURL = oauth2.getAuthorizeUrl({
response_type: 'code', // Explicitly specify the response type
redirect_uri: 'http://localhost:8080/code',
scope: 'launch/patient openid fhirUser offline_access patient/*.rs',
aud: 'https://fhirr4sandbox.fhir.webch.art/' // Add the correct audience
});
- launch/patient: Indicates the app is launched by a patient and intends to retrieve patient-specific data.
- openid: Required for OpenID Connect to authenticate the user and issue an ID token.
- fhirUser: Allows the app to access FHIR resources associated with the user.
- offline_access: Enables the app to request refresh tokens for long-term access to data.
- patient/*.rs: Grants read access to all FHIR resources related to the patient.
Example app: https://github.com/mieweb/webchart-oauth-example
On this page, individual accesses may be customized or denied altogether.
By clicking on the item, it will turn “grey” indicated access to that resource will be DENIED. The first four (launch/patient openid fhirUser offline_access) are mandatory and cannot be denied.
If allowed, the application will then be permitted to access the user’s data via the FHIR API.
Physician EHR Launch
The Quickview contains a FHIR Launch portlet which allows launching configured applications.
Navigate to the Quickview sidemenu tab
Open the Select Portlets manager
Utilizing the links to the configured applications present in the FHIR Launch portlet will allow EHR Practitioner access to those applications.
JWT created:
SMART Bulk Backend Services
Applications may utilize the FHIR Backend Services for bulk workflow order to consume EHR resources.
Management of Interfaces
Revocation of Access
Admins may revoke access to any applications previously granted access via the Token Administration tool.
URL: ?f=layout&module=Login&name=OAuthCodes
JWKS
https://fhirr4sandbox.fhir.webch.art/jwks
JWKS (JSON Web Key Sets): https://datatracker.ietf.org/doc/html/rfc7517#appendix-A
Manual Server Setup
While automatic App Registration via RFC 7591/7592 is the preferred method, apps may be registered manually.
Key Generation
Application registration begins with generating a unique cryptographic key for the application. These keys will be used for each of the individual app types.
$ openssl genrsa -out mykey.pem 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
........................+++++
.......................................................+++++
e is 65537 (0x010001)
$ openssl rsa -in mykey.pem -pubout
writing RSA key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvqTVtATjtY+gsbrbdZul
SwazoGNNJ3WoxjR2i2zZ+U8GhIWhKNdJJ/X4VuEaBKg1428JhAQ1+D35DywZyI9W
RcLLXeUWGnw+qJ04ZTQ7TZn8sP9oia++FRAdMKVGoN6Kw6Q/glHfhKDlxsp/UYtj
hai5ZqNBjMSgT6cLoq+HBeVrDgme7AZn00ur4YoYx49CvQXCSzQWX8gnsbkOMdts
epcpUTQ3XAj34ijjE+0sbzMTKD6ldb1Xzp7QGRXhsqt6bUqxBwaIm+S7iY/WLYA2
0q4bY+KpPmfRVslzIvCJx4PTS3qfko4brAxEZC/SxbOYmONN7K2xn9oYrmVKAZd6
7QIDAQAB
-----END PUBLIC KEY-----
Asymmetric Client (JWKS-based)
INSERT INTO
login_trusts (
domain, -- Client ID
description, -- Display name
allowed_options, -- OAuth flag
logout_url, -- launch_uri (optional)
login_fail_url, -- jwks_uri
private_key, -- Empty for asymmetric
public_key, -- Client's public key (optional if jwks_uri provided)
key_format, -- 'JWKS'
encryption_public_key, -- AS's RSA public key
encryption_private_key, -- AS's RSA private key
encryption_key_format -- 'PEM' for AS keys
)
VALUES
(
'AsymmetricApp',
'Example Asymmetric FHIR App',
8388608,
'https://app.example.com/launch',
'https://app.example.com/.well-known/jwks.json',
'', -- No client_secret for asymmetric
'', -- Public key fetched from JWKS URI
'JWKS',
'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvqTVtATjtY+gsbrbdZul\nSwazoGNNJ3WoxjR2i2zZ+U8GhIWhKNdJJ/X4VuEaBKg1428JhAQ1+D35DywZyI9W\nRcLLXeUWGnw+qJ04ZTQ7TZn8sP9oia++FRAdMKVGoN6Kw6Q/glHfhKDlxsp/UYtj\nhai5ZqNBjMSgT6cLoq+HBeVrDgme7AZn00ur4YoYx49CvQXCSzQWX8gnsbkOMdts\nepcpUTQ3XAj34ijjE+0sbzMTKD6ldb1Xzp7QGRXhsqt6bUqxBwaIm+S7iY/WLYA2\n0q4bY+KpPmfRVslzIvCJx4PTS3qfko4brAxEZC/SxbOYmONN7K2xn9oYrmVKAZd6\n7QIDAQAB\n-----END PUBLIC KEY-----',
'-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAvqTVtATjtY+gsbrbdZulSwazoGNNJ3WoxjR2i2zZ+U8GhIWh\nKNdJJ/X4VuEaBKg1428JhAQ1+D35DywZyI9WRcLLXeUWGnw+qJ04ZTQ7TZn8sP9o\nia++FRAdMKVGoN6Kw6Q/glHfhKDlxsp/UYtjhai5ZqNBjMSgT6cLoq+HBeVrDgme\n7AZn00ur4YoYx49CvQXCSzQWX8gnsbkOMdtsepcpUTQ3XAj34ijjE+0sbzMTKD6l\ndb1Xzp7QGRXhsqt6bUqxBwaIm+S7iY/WLYA20q4bY+KpPmfRVslzIvCJx4PTS3qf\nko4brAxEZC/SxbOYmONN7K2xn9oYrmVKAZd67QIDAQABAoIBAHdHUp3rYT07u+L3\nck/HLkgezUxQVPmXWB2KvZDGbiraEs3ffdG7wP3Lm7Ff7ZN0WyMNWfrLV6kVvTqM\n8STW6beEBRGeP5IaommE1MAdSe1npv5nDtT2rAsppdnFzsbf9hoqLcIvz5V/xcP2\n9mniuEXsJvPcuSqF63dqoJENGYHJ0BsKUYUQkVtMDo2gQ5EX5wV1VeVndH7P5eBI\nh3/ZYzct2RdGlA7gY4fLmF6wegJUP8GfQqW7EfqcqK6pBmI4A4tKuIRqPVlRy3yf\nZhMjF2u8dqvFf+azcbvYYgPwSGi9Rlgvc2xmB7nczVStAfZgKyDdFLcPhH0Wcag0\nYRlYB4ECgYEA3c3+sUQm6FWcbyI6tyxbVpAxQqV15rUKI+NyspSwtqyRVhDZ7HIs\nz43EizlXWXlofZIkoQf87HiAKhTypIeCfkKNLEvXPT2rhCIbF+PH63Y/ZEfepdYZ\ndr8YVwbsrJZyzdAo9VzOQUoJ4Lpmk1A5WzFlYe7ugB+elPGfUJLisiUCgYEA3AkC\n+76V6XP2DLagdjNeIGKx6jDcKsh1NrmU/+9fe/0EAB8D/VASiLmWtomxHYmX7PsT\nBevBa4aTgJxQQlFapUokdYcl/k24uXMGi3oJJDxEi6eW9R8dIQioQfd9bmd/W84L\nPjOxSvzQkqdMlx5blqCBG8n527B2W/asZMgHNykCgYEArldxf3J7RpmsSWpVTo9O\nB/90yNb3kmzw2H66NAZN1HhWEJlUQdcIw+fB+lELCKg2aqVJp015D4Iz81/dzVc6\nSfYTsyK1v0xPGaAZPbDr/ndGopMfPajJAR55ikZGF+51tLKOzzWwZX9Fvl+lqtsf\nCkAMWWsOCqVP5/D38cRS7gUCgYEAj2pgQ22pkIxAp3CxjdlVVI5/oEFQf6JAo/a6\nI0cGWW5EmT+d/hGewvcUQM3mX3Y7S/8qGwXbABarNXys40zbZDi7Is9/+Az4hgdv\nEKHuK2wM0Wnefs5U0h8ubDC/1KIo5NGbimNu/41g9PWOekETOU5MWKyA6qxNuQtC\nuj2WVmECgYEAni0m8n4P2wgs0w0Rm38/UxmAY7rBgFqpVqni8x3ASNUOujkosXYc\nCTR+MANXfp/VcvjvoCIP5M9/I/vLRGkv51nR9+8dgj17uzK6WWZ7UmAzW0K3Tuxj\nlLBDRTY4xzreE/oCFQXIQ7843qC3sBwvAMbzR6n2TZkC1iaucbXiiWU=\n-----END RSA PRIVATE KEY-----',
'PEM'
);
-- Store redirect URIs in translations table
INSERT INTO login_trusts_translations (domain, trans_type, trans_from, trans_to)
VALUES ('AsymmetricApp', 5, 'redirect_uri', 'https://app.example.com/redirect');
Public Client (PKCE)
INSERT INTO
login_trusts
(
domain,
description,
allowed_options,
logout_url,
login_fail_url,
private_key,
key_format,
encryption_public_key,
encryption_private_key,
encryption_key_format
)
VALUES
(
'MobileApp',
'Example Mobile FHIR App',
8388608,
'myapp://launch',
'', -- No JWKS for PKCE clients
'', -- No client_secret for public clients
'PKCE',
'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvqTVtATjtY+gsbrbdZul\nSwazoGNNJ3WoxjR2i2zZ+U8GhIWhKNdJJ/X4VuEaBKg1428JhAQ1+D35DywZyI9W\nRcLLXeUWGnw+qJ04ZTQ7TZn8sP9oia++FRAdMKVGoN6Kw6Q/glHfhKDlxsp/UYtj\nhai5ZqNBjMSgT6cLoq+HBeVrDgme7AZn00ur4YoYx49CvQXCSzQWX8gnsbkOMdts\nepcpUTQ3XAj34ijjE+0sbzMTKD6ldb1Xzp7QGRXhsqt6bUqxBwaIm+S7iY/WLYA2\n0q4bY+KpPmfRVslzIvCJx4PTS3qfko4brAxEZC/SxbOYmONN7K2xn9oYrmVKAZd6\n7QIDAQAB\n-----END PUBLIC KEY-----',
'-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAvqTVtATjtY+gsbrbdZulSwazoGNNJ3WoxjR2i2zZ+U8GhIWh\nKNdJJ/X4VuEaBKg1428JhAQ1+D35DywZyI9WRcLLXeUWGnw+qJ04ZTQ7TZn8sP9o\nia++FRAdMKVGoN6Kw6Q/glHfhKDlxsp/UYtjhai5ZqNBjMSgT6cLoq+HBeVrDgme\n7AZn00ur4YoYx49CvQXCSzQWX8gnsbkOMdtsepcpUTQ3XAj34ijjE+0sbzMTKD6l\ndb1Xzp7QGRXhsqt6bUqxBwaIm+S7iY/WLYA20q4bY+KpPmfRVslzIvCJx4PTS3qf\nko4brAxEZC/SxbOYmONN7K2xn9oYrmVKAZd67QIDAQABAoIBAHdHUp3rYT07u+L3\nck/HLkgezUxQVPmXWB2KvZDGbiraEs3ffdG7wP3Lm7Ff7ZN0WyMNWfrLV6kVvTqM\n8STW6beEBRGeP5IaommE1MAdSe1npv5nDtT2rAsppdnFzsbf9hoqLcIvz5V/xcP2\n9mniuEXsJvPcuSqF63dqoJENGYHJ0BsKUYUQkVtMDo2gQ5EX5wV1VeVndH7P5eBI\nh3/ZYzct2RdGlA7gY4fLmF6wegJUP8GfQqW7EfqcqK6pBmI4A4tKuIRqPVlRy3yf\nZhMjF2u8dqvFf+azcbvYYgPwSGi9Rlgvc2xmB7nczVStAfZgKyDdFLcPhH0Wcag0\nYRlYB4ECgYEA3c3+sUQm6FWcbyI6tyxbVpAxQqV15rUKI+NyspSwtqyRVhDZ7HIs\nz43EizlXWXlofZIkoQf87HiAKhTypIeCfkKNLEvXPT2rhCIbF+PH63Y/ZEfepdYZ\ndr8YVwbsrJZyzdAo9VzOQUoJ4Lpmk1A5WzFlYe7ugB+elPGfUJLisiUCgYEA3AkC\n+76V6XP2DLagdjNeIGKx6jDcKsh1NrmU/+9fe/0EAB8D/VASiLmWtomxHYmX7PsT\nBevBa4aTgJxQQlFapUokdYcl/k24uXMGi3oJJDxEi6eW9R8dIQioQfd9bmd/W84L\nPjOxSvzQkqdMlx5blqCBG8n527B2W/asZMgHNykCgYEArldxf3J7RpmsSWpVTo9O\nB/90yNb3kmzw2H66NAZN1HhWEJlUQdcIw+fB+lELCKg2aqVJp015D4Iz81/dzVc6\nSfYTsyK1v0xPGaAZPbDr/ndGopMfPajJAR55ikZGF+51tLKOzzWwZX9Fvl+lqtsf\nCkAMWWsOCqVP5/D38cRS7gUCgYEAj2pgQ22pkIxAp3CxjdlVVI5/oEFQf6JAo/a6\nI0cGWW5EmT+d/hGewvcUQM3mX3Y7S/8qGwXbABarNXys40zbZDi7Is9/+Az4hgdv\nEKHuK2wM0Wnefs5U0h8ubDC/1KIo5NGbimNu/41g9PWOekETOU5MWKyA6qxNuQtC\nuj2WVmECgYEAni0m8n4P2wgs0w0Rm38/UxmAY7rBgFqpVqni8x3ASNUOujkosXYc\nCTR+MANXfp/VcvjvoCIP5M9/I/vLRGkv51nR9+8dgj17uzK6WWZ7UmAzW0K3Tuxj\nlLBDRTY4xzreE/oCFQXIQ7843qC3sBwvAMbzR6n2TZkC1iaucbXiiWU=\n-----END RSA PRIVATE KEY-----',
'PEM'
);
-- Store multiple redirect URIs (mobile apps often have both deep link and universal link)
INSERT INTO login_trusts_translations (domain, trans_type, trans_from, trans_to)
VALUES
('MobileApp', 5, 'redirect_uri', 'myapp://callback'),
('MobileApp', 5, 'redirect_uri', 'https://app.example.com/mobile-callback');
Confidential Client (Secret + optional PKCE)
INSERT INTO
login_trusts
(
domain,
description,
allowed_options,
logout_url,
private_key,
key_format,
encryption_public_key,
encryption_private_key,
encryption_key_format
)
VALUES
(
'BackendService',
'Example Backend FHIR Service',
8388608,
'https://backend.example.com/launch',
'BACKEND_SECRET_123',
'SECRET', -- Client can optionally use PKCE at runtime for defense-in-depth
'-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvqTVtATjtY+gsbrbdZul\nSwazoGNNJ3WoxjR2i2zZ+U8GhIWhKNdJJ/X4VuEaBKg1428JhAQ1+D35DywZyI9W\nRcLLXeUWGnw+qJ04ZTQ7TZn8sP9oia++FRAdMKVGoN6Kw6Q/glHfhKDlxsp/UYtj\nhai5ZqNBjMSgT6cLoq+HBeVrDgme7AZn00ur4YoYx49CvQXCSzQWX8gnsbkOMdts\nepcpUTQ3XAj34ijjE+0sbzMTKD6ldb1Xzp7QGRXhsqt6bUqxBwaIm+S7iY/WLYA2\n0q4bY+KpPmfRVslzIvCJx4PTS3qfko4brAxEZC/SxbOYmONN7K2xn9oYrmVKAZd6\n7QIDAQAB\n-----END PUBLIC KEY-----',
'-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEAvqTVtATjtY+gsbrbdZulSwazoGNNJ3WoxjR2i2zZ+U8GhIWh\nKNdJJ/X4VuEaBKg1428JhAQ1+D35DywZyI9WRcLLXeUWGnw+qJ04ZTQ7TZn8sP9o\nia++FRAdMKVGoN6Kw6Q/glHfhKDlxsp/UYtjhai5ZqNBjMSgT6cLoq+HBeVrDgme\n7AZn00ur4YoYx49CvQXCSzQWX8gnsbkOMdtsepcpUTQ3XAj34ijjE+0sbzMTKD6l\ndb1Xzp7QGRXhsqt6bUqxBwaIm+S7iY/WLYA20q4bY+KpPmfRVslzIvCJx4PTS3qf\nko4brAxEZC/SxbOYmONN7K2xn9oYrmVKAZd67QIDAQABAoIBAHdHUp3rYT07u+L3\nck/HLkgezUxQVPmXWB2KvZDGbiraEs3ffdG7wP3Lm7Ff7ZN0WyMNWfrLV6kVvTqM\n8STW6beEBRGeP5IaommE1MAdSe1npv5nDtT2rAsppdnFzsbf9hoqLcIvz5V/xcP2\n9mniuEXsJvPcuSqF63dqoJENGYHJ0BsKUYUQkVtMDo2gQ5EX5wV1VeVndH7P5eBI\nh3/ZYzct2RdGlA7gY4fLmF6wegJUP8GfQqW7EfqcqK6pBmI4A4tKuIRqPVlRy3yf\nZhMjF2u8dqvFf+azcbvYYgPwSGi9Rlgvc2xmB7nczVStAfZgKyDdFLcPhH0Wcag0\nYRlYB4ECgYEA3c3+sUQm6FWcbyI6tyxbVpAxQqV15rUKI+NyspSwtqyRVhDZ7HIs\nz43EizlXWXlofZIkoQf87HiAKhTypIeCfkKNLEvXPT2rhCIbF+PH63Y/ZEfepdYZ\ndr8YVwbsrJZyzdAo9VzOQUoJ4Lpmk1A5WzFlYe7ugB+elPGfUJLisiUCgYEA3AkC\n+76V6XP2DLagdjNeIGKx6jDcKsh1NrmU/+9fe/0EAB8D/VASiLmWtomxHYmX7PsT\nBevBa4aTgJxQQlFapUokdYcl/k24uXMGi3oJJDxEi6eW9R8dIQioQfd9bmd/W84L\nPjOxSvzQkqdMlx5blqCBG8n527B2W/asZMgHNykCgYEArldxf3J7RpmsSWpVTo9O\nB/90yNb3kmzw2H66NAZN1HhWEJlUQdcIw+fB+lELCKg2aqVJp015D4Iz81/dzVc6\nSfYTsyK1v0xPGaAZPbDr/ndGopMfPajJAR55ikZGF+51tLKOzzWwZX9Fvl+lqtsf\nCkAMWWsOCqVP5/D38cRS7gUCgYEAj2pgQ22pkIxAp3CxjdlVVI5/oEFQf6JAo/a6\nI0cGWW5EmT+d/hGewvcUQM3mX3Y7S/8qGwXbABarNXys40zbZDi7Is9/+Az4hgdv\nEKHuK2wM0Wnefs5U0h8ubDC/1KIo5NGbimNu/41g9PWOekETOU5MWKyA6qxNuQtC\nuj2WVmECgYEAni0m8n4P2wgs0w0Rm38/UxmAY7rBgFqpVqni8x3ASNUOujkosXYc\nCTR+MANXfp/VcvjvoCIP5M9/I/vLRGkv51nR9+8dgj17uzK6WWZ7UmAzW0K3Tuxj\nlLBDRTY4xzreE/oCFQXIQ7843qC3sBwvAMbzR6n2TZkC1iaucbXiiWU=\n-----END RSA PRIVATE KEY-----',
'PEM'
);
-- Store redirect URI
INSERT INTO login_trusts_translations (domain, trans_type, trans_from, trans_to)
VALUES ('BackendService', 5, 'redirect_uri', 'https://backend.example.com/oauth/callback');
References
https://en.wikipedia.org/wiki/OpenID#OpenID_Connect_(OIDC)


