Skip to main content

SAML Metadata Reference

SAML 2.0 (OASIS XML-based SSO standard) uses an XML metadata document to describe each entity's endpoints, supported bindings, NameID formats, and X.509 certificates. Exchanging metadata is how an IdP and SP establish trust without hand-copying URLs or certificates. This page describes the metadata documents LumoAuth publishes and how to read or validate them.

Metadata Endpoints​

EndpointDescription
/orgs/\{orgId\}/saml/sp/metadataService Provider metadata (when LumoAuth is SP)
/orgs/\{orgId\}/saml/idp/metadataIdentity Provider metadata (when LumoAuth is IdP)
Best Practice

Use metadata URLs instead of copying values by hand. That way certificates and endpoints stay in sync when either side rotates keys.

SP Metadata Structure​

When LumoAuth acts as a Service Provider:

<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
entityID="https://app.lumoauth.dev/orgs/acme-corp/saml/sp/metadata">
<ds:Signature>...</ds:Signature>
<md:SPSSODescriptor AuthnRequestsSigned="false"
WantAssertionsSigned="false"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICoDCCAYigAwIBAgIJAL...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://app.lumoauth.dev/orgs/acme-corp/saml/sp/slo"/>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:AssertionConsumerService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://app.lumoauth.dev/orgs/acme-corp/saml/sp/acs"
index="0"
isDefault="true"/>
</md:SPSSODescriptor>
</md:EntityDescriptor>

The SP metadata document is itself signed (ds:Signature) with the organization's SAML certificate. The two descriptor flags are advertised as false because they are decided per identity provider at runtime: LumoAuth always requires signed assertions, and signs its own requests when Sign authentication requests is on for that IdP.

SP Metadata Elements​

ElementAttributeDescription
EntityDescriptorentityIDUnique identifier for this SP
SPSSODescriptorAuthnRequestsSignedWhether SP signs AuthnRequests (advertised as false; see above)
WantAssertionsSignedWhether the SP asks the IdP to sign assertions (advertised as false; LumoAuth enforces it at runtime anyway)
KeyDescriptoruse="signing"Certificate for signature verification
AssertionConsumerServiceLocationURL where IdP posts SAML Response
BindingHTTP-POST or HTTP-Redirect
SingleLogoutServiceLocationURL for logout requests

IdP Metadata Structure​

When LumoAuth acts as an Identity Provider:

<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
entityID="https://app.lumoauth.dev/orgs/acme-corp/saml/idp/metadata">
<md:IDPSSODescriptor WantAuthnRequestsSigned="true"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
<md:KeyDescriptor use="signing">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICoDCCAYigAwIBAgIJAL...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</md:KeyDescriptor>
<md:KeyDescriptor use="encryption">
<ds:KeyInfo>
<ds:X509Data>
<ds:X509Certificate>MIICoDCCAYigAwIBAgIJAL...</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
<md:EncryptionMethod Algorithm="http://www.w3.org/2009/xmlenc11#aes256-gcm"/>
<md:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p"/>
</md:KeyDescriptor>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://app.lumoauth.dev/orgs/acme-corp/saml/idp/slo"/>
<md:SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://app.lumoauth.dev/orgs/acme-corp/saml/idp/slo"/>
<md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:persistent</md:NameIDFormat>
<md:NameIDFormat>urn:oasis:names:tc:SAML:2.0:nameid-format:transient</md:NameIDFormat>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect"
Location="https://app.lumoauth.dev/orgs/acme-corp/saml/idp/sso"/>
<md:SingleSignOnService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
Location="https://app.lumoauth.dev/orgs/acme-corp/saml/idp/sso"/>
</md:IDPSSODescriptor>
</md:EntityDescriptor>

IdP Metadata Elements​

ElementAttributeDescription
EntityDescriptorentityIDUnique identifier for this IdP
IDPSSODescriptorWantAuthnRequestsSignedRequire SPs to sign requests
KeyDescriptoruse="signing"Certificate SPs use to verify signatures
KeyDescriptoruse="encryption"Certificate for encrypted SAML traffic, with the EncryptionMethod algorithms the IdP supports (AES-256-GCM content, RSA-OAEP-MGF1P key transport — see IdP assertion encryption)
SingleSignOnServiceLocationURL where SPs send AuthnRequests
BindingSupported binding type

SAML Bindings​

Bindings define how SAML messages are transported over HTTP:

BindingURNMethodUse Case
HTTP-Redirecturn:oasis:names:tc:SAML:2.0:bindings:HTTP-RedirectGETAuthnRequests, LogoutRequests
HTTP-POSTurn:oasis:names:tc:SAML:2.0:bindings:HTTP-POSTPOSTSAML Responses, large messages
HTTP-Artifacturn:oasis:names:tc:SAML:2.0:bindings:HTTP-ArtifactGET/POSTHigh-security (back-channel resolution)
Redirect Binding Limitations

The HTTP-Redirect binding has a URL length limit of about 2 KB. For larger SAML messages, use HTTP-POST instead.

Certificate Handling​

Certificate Format in Metadata​

Certificates in metadata are Base64-encoded X.509 certificates without PEM headers:

MIICoDCCAYigAwIBAgIJALmv3e3J7tFpMA0GCSqGSIb3DQEBCwUAMBkxFzAVBgNV
BAMMDmF1dGguZXhhbXBsZS5jb20wHhcNMjQwMTE1MTAzMDAwWhcNMjcwMTE0MTAz
MDAwWjAZMRcwFQYDVQQDDA5hdXRoLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B
...

Converting to PEM Format​

To use the certificate with external tools, add PEM headers:

# SHA-256 fingerprint
openssl x509 -in cert.pem -noout -fingerprint -sha256

# SHA-1 fingerprint (legacy)
openssl x509 -in cert.pem -noout -fingerprint -sha1

Extracting Values from Metadata​

If manual configuration is required, extract values using XPath:

ValueXPath Expression
Entity ID/md:EntityDescriptor/@entityID
SSO URL (Redirect)//md:SingleSignOnService[@Binding='...HTTP-Redirect']/@Location
SSO URL (POST)//md:SingleSignOnService[@Binding='...HTTP-POST']/@Location
ACS URL//md:AssertionConsumerService/@Location
SLO URL//md:SingleLogoutService/@Location
Signing Certificate//md:KeyDescriptor[@use='signing']//ds:X509Certificate/text()

Using cURL and xmllint​

# Download and extract Entity ID
curl -s https://idp.example.com/metadata | \
xmllint --xpath "/*/@entityID" - 2>/dev/null

# Extract SSO URL
curl -s https://idp.example.com/metadata | \
xmllint --xpath "//*[local-name()='SingleSignOnService']/@Location" - 2>/dev/null

Metadata Validation​

Before deployment, validate metadata:

  1. XML Validity: Ensure well-formed XML syntax
  2. Schema Compliance: Validate against SAML metadata XSD
  3. Certificate Validity: Check certificate expiration dates
  4. Endpoint Accessibility: Verify all URLs are reachable
  5. Binding Support: Ensure compatible bindings

Debugging Tools​

ToolDescription
SAMLTool.comOnline SAML message decoder and validator
SAML TracerFirefox extension for SAML debugging
SAML DevToolsChrome extension for SAML debugging

Common Issues​

IssueCauseSolution
Certificate MismatchMetadata certificate differs from signing keyRe-download metadata after cert rotation
Expired CertificateCertificate validity period passedGenerate new certificate, update all parties
Wrong BindingSP/IdP using incompatible bindingCheck supported bindings in metadata
Namespace IssuesMissing or wrong XML namespacesEnsure all required namespaces declared