Mutual TLS Testing Setup Guide

Overview

This guide explains how to set up and test the Mutual TLS (mTLS) functionality in the DIBBs Query Connector.

Prerequisites

1. Obtain mTLS Certificates

You'll need a certificate and private key pair for mTLS authentication. These can be:

  • For Development/Testing: VAL environment certificates signed by the EMR Direct Certificate Authority
  • For Production: PROD environment certificates signed by the EMR Direct Certificate Authority

Getting Certificates

Follow the instructions from EMR Direct to obtain your mTLS certificates.

2. Certificate Placement

The application looks for certificates in two places:

  1. File System (preferred for development):

    • Place certificates in the keys/ directory at the project root
    • Files should be named:
      • mtls-cert.pem - Certificate file
      • mtls-key.pem - Private key file
  2. Environment Variables (preferred for production):

    • MTLS_CERT and MTLS_KEY must hold the base64-encoded PEM contents — not a file path. On first use they are decoded and written to the keys/ directory.
    • Encode each PEM file and set the variables, for example:
    export MTLS_CERT="$(base64 -w0 mtls-cert.pem)"
    export MTLS_KEY="$(base64 -w0 mtls-key.pem)"
    

Running Tests

Unit Tests

# Run all mTLS-related unit tests
npm run test:unit:file -- mtls

# Run specific test files (by path pattern)
npm run test:unit:file -- mtls-utils
npm run test:unit:file -- fhir-client-mtls

Integration Tests

# Run integration tests including mTLS functionality
npm run test:integration

End-to-End Tests

# Run the Playwright E2E suite (includes the mTLS scenarios in e2e/mtls.spec.ts)
npm run test:playwright

Manual Testing with eHealthExchange

1. Configure an mTLS-enabled FHIR Server

  1. Navigate to /fhirServers in the application
  2. Click "New server"
  3. Fill in server details:
    • Server name: "eHX VAL (mTLS)"
    • URL: https://fhir002val.ehealthexchange.org/ehx/1.0/r4/cdex
    • Endpoint Type: Choose how the server is queried (see below)
    • Auth Method: Mutual TLS
    • Custom Headers: Add any required headers (e.g. X-POU, X-DESTINATION)
  4. Click "Test connection" to verify
  5. Click "Add server" to save

Endpoint Type

The Endpoint Type controls which resource the connection check probes and how patient discovery is routed. It is independent of the auth method, so a mutual-TLS server can be any of the three types:

  • Standard FHIR – probes /Patient and uses a direct /Patient search for patient discovery.
  • Immunization Gateway – probes /Immunization. Patient discovery still uses the standard /Patient path, then immunization records are pulled with /Immunization?subject=Patient/{id}. Choose this for an eHealth Exchange immunization gateway (e.g. IZGUAT).
  • Fanout (Task) – probes /Task and performs TEFCA-style fanout discovery by POSTing a /Task resource and polling for child tasks.

Existing mutual-TLS servers were automatically migrated to Fanout (Task) to preserve their prior behavior. New servers default to Standard FHIR.

2. Test Patient Discovery

  1. Navigate to the main query page
  2. Fill in patient demographics
    • First Name: Rick943
    • Last Name: Prohaska837
    • DOB: 01-05-1963
    • Phone Number: 555-306-8493
    • State: MA
  3. Click "Advanced" and select your mTLS server
  4. Click "Search for patient"
  5. What happens next depends on the server's Endpoint Type:
    • Standard FHIR / Immunization Gateway — a direct /Patient search is issued, then clinical records (e.g. /Immunization) are queried for the matched patient.
    • Fanout (Task) — a /Task resource is POSTed, child tasks are polled to completion, and patient results are retrieved from the completed tasks.

Troubleshooting

Certificate Not Found Error

If you see "Mutual TLS certificate not found" error:

  1. Check that certificates exist in keys/ directory:

    ls -la keys/mtls-*
    
  2. Verify environment variables are set:

    echo $MTLS_CERT | head -n 1
    echo $MTLS_KEY | head -n 1
    
  3. Ensure certificates have correct permissions:

    chmod 600 keys/mtls-key.pem
    chmod 644 keys/mtls-cert.pem
    

Connection Refused

If the mTLS connection is refused:

  1. Verify the server actually requires mTLS
  2. Check that your certificate is trusted by the server
  3. Ensure the certificate CN or SAN matches what the server expects
  4. Try disabling certificate validation for testing (not recommended for production)

Task Polling Timeout

If tasks don't complete:

  1. Check the server's Task implementation
  2. Verify the server supports the Task profile being used
  3. Look for error messages in child tasks
  4. Check server logs for processing errors

Security Considerations

  1. Never commit certificates to version control

    • The keys dir has been added to .gitignore - keep it there!
    • Use environment variables in production
  2. Certificate Rotation

    • Plan for certificate expiration
    • Implement a process for updating certificates
    • Test certificate updates in a staging environment

Additional Resources