Authentication

Use the EHR authentication API to exchange an access token issued by your identity provider for an access token usable by Dragon Copilot for authenticating with its backend services.

Create the EHR authentication client

Create an instance of EhrAuthenticationClient with the required configuration. You'll need to pass a different configuration depending on your authentication flow.

If you're using Microsoft Entra ID as your identity provider, customerId is required. See Dragon Copilot access token requirements using Microsoft Entra.

If you're using an alternative identity provider, customerId isn't required because it's sourced from a custom claim instead. See Dragon Copilot access token requirements using alternative identity providers.

const client = new DragonCopilotSDK.dragon.authentication.ehr.EhrAuthenticationClient({
  productId: "<your-product-id>",
});
Property Type Required Description
customerId String No The unique identifer for the customer. Required when the partner is using Entra ID tokens.
productId String No The product ID used to generate the EHR token.

Initialize the SDK

When initializing the SDK, pass your implementation of the acquireAccessToken callback. For implementation details, see Token acquisition.

async function acquireToken() {
  // Left blank for brevity.
}

DragonCopilotSDK.dragon.initialize({
  // Other initialization options...
  services: "us",
  authentication: {
    acquireAccessToken: acquireToken,
  },
});

Token acquisition

Note

This API can only be called in a secure context.

You'll pass your access token to every acquireToken call. This is to ensure proper cache lookups. If you need to change your access token because it expired or for any other reason, pass the new token to acquireToken.

const result = await client.acquireToken({
  accessToken: "partner-issued-access-token",
});

Parameters

Property Type Required Description
accessToken String Yes Your access token.

Response

On success, acquireToken() returns an AcquireTokenResult object:

type AcquireTokenResult = {
  accessToken: string;
  expiresOn: Date;
};

Token caching

The Dragon Copilot SDK caches tokens in the browser's session storage, hashed using SHA-512. This prevents unnecessary network requests when the same token is requested multiple times.

The cached token is invalidated when the browser tab/window closes and when the token expires. Expired tokens are automatically removed from the cache.

Error handling

For information on integration errors, see Error handling.

If an error occurs during the token exchange, a DragonCopilotSDK.dragon.authentication.ehr.EhrAuthenticationError error is thrown.

Error Code Description Suggested action
unauthorized Authentication failed (401 or 403 error). Verify the access token is valid.
token_exchange_failed Token exchange request failed. Check network connectivity and service availability.

The subError field provides the following additional context from the EHR integration service:

  • For HTTP errors: Includes status code and status text.

  • For a subset of HTTP errors (400, 500): Includes an additional error code and description.

    Example subError values:

    ["401: Unauthorized"]
    ["500: Internal Server Error", "server_error: Failed to generate token"]
    ["400: Bad Request", "HmsUserFetchError: Failed to retrieve user details from the HMS"]

Best practices

When implementing the EHR authentication client API, we recommend the following:

  • Reuse client instances. Create one EhrAuthenticationClient per configuration and reuse it throughout your application's lifecycle.

  • Don't cache the token returned by acquireToken. Let the Dragon Copilot SDK handle token caching.

  • Handle token expiration. Make sure your access token doesn't expire before you call acquireToken.

Sample code

Using an access token from Microsoft Entra ID:

const client = new DragonCopilotSDK.dragon.authentication.ehr.EhrAuthenticationClient({
  customerId: "customer-id",
});

// The partner's callback implementation
async function acquireToken(scope: string) {
  // Entra ID tokens are issued using MSAL, and should use the scope provided by the SDK when `ehrScoped` is used.
  const partnerToken = await acquireMsalToken(scope)

  return await client.acquireToken({
    accessToken: partnerToken,
  });
}

// Pass the callback into DragonCopilotSDK.dragon.initialize
DragonCopilotSDK.dragon.initialize({
  // Other initialization options...
  services: "us",
  authentication: {
    acquireAccessToken: acquireToken,
    scopeBehavor: "ehrScoped", // This is the default behavior, explicitly set for demonstration purposes.
  },
});

Using an access token from an alternative identity provider:

const client = new DragonCopilotSDK.dragon.authentication.ehr.EhrAuthenticationClient();

// The partner's callback implementation
async function acquireToken() {
  // Ensure the partner issued token is still valid to avoid unnecessary errors.
  const partnerToken = await acquirePartnerToken();

  return await client.acquireToken({
    accessToken: partnerToken,
  });
}

// Pass the callback into DragonCopilotSDK.dragon.initialize
DragonCopilotSDK.dragon.initialize({
  // Other initialization options...
  services: "us",
  authentication: {
    acquireAccessToken: acquireToken,
  },
});

See also

API reference