Healthcare document exchange - IHE, TEFCA, eHealth Exchange

SOAP 1.2, MTOM, WS-Addressing and signed SAML - the stack the IHE profiles mandate for TEFCA, eHealth Exchange and ePA.

The IHE profiles - XDS.b for document submission and retrieval, XCA for cross-community access, XUA for user assertions - are the technical foundation of the large document-exchange networks: TEFCA and eHealth Exchange in the United States, gematik's ePA in Germany, the Swiss EPD. Whichever network it is, the transport stack is the same because the underlying IHE volumes mandate it.

What the profiles mandate

RequirementWhere it comes fromThe Zato block
SOAP 1.2IHE ITI, Appendix VThe SOAP version dropdown
MTOM for documentsXDS.b (ITI-41, ITI-43)The MTOM checkbox
WS-Addressing headersIHE ITI, Appendix VThe WS-Addressing checkbox
A signed SAML assertion naming the requesting userXUA (ITI-40)A WS-Security definition in SAML mode with Sign
TLS, frequently mutualEach network's participation agreementThe connection's Security tab

Piecing it together

Step 1. Create the SAML definition under Security > WS-Security: mode SAML, the Issuer and Subject your network agreement assigns, Sign enabled, and the Signing key with its Signing certificate chain in the Crypto material tab.

Step 2. Create the outgoing connection under Connections > Outgoing > SOAP, pointing at the responding gateway. In the SOAP tab, set the version to 1.2 and enable both WS-Addressing and MTOM:

Step 3. In the Security tab, attach the SAML definition - and when the network requires mutual TLS, fill in the client certificate paths on the same tab.

The service itself is unaware of all of the above - it submits a document as bytes and reads the registry's reply:

request = SOAPMessage()
request.namespace = 'urn:ihe:iti:xds-b:2007'
request.Document = document_bytes

response = self.soap['Document Exchange'].invoke('ProvideAndRegisterDocumentSet', request)

status = response.ProvideAndRegisterDocumentSetResponse.status

On the wire, that one call sends a SOAP 1.2 envelope with wsa:Action and wsa:MessageID headers, a signed SAML assertion in wsse:Security, and the document as an MTOM part - each piece added by the platform from what the connection is configured with.

Receiving submissions

The same profiles apply when you are the repository other systems submit to. Create a channel under Connections > Channels > SOAP with the version set to 1.2 and MTOM enabled for the responses:

The channel accepts multipart submissions of either packaging, resolves the document parts into bytes, and hands your service a dot-accessed payload:

request = self.request.payload

# An MTOM part reads as plain bytes
document = request.Document

response = SOAPMessage()
response.status = 'urn:ihe:iti:2007:ResponseStatusType:Success'

self.response.payload = response

The receiving tutorial walks through the whole channel side with document submission as its running example.

Learn more