Create Integrated Applications for DDFS OAuth

Create the OCI Identity Domain applications that a service-to-service client uses to obtain an OAuth access token for Device Data FHIR Service (DDFS).

Configure one confidential application as the DDFS resource server and a separate confidential application for each calling service. This procedure uses the OAuth 2.0 client credentials grant with JWT client assertion authentication and grants only the FHIR resource scopes required by the client.

Before You Begin

  • Confirm that you have administrator access to the identity domain that you want to use for DDFS. To create a domain, see Creating an Identity Domain. To use an existing domain, see Getting an Identity Domain's Details.
  • Identify the DDFS FHIR resources and operations that the client requires. Grant only the minimum required scopes.
  • Before configuring the client application, obtain a public certificate and its matching private key by using your organization's approved certificate-management process. See Importing a Trusted Partner Certificate.
  • Create a DDFS instance or get a DDFS instance details to obtain the version-specific FHIR API base URL for the DDFS instance that the client calls.

    For example:

    https://<ddfs-instance-id>.ddfs.<region>.oci.oraclecloud.com/api/fhir/r4
    or
    https://<ddfs-instance-id>.ddfs.<region>.oci.oraclecloud.com/api/fhir/r6-ballot4

The setup uses two confidential applications:

ApplicationPurposeExample Scope
DDFS resource serverRepresents the protected DDFS FHIR API and defines the scopes that clients can request.system/Device.rs
Client applicationRepresents one application or service that calls DDFS and receives only the scopes required by that caller.ddfssystem/Device.rs

For the complete scope syntax and context mapping, see Where Scopes Are Configured and Requested.

Step 1: Prepare the Identity Domain

  1. Open the navigation menu, and select Identity & Security. Under Identity, select Domains.
  2. Select the identity domain that you want to use for DDFS.
  3. On the Domain details page, on the top navigation scroll to the right and select Settings.
  4. Under Domain settings - Locale select Edit domain settings.
  5. Under Access signing certificate, turn on Configure client access, and then save the changes.
  6. Return to the Domain details page, and select Integrated applications.

Identity Domains publishes the public signing keys at this endpoint:

https://<identity-domain>/admin/v1/SigningCert/jwk

DDFS retrieves these public signing keys automatically to validate access-token signatures. The root-certificate download, PEM-file creation, and federation-partner installation steps are not part of this DDFS setup.

