SOAP security

WS-Security, body credentials and mutual TLS - each mechanism configured separately and combined freely.

SOAP endpoints authenticate in three distinct places - the SOAP header, the message body and the TLS layer - and real systems routinely require more than one at a time. Zato models each mechanism separately so that any combination is a matter of configuration:

  • WS-Security definitions cover everything that lives in the wsse:Security header: UsernameToken, X.509 signing and encryption, SAML assertions
  • Body credentials put a username and password inside the business message itself
  • Mutual TLS presents a client certificate at the transport layer

Your service code stays identical whichever mechanisms a connection uses - security is applied by the platform when invoke runs, never by the service.

WS-Security definitions

A WS-Security definition is created once, under Security → WS-Security in the Dashboard, and then attached to any number of connections through their Security tab. Each definition has a mode that decides what goes into the header.

UsernameToken

The username and password travel in a wsse:UsernameToken header element - the most common corporate SOAP setup. The password is entered separately, through the definition's Change password link, and can be sent either as text over TLS or in digest form, with an auto-generated nonce and timestamp, for endpoints that require it.

X.509

The definition holds PEM material and two switches:

  • Sign - the message is signed with your private key (Signing key), and your Signing certificate chain travels along so the receiver can verify the signature
  • Encrypt - the body is encrypted for the receiver using their Peer certificate

For verifying and decrypting what comes back, the definition also holds a Decryption key and Trust anchors - the CA certificates that peers' signatures are validated against. All of it is standard XML-DSig and XML-Encryption, the same W3C mechanics that WS-Security prescribes.

SAML

The definition generates a sender-vouches SAML 2.0 assertion on each request, built from the Issuer, Subject and Audience fields. With Sign enabled, the assertion includes an enveloped RSA-SHA256 signature computed with the same Signing key and Signing certificate chain fields the X.509 mode uses - which is what healthcare document-exchange profiles such as IHE XUA require of cross-community requests.

Externally issued assertions - tokens obtained from an identity provider rather than generated by the platform - can also be attached as raw bytes and pass through unmodified.

Body credentials

Some endpoints do not look at the SOAP header at all - they expect the username and password as the first elements of the business message. Immunization registries following the CDC WSDL are the best-known example:

<sub:submitSingleMessage>
    <sub:username>my-user</sub:username>
    <sub:password>*******</sub:password>
    <sub:hl7Message>MSH|^~\&amp;|...</sub:hl7Message>
</sub:submitSingleMessage>

The Body credentials tab of an outgoing SOAP connection defines this mapping as a list of rows - each row names the element to create and, optionally, its 1-based position among the operation's children. Rows without a position become the first children in row order, which matches the common case of credentials-first layouts.

The values come from the security definition attached to the connection, and injection happens inside invoke, after your service has built the message - so the service never sees, handles or logs the credentials:

# The service only builds business fields ..
request = SOAPMessage()
request.hl7Message = hl7_payload

# .. username and password are injected here, per the connection's mapping.
response = self.soap['My Registry'].invoke('submitSingleMessage', request)

Because the injected elements inherit the operation's namespace, they look to the receiving system exactly like any other field of the message.

Mutual TLS

Endpoints that authenticate clients at the TLS layer are covered by two fields on the connection's Security tab:

  • Client certificate - a local path to a PEM file with the certificate, or with the certificate and key combined
  • Client key - a local path to the key's PEM file, when it is kept separately

The paths point to files on the server - in containerized deployments, certificates are mounted into the container and the fields name the mount paths. Because this is a connection-level setting and not a security-definition type, it combines freely with everything above: one connection can present a client certificate and inject body credentials and sign its messages, which is precisely what some registries and national networks require.

The TLS validation dropdown on the same tab controls verification of the server's own certificate.

Combining the mechanisms

RequirementConfiguration
Username and password in the SOAP headerWS-Security definition, UsernameToken mode
Username and password inside the message bodyAny definition with credentials + Body credentials rows
Signed messagesWS-Security definition, X.509 mode with Sign
Encrypted messagesWS-Security definition, X.509 mode with Encrypt
Signed SAML user assertionWS-Security definition, SAML mode with Sign
Client certificate at the TLS layerClient certificate and key paths on the connection
Any combination of the aboveAttach the definition and set the connection fields together

Configuration as code

Everything above is also plain YAML. A WS-Security definition deploys with enmasse like any other object - the mode and its fields map one-to-one from the Dashboard forms:

security:

  - name: Registry Credentials
    type: wss
    username: my-registry-user
    password: Zato_Enmasse_Env.RegistryPassword
    mode: username_token
    use_digest: true

The enmasse reference documents every field of all three modes, with complete YAML examples for UsernameToken, X.509 and SAML definitions.

Learn more