# WS-Security

UsernameToken, X.509 and SAML for SOAP - inbound enforcement on channels and outgoing headers from one definition.

[Video: New WS-Security definition](https://zatosource-production.b-cdn.net/docs/gfx/security/wss-create.webm?v=1792089397)

Dashboard menu: Security > WS-Security

## Overview {#overview}

A WS-Security definition describes credentials placed inside a SOAP envelope's `wsse:Security` header rather than in HTTP headers - the security model of classic enterprise SOAP stacks. One definition serves both directions of traffic:

- **Channels** - Zato enforces the configured token on SOAP requests before any service code runs.
- **Outgoing** - Zato adds the `wsse:Security` header to the envelopes an outgoing SOAP connection sends.

Definitions are managed in the dashboard under **Security** > **WS-Security**. Changes take effect immediately, without server restarts.

## Definition fields {#definition-fields}

Each definition is in one of three modes, selected in the create and edit forms, and the mode controls which fields apply.

Fields shared by all modes:

| Field | Notes |
| --- | --- |
| Name | A unique name for the definition |
| Mode | One of Username token, X.509 or SAML |
| Username | The username inside the token |

Username token mode:

| Field | Notes |
| --- | --- |
| Password digest | When checked, the password is sent as `Base64(SHA-1(nonce + created + password))` per the UsernameToken profile - otherwise it goes as clear text, which assumes TLS |
| Password | Set through the definition's change-password action after it is created |

X.509 mode:

| Field | Notes |
| --- | --- |
| Sign | Whether to sign the envelope's body and timestamp |
| Encrypt | Whether to encrypt the envelope for the peer |
| Signing key | Path to the PEM private key that signs |
| Signing certificate chain | Path to the PEM chain sent along with the signature |
| Decryption key | Path to the PEM private key that decrypts inbound envelopes |
| Peer certificate | Path to the peer's PEM certificate that encryption is for |
| Trust anchors | Path to the PEM CA bundle inbound signatures must chain up to |

A definition in X.509 mode must ask for signing or encryption - one with neither is refused.

SAML mode:

| Field | Notes |
| --- | --- |
| Issuer | The `saml:Issuer` of the assertion |
| Subject | The assertion's subject |
| Audience | The audience the assertion is restricted to |
| Sign | Whether the assertion is signed with the X.509 material above |

The definition is exported and imported with [enmasse](https://zato.io/docs/admin/enmasse.html) under the `security` key, with `type: wss` - the fields are in the [enmasse reference](https://zato.io/docs/admin/enmasse-reference.html).

## SOAP channels {#soap-channels}

Assign a definition to a [SOAP channel](https://zato.io/docs/dev/soap/index.html) by selecting **WS-Security/\<name>** in the channel's security dropdown. From then on, every envelope arriving at that channel must have a `wsse:Security` header that satisfies the definition, and everything else receives a 401 response.

For a Username token definition, enforcement checks more than the password:

- The password type must be the configured one - a clear-text password sent to a definition that expects a digest is refused, and the other way around.
- With digests, the `wsu:Created` timestamp must be recent - the default window is 300 seconds, with 60 seconds of allowance for clock skew.
- Each nonce may be used once - replayed nonces are refused for the length of the window.

## Outgoing connections {#outgoing-connections}

The same definition drives outgoing calls. When an [outgoing SOAP connection](https://zato.io/docs/admin/security/outgoing.html) uses a WS-Security definition, Zato builds the `wsse:Security` header for every envelope the connection sends - a Username token with a fresh nonce and timestamp, a signed or encrypted envelope in X.509 mode, or a SAML assertion - with nothing to add in service code.

## Learn more {#learn-more}

- [Securing channels](https://zato.io/docs/admin/security/channel.html) - Which security types a channel accepts, and how to assign them
- [Securing outgoing connections](https://zato.io/docs/admin/security/outgoing.html) - Credentials Zato presents to the systems it calls
- [API keys](https://zato.io/docs/security/api-keys.html) - Per-client keys in a configurable HTTP header
- [Basic Auth](https://zato.io/docs/security/basic-auth.html) - Usernames and passwords for channels and outgoing connections
- [Bearer tokens](https://zato.io/docs/security/bearer-tokens/) - Static tokens and JWTs verified against a JWKS endpoint
- [Security groups](https://zato.io/docs/security/groups.html) - Many API client credentials on one channel or MCP gateway
- [Kerberos (SPNEGO)](https://zato.io/docs/security/kerberos/) - Negotiate authentication from a keytab, with no ticket management
- [mTLS](https://zato.io/docs/security/mtls/) - Client certificates in both directions, matched by fingerprint or DN
- [NTLM](https://zato.io/docs/security/ntlm.html) - Windows domain credentials for outgoing connections
- [Quota tiers](https://zato.io/docs/security/quota-tiers.html) - Named rate-limit plans assigned to any number of API clients
- [TLS certificates](https://zato.io/docs/admin/security/ssl/) - Your own certificates, the self-signed ones and how to rotate them
