XUA SAML and WS-Security requirements for XCA endpoints
This document describes the requirements a SAML 2.0 assertion must meet to pass validation when submitting requests to the National Imaging Registry via the XCA (ITI-38 Cross-Gateway Query, ITI-39 Cross-Gateway Retrieve) and XCA-I (RAD-75 Cross-Gateway Image Retrieve) transactions.
Requirements follow the IHE Cross-Enterprise User Assertion (XUA) profile, ITI Technical Framework Volume 2, Transaction ITI-40, which profiles OASIS SAML 2.0 Core and the WS-Security SAML Token Profile 1.1.
How a request is brokered
NIR acts as a trust broker. A consumer submits a request to the NIR gateway; the NIR gateway then validates it and forwards it to the appropriate responding gateway(s) on their behalf, re-signing it under NIR's own identity.
- you establish trust only with NIR – your issuing/signing certificate is registered with the NIR gateway's inbound trust store
- the audience of your assertion is the NIR gateway, not the responding gateway
NIR preserves the provenance of your request (your originating community and user identity) when it re-asserts downstream, so audit records downstream still reflect the real principal.
SOAP envelope structure
The SAML assertion is carried as a security token in the wsse:Security header:
Namespace prefixes are arbitrary; only the namespace URIs are significant.
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<wsse:Security 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">
<wsu:Timestamp wsu:Id="Timestamp-1"> ... </wsu:Timestamp>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion" ID="SamlAssertion-1"> ... </saml:Assertion>
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"> ... </ds:Signature>
</wsse:Security>
</soap:Header>
<soap:Body wsu:Id="Body" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<!-- ITI-38 / ITI-39 / RAD-75 request body -->
</soap:Body>
</soap:Envelope>
Required assertion elements
Assertion element
| Requirement | Detail |
|---|---|
| Namespace | urn:oasis:names:tc:SAML:2.0:assertion |
| Presence | Mandatory |
| Version | Mandatory (SAML Core — AssertionType) — exactly 2.0 |
| ID | Mandatory (SAML Core — AssertionType) — unique XML ID |
| IssueInstant | Mandatory (SAML Core — AssertionType) — UTC dateTime. Per XUA, Conditions/@NotBefore is set equal to this value. |
Issuer
| Requirement | Detail |
|---|---|
| Element | <saml:Issuer> |
| Presence | Mandatory (SAML Core — <Issuer> is a required element of AssertionType) |
| Value | Entity identifier of the X-Assertion Provider (STS/IdP) that issued and signed the assertion. |
Assertion signature
| Requirement | Detail |
|---|---|
| Element | <ds:Signature> (enveloped), per SAML Core, signed by the issuer |
| Presence | Mandatory — consumers use the bearer model, where trust derives from this signature |
| Algorithms | Signature rsa-sha256; digest sha256. SHA-1 is rejected. |
| Canonicalization | Exclusive C14N (http://www.w3.org/2001/10/xml-exc-c14n#) |
| Trust | Signing certificate must chain to a CA in NIR's inbound trust store |
Subject
| Requirement | Detail |
|---|---|
| <saml:Subject> | Mandatory |
| <saml:NameID> | Mandatory, non-empty. This, not the optional subject-id attribute, is the required user identifier. |
| Format | Recommended (e.g. ...:nameid-format:emailAddress). The format URI belongs in Format, not NameQualifier. |
| <saml:SubjectConfirmation> Method | Mandatory — urn:oasis:names:tc:SAML:2.0:cm:bearer |
| <saml:SubjectConfirmationData> | Required by NIR policy; NotBefore/NotOnOrAfter checked as defence-in-depth where present. The authoritative validity window is Conditions, not this element. Recipient is not currently inspected. |
Conditions
| Requirement | Detail |
|---|---|
| <saml:Conditions> | Mandatory |
| NotBefore | Mandatory — the issuer sets it to the issue instant. NIR enforces the admission check (reject if now < NotBefore). |
| NotOnOrAfter | Optional — XUA deliberately does not specify expiry. NIR enforces now < NotOnOrAfter (exclusive) when it is provided. |
| AudienceRestriction / Audience | Mandatory — this should match the base URL of the NIR Gateway, e.g. https://nir.national.nhs.uk, https://int.nir.national.nhs.uk |
AuthnStatement
| Requirement | Detail |
|---|---|
| <saml:AuthnStatement> | Mandatory (IHE XUA, ITI-40 §3.40.4.1.2 — optional in base SAML) |
| AuthnInstant | Mandatory — UTC dateTime of the authentication event (the user's login), which is not necessarily the assertion's IssueInstant |
| <saml:AuthnContext> | Mandatory — contains the authentication-method description |
| AuthnContextClassRef (or AuthnContextDeclRef) | Mandatory — a URI naming how the user authenticated |
SubjectLocality, SessionIndex, and SessionNotOnOrAfter are optional and normally omitted for XUA. The minimal conformant form is AuthnInstant plus a single AuthnContextClassRef.
Validation: NIR checks that an AuthnContext with a non-empty AuthnContextClassRef (or AuthnContextDeclRef) is present — this is the XUA §3.40.4.1.2 requirement. The value is not currently checked against an accept-list.
AttributeStatement
All <saml:Attribute> elements should carry NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri" (except subject-id, conventionally ...:basic).
| Attribute Name | Presence | Value |
|---|---|---|
| urn:oasis:names:tc:xspa:1.0:subject:subject-id | Optional | Supplementary user identifier. The mandatory user identity is the Subject NameID (§3.4), not this attribute. |
| urn:oasis:names:tc:xspa:1.0:subject:organization | Optional | Organisation name |
| urn:oasis:names:tc:xspa:1.0:subject:organization-id | Optional | Organisation identifier (OID/URI) |
| urn:oasis:names:tc:xacml:2.0:subject:role | Mandatory | Role — coded preferred |
| urn:oasis:names:tc:xspa:1.0:subject:purposeofuse | Mandatory | Purpose of use — bare string acceptable |
| urn:ihe:iti:xca:2010:homeCommunityId | Mandatory | Originating community OID, urn:oid: format |
Role (ITI-40 Subject-Role Option). Consumers should supply a coded role: an HL7 Role element in the urn:hl7-org:v3 namespace, xsi:type="CE", with code / codeSystem / codeSystemName / displayName:
<saml:Attribute Name="urn:oasis:names:tc:xacml:2.0:subject:role"> <saml:AttributeValue> <Role xmlns="urn:hl7-org:v3" xsi:type="CE" code="158965000" codeSystem="2.16.840.1.113883.6.96" codeSystemName="SNOMED_CT" displayName="Medical practitioner"/> </saml:AttributeValue> </saml:Attribute>
NIR accepts a bare string (for example, DOCTOR), but a coded role is preferred in order to enrich the audit logs.
Purpose of use. A bare string value (for example, TREATMENT) is acceptable. Purpose of use is an access/claim attribute only.
Home Community ID. The OID of the community initiating the request, in urn:oid: format. Distinct from the $homeCommunityId query slot (ITI-38) / <HomeCommunityId> element (ITI-39, RAD-75) in the SOAP Body, which identifies the target community.
WS-Security message layer
In addition to the issuer-signed assertion, the request carries a WS-Security message signature.
| Requirement | Detail |
|---|---|
| <wsse:Security> | Mandatory |
| <ds:Signature> (detached) | Signs #Body, #Timestamp-1, #SamlAssertion-1 — exactly 3 references |
| Algorithms | rsa-sha256 / sha256 / exclusive C14N |
| Certificate | X.509, chaining to NIR's inbound trust store |
| <wsu:Timestamp wsu:Id="Timestamp-1"> | Contains Created and Expires |
On the Timestamp. The Timestamp is a WS-Security message-layer element for message-replay protection. It is not part of XUA assertion profiling, and the assertion's own Conditions is what bounds assertion validity. It is required here because it is one of the three references covered by the message signature.
Example
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<wsse:Security 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">
<wsu:Timestamp wsu:Id="Timestamp-1">
<wsu:Created>2026-06-09T12:00:00Z</wsu:Created>
<wsu:Expires>2026-06-09T12:05:00Z</wsu:Expires>
</wsu:Timestamp>
<saml:Assertion xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
ID="SamlAssertion-1" IssueInstant="2026-06-09T12:00:00Z" Version="2.0">
<saml:Issuer>urn:your-org:sts</saml:Issuer>
<!-- Enveloped signature by the issuer (rsa-sha256), abbreviated -->
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#SamlAssertion-1">
<ds:Transforms>
<ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/>
<ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</ds:Transforms>
<ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/>
<ds:DigestValue>...</ds:DigestValue>
</ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>...</ds:X509Certificate></ds:X509Data></ds:KeyInfo>
</ds:Signature>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">[email protected]</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="2026-06-09T14:00:00Z" Recipient="urn:nir:xca:proxy"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:Conditions NotBefore="2026-06-09T12:00:00Z" NotOnOrAfter="2026-06-09T14:00:00Z">
<saml:AudienceRestriction>
<saml:Audience>urn:nir:xca:proxy</saml:Audience> <!-- the NIR gateway, not the responding gateway -->
</saml:AudienceRestriction>
</saml:Conditions>
<saml:AuthnStatement AuthnInstant="2026-06-09T12:00:00Z">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:X509</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="urn:oasis:names:tc:xspa:1.0:subject:subject-id"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:basic">
<saml:AttributeValue xsi:type="xs:string">Dr Jane Smith</saml:AttributeValue> <!-- optional; user identity is the NameID above -->
</saml:Attribute>
<saml:Attribute Name="urn:oasis:names:tc:xspa:1.0:subject:organization"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xsi:type="xs:string">Example NHS Trust</saml:AttributeValue> <!-- optional -->
</saml:Attribute>
<saml:Attribute Name="urn:oasis:names:tc:xspa:1.0:subject:organization-id"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue xsi:type="xs:anyURI">urn:oid:1.2.826.0.1285.0.1.10</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="urn:oasis:names:tc:xacml:2.0:subject:role"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue>
<Role xmlns="urn:hl7-org:v3" xsi:type="CE"
code="158965000" codeSystem="2.16.840.1.113883.6.96"
codeSystemName="SNOMED_CT" displayName="Medical practitioner"/>
</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="urn:oasis:names:tc:xspa:1.0:subject:purposeofuse"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue>TREATMENT</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="urn:ihe:iti:xca:2010:homeCommunityId"
NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<saml:AttributeValue>urn:oid:1.2.826.0.1285.0.2.0.107</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
<!-- Detached message signature over #Body, #Timestamp-1, #SamlAssertion-1 (rsa-sha256), abbreviated -->
<ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:SignedInfo>
<ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/>
<ds:Reference URI="#Body"><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>...</ds:DigestValue></ds:Reference>
<ds:Reference URI="#Timestamp-1"><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>...</ds:DigestValue></ds:Reference>
<ds:Reference URI="#SamlAssertion-1"><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>...</ds:DigestValue></ds:Reference>
</ds:SignedInfo>
<ds:SignatureValue>...</ds:SignatureValue>
<ds:KeyInfo><ds:X509Data><ds:X509Certificate>...</ds:X509Certificate></ds:X509Data></ds:KeyInfo>
</ds:Signature>
</wsse:Security>
</soap:Header>
<soap:Body wsu:Id="Body" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<!-- ITI-38 AdhocQueryRequest / ITI-39 RetrieveDocumentSetRequest / RAD-75 RetrieveImagingDocumentSetRequest -->
</soap:Body>
</soap:Envelope>
Additional notes
- All datetimes are UTC (Z suffix). NotOnOrAfter is exclusive; NotBefore is inclusive (both Conditions and SubjectConfirmationData).
- Per XUA, the issuer populates Conditions/@NotBefore with the assertion's IssueInstant; NIR checks admission against NotBefore but does not reject when the two differ.
- XUA does not specify Conditions/@NotOnOrAfter; NIR will validate it if present. ProxyRestriction/OneTimeUse are ignored.
- Audience should match the base URL of the NIR gateway you submit to, e.g. https://nir.national.nhs.uk, not the downstream responding gateway.
- SHA-1 signatures/digests are rejected; use SHA-256.
- Synchronise clocks (NTP) to avoid time-skew rejection.
- Register your issuing/signing certificate's CA with the NIR team. There is no requirement to register with downstream responding gateways.
- Supplying coded role values is requested even though bare strings are accepted; it improves audit fidelity.
Last edited: 19 June 2026 4:34 pm