Step 2: Create and Activate the DDFS Resource Server

  1. On the Integrated applications page, select Add application.
  2. Select Confidential Application, and select Launch workflow.
  3. Enter a name and description that identify this application as the DDFS resource server, and Submit the application. Avoid entering confidential information.
  4. On the application details page, select Actions and then Activate the resource server application.
  5. Select OAuth configuration, and then Edit the OAuth configuration.
  6. Under Resource server configuration select Configure this application as a resource server now.
  7. Turn on the option to Allow token refresh.
  8. In Primary audience, enter the exact lowercase value ddfs.
  9. Turn on the option to Add Scopes.
  10. Select Add to add a Scope for each operation needed by the calling application, enter only the canonical DDFS scopes needed by the calling applications. For example, add system/Device.rs for Device read and search access or add system/Device.* for access to all device operations. Or you can add system/*.* for access to all operations for all resources.

    To define specific access to supported resources, see Scope Configuration Reference for a list of resource names, operation letters, client scope forms, Subscription status requirements, and administrative scopes required for hard delete operations.

  11. Optionally, enter a display name or description for each scope.
  12. Select Add and then Submit to save the OAuth configuration.

Step 3: Create and Activate the Client Application

  1. Return to the Integrated applications page for the DDFS domain, select Add application.
  2. Select Confidential Application, and select Launch workflow.
  3. Enter a name and description that identify the application or service that calls DDFS, and select Submit to create the application. Create a separate client application for each independently managed caller.
  4. On the application's details page, select OAuth configuration, and then select Edit OAuth configuration, to configure it as a client.
  5. Under Client Configuration, select the option to Configure this application as a Client now and then Submit.
  6. Under Authorization, select Client credentials as the OAuth grant type for this service to service workflow; it is not a username and password sign in flow.
  7. Under Token issuance Policy turn on the option, to Add resources so that you can add the DDFS resource server as an authorized resource.
  8. Select Add Scope, now you can see the scopes setup previously for the resource server, select the checkbox next to the scopes you want to add, and then select Add and then select Submit to save the OAuth configuration.

    Grant only the client-facing DDFS scopes required by this caller. For example, grant ddfssystem/Device.rs when the client reads and searches Device resources or to grant the client access to all device operations, select ddfssystem/Device.*

  9. On the application details page, select the Actions menu and then select Activate. Confirm the client application displays an Active status.
  10. Select Settings and then select Trusted partner certificates.
  11. Under Security, select Trusted Partner Certificates.
  12. Select Import certificate, and import the public certificate that corresponds to the client's protected private key.

The private key remains with the calling application and is not uploaded to Identity Domains. The application uses the private key to sign each short-lived JWT client assertion sent with an access-token request.

Step 4: Collect the Token Request Values

Collect the following values without placing credentials or private key material in source control, logs, support tickets, or documentation.

ValueSource
DOMAIN_URLThe base URL of the identity domain that contains both integrated applications, for example https://idcs-xxxxxxxx.identity.oraclecloud.com.
CLIENT_IDThe client ID on the confidential client application's details page.
CLIENT_ASSERTIONA new short-lived JWT assertion signed with the client's protected private key. Generate it immediately before the token request.
SCOPEThe client-facing scopes granted to the client application, such as ddfssystem/Device.rs. Separate multiple scopes with a space.
FHIR_API_BASE_URLThe complete version-specific FHIR API base URL from the DDFS instance details, such as https://<ddfs-instance-id>.ddfs.<region>.oci.oraclecloud.com/api/fhir/r4 or https://<ddfs-instance-id>.ddfs.<region>.oci.oraclecloud.com/api/fhir/r6-ballot4.

Step 5: Request an OAuth Access Token

Request a token from the identity domain by using the client credentials grant and a freshly generated JWT client assertion. The SCOPE value must contain only scopes already granted to the client application.

Treat the returned access token as a credential. Do not log it, retain it longer than required, or paste it into a support ticket.

  • curl -sS -X POST "${DOMAIN_URL}/oauth2/v1/token" \
      -H "Content-Type: application/x-www-form-urlencoded;charset=UTF-8" \
      --data-urlencode "grant_type=client_credentials" \
      --data-urlencode "client_id=${CLIENT_ID}" \
      --data-urlencode "client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer" \
      --data-urlencode "client_assertion=${CLIENT_ASSERTION}" \
      --data-urlencode "scope=${SCOPE}"
  • $body = @{
      grant_type = "client_credentials"
      client_id = $CLIENT_ID
      client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
      client_assertion = $CLIENT_ASSERTION
      scope = $SCOPE
    }
    
    $response = Invoke-RestMethod -Method Post `
      -Uri "$DOMAIN_URL/oauth2/v1/token" `
      -ContentType "application/x-www-form-urlencoded;charset=UTF-8" `
      -Body $body
    
    $ACCESS_TOKEN = $response.access_token

Step 6: Call the DDFS FHIR API

Send the access token in the HTTP Authorization header when calling a protected DDFS FHIR endpoint:

Authorization: Bearer <access_token>

For example, a client with Device read permission can retrieve a Device resource:

curl -sS "${FHIR_API_BASE_URL}/Device/${DEVICE_ID}" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Accept: application/fhir+json"

Use the access token only with requests authorized by its granted scopes. Do not decode the token as part of the normal client workflow.

Result

The active client application can request an OAuth access token for its granted DDFS scopes and use that token to call the corresponding protected FHIR endpoints.

Troubleshooting

ProblemPossible CauseAction
The DDFS resource server is not available when configuring the client.The applications are in different identity domains, or the resource server is not active.Confirm that both applications are in the same identity domain and that the resource server status is Active.
The token request does not authenticate the client.The client assertion is expired, has the wrong token endpoint audience, or was not signed by the key associated with the registered public certificate.Generate a new short-lived assertion, verify the token endpoint and client ID, and confirm that the registered public certificate matches the protected signing key.
The token request reports an invalid or unauthorized scope.The scope is not defined on the resource server, is not granted to the client, uses the wrong context form, or was not form-URL-encoded.Define the canonical system/... scope on the resource server, grant and request the corresponding ddfssystem/... form, and form-URL-encode the complete scope parameter value.
DDFS returns HTTP 401.The access token is missing, expired, malformed, or not issued for the configured DDFS identity domain and audience.Request a new token from the configured identity domain and send it once in the Authorization: Bearer header. Do not include the token in diagnostic records.
DDFS returns HTTP 403.The token is valid but does not grant the resource and operation required by the request.Compare the requested FHIR interaction with the client's granted scopes. Grant and request only the missing least-privilege scope.

For general API diagnostics, see Troubleshooting.

FAQs

Why are two integrated applications required?
The resource server represents the protected DDFS FHIR API and defines available scopes. The client application represents one caller and receives only the scopes that caller requires.
When do I activate the applications?
Activate each application after saving its OAuth configuration. The resource server must be active before you grant its scopes to the client, and the client must be active before it requests a token.
Why does this procedure use a JWT client assertion?
A JWT client assertion lets the confidential client prove possession of its private key without sending that private key to Identity Domains. The assertion is still short-lived credential material and must not be logged or reused.
How are the identity-domain signing certificate, client authentication certificate, and Subscription secret different?
  1. Identity-domain access-signing configuration: In Step 1, enable access to the identity domain's signing certificate. This allows DDFS to obtain the identity domain's public signing keys and validate issued access tokens. DDFS retrieves the keys automatically; you don't create or upload the client authentication key pair, download a root certificate, or install a certificate at a federation partner in this step.
  2. Client authentication key pair: Obtain a public certificate and matching private key by using your organization's approved process. In Step 3, configure the confidential application as a client, select the Client Credentials grant and Trusted Client, and import the public certificate. The private key remains with the calling application and signs each short-lived JWT client assertion. Adding a Confidential Application describes the general Identity Domains workflow and its available options; Step 3 identifies the selections required for DDFS.
  3. Subscription secret: The OCI Vault secret for R6 Subscription notification authorization is separate and optional. It is used only when an R6 REST-hook endpoint requires an outbound Authorization header and is unrelated to the access-token request made by the calling application.
Do I need to decode the access token?
No. After Identity Domains returns the token, send it to DDFS in the Authorization: Bearer <access_token> header. Decode tokens only as part of an approved diagnostic process, and never disclose a live token.
Does this configure SMART on FHIR authorization?
No. DDFS uses OAuth scopes issued by OCI Identity Domains and does not provide SMART launch or SMART user and patient authorization scopes.

Optional Hard-Delete Authorization

Configure hard-delete authorization only for an administrative workflow that must call $hardDelete or $purgeDeleted. These operations require a matching resource delete scope and the custom hard-delete scope. For the exact resource-server and client values, see Custom Hard-Delete Scope.