Security guide
Build and validate WS-Security UsernameToken and Timestamp
Place WS-Security headers correctly, validate freshness and replay state, and understand what PasswordDigest and TLS each protect.
10 min read · Updated 2026-08-21
The short answer
Put one wsse:Security header at the role the service processes, include a wsu:Timestamp with UTC Created and Expires values, and follow the UsernameToken profile exactly for PasswordText or PasswordDigest. On receipt, authenticate the credential, validate timestamp skew and expiry, cache nonce-plus-created values to reject replay, and require TLS because a password digest is not message encryption or a replacement for transport confidentiality.Construct the profile-shaped header
WS-Security extends SOAP through a Header block. Namespace URIs identify the security and utility vocabularies; prefixes are aliases. The Timestamp belongs inside wsse:Security and may contain Created followed by Expires.
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsse:Security soap:mustUnderstand="1">
<wsu:Timestamp wsu:Id="TS-1">
<wsu:Created>2026-08-21T12:00:00Z</wsu:Created>
<wsu:Expires>2026-08-21T12:05:00Z</wsu:Expires>
</wsu:Timestamp>
<wsse:UsernameToken wsu:Id="UT-1">
<wsse:Username>integration-user</wsse:Username>
<wsse:Password Type="...#PasswordDigest">BASE64_DIGEST</wsse:Password>
<wsse:Nonce EncodingType="...#Base64Binary">BASE64_NONCE</wsse:Nonce>
<wsu:Created>2026-08-21T12:00:00Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soap:Header>
<soap:Body><m:Check xmlns:m="urn:example:orders"/></soap:Body>
</soap:Envelope>Validate freshness and replay together
Timestamp validation needs a documented maximum lifetime and clock-skew allowance. A valid Created value without a replay cache lets the same captured token be used repeatedly during that window; a replay cache without expiry grows without bound.
- Reject expired messages and messages created too far in the future.
- Require the nonce and Created inputs the selected password-digest profile expects.
- Cache a replay key until the accepted message window closes.
- Sign the Timestamp and Body when the service policy requires message integrity.
Do not confuse digest, signature, and encryption
PasswordDigest proves knowledge of a shared secret under the profile's construction; it does not hide the SOAP Body and does not make a message confidential. TLS protects the transport hop, while XML Signature and XML Encryption can protect selected message parts through intermediaries when the service policy requires them.
Match the deployed WS-SecurityPolicy or vendor contract exactly. Adding extra tokens, changing element order, or inventing namespace URIs often causes interoperability failures before authentication code runs.
Prove the fix
- Validate the envelopeCatch SOAP structure and namespace problems before authentication debugging.
- Inspect WS-Security namesUse the specification namespace URIs without treating them as fetch URLs.
- Debug SOAP failuresSeparate protocol faults from credential and application failures.
Related guides
- Verify an XML Signature safelySeparate reference digest validation, SignatureValue verification, key trust, and application meaning so a valid XML signature protects the intended data.
- Prevent SAML XML signature wrappingValidate SAML structure, signatures, destination, audience, time, request correlation, and replay without consuming an unsigned sibling assertion.
- How to debug a SOAP FaultRead the standard fault fields before application detail, preserve the HTTP response, and reduce a failing SOAP request without losing context.
Get started
Bring order to the XML your team can't afford to ignore.
Create a free account and get a private workspace to search, validate, diff, and monitor your XML feeds, sitemaps, schemas, and vendor integrations.