WEB / WEB-15.S02
Introduction to the SAML federation model
Bind an IdP authentication result to SP transaction, recipient and signature contexts.
1. Core · Mechanism
Read every scenario without motion
Normal SSO
- SP request ready
The SP bound request-A to the initiating browser context; IdP and ACS registration are preselected in this synthetic profile.
- Atlas SP
- Request-A pending; no session
- Browser
- Normal login navigation
- IdP
- Configured IdP; no request
- Redirect at browser
The SP’s ordinary redirect response reached the browser; the declared AuthnRequest navigation target is the registered IdP.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Configured IdP; no request
- AuthnRequest at IdP
The browser’s ordinary navigation request reached the IdP; request-A and SP context were received, while authentication is local.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Request-A received; pending
- IdP local authentication
Declared IdP authentication completed and the selected assertion/response was prepared; no actual XML or signature bytes are produced.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Response-A + assertion-A ready
- POST form at browser
The IdP’s ordinary HTTP response reached the browser; the form destined for the ACS carries the selected response alias.
- Atlas SP
- Request-A pending; no session
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- Response arrived at ACS
The browser’s ordinary POST request reached the ACS; response/assertion were received, while SP validation and session remain pending.
- Atlas SP
- Response received; validation pending
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- SP local validation
Issuer/key and the same verified/consumed node conditions pass for Atlas SP. Audience contains the Atlas entity ID; ACS, request-A and browser-A bindings match. now=1050 satisfies Conditions [1000,1100) and confirmation <1080, so selected validation is accepted.
- Atlas SP
- All selected gates valid
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- Local session result
All selected assertion/context conditions passed. The SP creates its new local session, consumes the pending request and tracks assertion use through confirmation validity. This scene does not return a session response to the browser; IdP session and resource policy remain separate.
- Atlas SP
- New SP session; request consumed
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
Audience deny
- SP request ready
The SP bound request-A to the initiating browser context; IdP and ACS registration are preselected in this synthetic profile.
- Atlas SP
- Request-A pending; no session
- Browser
- Normal login navigation
- IdP
- Configured IdP; no request
- Redirect at browser
The SP’s ordinary redirect response reached the browser; the declared AuthnRequest navigation target is the registered IdP.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Configured IdP; no request
- AuthnRequest at IdP
The browser’s ordinary navigation request reached the IdP; request-A and SP context were received, while authentication is local.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Request-A received; pending
- IdP local authentication
Declared IdP authentication completed and the selected assertion/response was prepared; no actual XML or signature bytes are produced.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Response-A + assertion-A ready
- POST form at browser
The IdP’s ordinary HTTP response reached the browser; the form destined for the ACS carries the selected response alias.
- Atlas SP
- Request-A pending; no session
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- Response arrived at ACS
The browser’s ordinary POST request reached the ACS; response/assertion were received, while SP validation and session remain pending.
- Atlas SP
- Response received; validation pending
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- SP local validation
The assertion audience restriction contains only the catalog SP entity ID; the Atlas entity ID does not satisfy it. Correct ACS, signature and now=1050 do not repair this intended-recipient mismatch. The SP rejects validation on audience.
- Atlas SP
- Audience mismatch
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- Local session result
The SP creates a session only when all selected conditions pass; failure branches create no session despite completed receipt.
- Atlas SP
- No SP session; denied
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
Time deny
- SP request ready
The SP bound request-A to the initiating browser context; IdP and ACS registration are preselected in this synthetic profile.
- Atlas SP
- Request-A pending; no session
- Browser
- Normal login navigation
- IdP
- Configured IdP; no request
- Redirect at browser
The SP’s ordinary redirect response reached the browser; the declared AuthnRequest navigation target is the registered IdP.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Configured IdP; no request
- AuthnRequest at IdP
The browser’s ordinary navigation request reached the IdP; request-A and SP context were received, while authentication is local.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Request-A received; pending
- IdP local authentication
Declared IdP authentication completed and the selected assertion/response was prepared; no actual XML or signature bytes are produced.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Response-A + assertion-A ready
- POST form at browser
The IdP’s ordinary HTTP response reached the browser; the form destined for the ACS carries the selected response alias.
- Atlas SP
- Request-A pending; no session
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- Response arrived at ACS
The browser’s ordinary POST request reached the ACS; response/assertion were received, while SP validation and session remain pending.
- Atlas SP
- Response received; validation pending
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- SP local validation
now=1080 precedes Conditions expiry 1100, but bearer confirmation NotOnOrAfter=1080 excludes equality. Receipt at the SP does not keep confirmation valid. Signature and request binding remain positive while the SP rejects on time.
- Atlas SP
- Confirmation window expired
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- Local session result
The SP creates a session only when all selected conditions pass; failure branches create no session despite completed receipt.
- Atlas SP
- No SP session; denied
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
Node deny
- SP request ready
The SP bound request-A to the initiating browser context; IdP and ACS registration are preselected in this synthetic profile.
- Atlas SP
- Request-A pending; no session
- Browser
- Normal login navigation
- IdP
- Configured IdP; no request
- Redirect at browser
The SP’s ordinary redirect response reached the browser; the declared AuthnRequest navigation target is the registered IdP.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Configured IdP; no request
- AuthnRequest at IdP
The browser’s ordinary navigation request reached the IdP; request-A and SP context were received, while authentication is local.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Request-A received; pending
- IdP local authentication
Declared IdP authentication completed and the selected assertion/response was prepared; no actual XML or signature bytes are produced.
- Atlas SP
- Request-A pending; no session
- Browser
- AuthnRequest navigation ready
- IdP
- Response-A + assertion-A ready
- POST form at browser
The IdP’s ordinary HTTP response reached the browser; the form destined for the ACS carries the selected response alias.
- Atlas SP
- Request-A pending; no session
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- Response arrived at ACS
The browser’s ordinary POST request reached the ACS; response/assertion were received, while SP validation and session remain pending.
- Atlas SP
- Response received; validation pending
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- SP local validation
signedNodeAlias=assertion-A differs from consumedNodeAlias=assertion-other. The declared signature result covers the verified node, not a different consumed node. The SP rejects the same-node binding and creates no new local identity.
- Atlas SP
- Verified/consumed node mismatch
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
- Local session result
The SP creates a session only when all selected conditions pass; failure branches create no session despite completed receipt.
- Atlas SP
- No SP session; denied
- Browser
- ACS POST form ready
- IdP
- Response-A + assertion-A ready
ACTORS · STATE · DATA FLOW
Who speaks, and who decides?
In SAML federation the IdP expresses the principal’s authentication result through an assertion; the SP is the relying party evaluating it in a local application context. Atlas selects SP-initiated browser SSO: the SP creates pending request-A, the browser carries the request to the registered IdP, and the IdP response reaches the SP ACS endpoint through the browser. The browser mediates transport, without owning the SP’s trust in the IdP signing identity. The local SP session is established separately from the IdP session.
The Response ID is response-A and the contained assertion ID is assertion-A; they are different fields. The assertion contains issuer, subject, an AuthnStatement, Conditions and bearer SubjectConfirmation. Response Status=Success alone does not mean local login acceptance. The SP reads the selected profile’s issuer, signature coverage, audience, recipient, time and request-correlation conditions together. The table selects one bearer assertion; its choice does not generalize to every profile or unsolicited-response configuration.
Destination, audience and recipient bind different things
Response Destination matches the ACS location receiving the message; bearer Recipient is the ACS URL where the assertion can be confirmed. Audience is the SP’s unique entity identifier and need not equal its ACS URL. Response and bearer InResponseTo are bound to selected request-A. The SP also preserves its pending request and browser context. Do not confuse a Core field’s generally optional definition with correlation requirements in this selected SP-initiated profile; unsolicited flows have separate rules and are not accepted here.
Conditions NotBefore includes the starting instant, while NotOnOrAfter excludes the ending instant. Bearer SubjectConfirmationData has its own NotOnOrAfter bound that must still permit RP confirmation; it is not merely a browser delivery deadline. Bearer data does not include NotBefore. The example selects Conditions [1000,1100), confirmation before 1080 and zero clock skew; now=1080 fails the confirmation gate. A real deployment manages clock-skew policy explicitly; earlier response receipt does not automatically validate later processing.
Which business data does the signature protect?
Approved erratum E26 for the POST profile requires digital-signature protection for each assertion; signing the assertion individually or signing a covering Response can provide it. This example selects individual assertion coverage. Signature validation needs a trusted IdP key, an accepted algorithm and known verified-node coverage; a certificate or KeyInfo inside the message is not automatically a trust anchor. Business identity must be read from the node actually verified and evaluated against policy.
When signedNodeAlias and consumedNodeAlias do not identify the same node, the local gate does not accept even a declared valid signature. These aliases are not XML, certificates or actual signatures; they form an inert typed ledger for parsed-business-node binding. NameID mapping depends on the trusted issuer and identifier format/qualifier agreement; resemblance of a display name or email alone does not create a local account. Login acceptance also does not automatically grant application roles, tenants or resource authorization.
2. Red · Trust & Impact
Read every scenario without motion
Different SP
- The SAML relying-party context was selected
The profile selects SP-initiated SSO, one bearer assertion and unsolicitedAccepted=false. Even with Response Destination at the Atlas ACS, assertion recipient, audience and request binding are evaluated separately.
- SAML profile
- case=audience-denied
- Assertion context validation
- Assertion gate not read
- SP session boundary
- No SP session
- Declared signature and trusted provenance were separated
cryptographicValidDeclared=true, keyProvenanceDeclared=true and selectedCoverage=individual-assertion are supplied. A certificate in a message is not itself a trust anchor; the verified data node remains identified.
- SAML profile
- case=audience-denied
- Assertion context validation
- Individual assertion signature predicate
- SP session boundary
- No SP session
- The consumption or audience gate was applied
The audience restriction contains only https://catalog.example.org/saml/entity. The Atlas SP entity ID is absent; a correct ACS destination does not permit a different intended SP.
- SAML profile
- case=audience-denied
- Assertion context validation
- Intended audience ≠ Atlas SP
- SP session boundary
- No SP session
- Other positive gates did not change the rejection
now=1050, pending request-A and browser-A remain valid. Positive correlation and time predicates do not compensate for failed audience.
- SAML profile
- case=audience-denied
- Assertion context validation
- Context/time valid; selected gate failed
- SP session boundary
- No SP session
- Local-session acceptance was withheld
Expected=false; no new SP session is established through this assertion. NameID text or an AuthnStatement does not serve as local identity proof overriding the failed context gate.
- SAML profile
- case=audience-denied
- Assertion context validation
- Selected validation denied
- SP session boundary
- No new SP session
- The typed-ledger trust boundary was preserved
This branch explains association and intended-recipient boundaries; it runs no actual XML signature or parser operation. Attribute, role and tenant authorization remain separate policy after accepted authentication.
- SAML profile
- case=audience-denied
- Assertion context validation
- Known: selected gate denial
- SP session boundary
- No broadened local authority
Node mismatch
- The SAML relying-party context was selected
The profile selects SP-initiated SSO, one bearer assertion and unsolicitedAccepted=false. Even with Response Destination at the Atlas ACS, assertion recipient, audience and request binding are evaluated separately.
- SAML profile
- case=node-denied
- Assertion context validation
- Assertion gate not read
- SP session boundary
- No SP session
- Declared signature and trusted provenance were separated
cryptographicValidDeclared=true, keyProvenanceDeclared=true and selectedCoverage=individual-assertion are supplied. A certificate in a message is not itself a trust anchor; the verified data node remains identified.
- SAML profile
- case=node-denied
- Assertion context validation
- Individual assertion signature predicate
- SP session boundary
- No SP session
- The consumption or audience gate was applied
signedNodeAlias=assertion-A differs from consumedNodeAlias=assertion-other. Signature success for one node does not verify another business node’s identity or condition data.
- SAML profile
- case=node-denied
- Assertion context validation
- Verified node ≠ consumed node
- SP session boundary
- No SP session
- Other positive gates did not change the rejection
now=1050, pending request-A and browser-A remain valid. Positive correlation and time predicates do not compensate for failed node association.
- SAML profile
- case=node-denied
- Assertion context validation
- Context/time valid; selected gate failed
- SP session boundary
- No SP session
- Local-session acceptance was withheld
Expected=false; no new SP session is established through this assertion. NameID text or an AuthnStatement does not serve as local identity proof overriding the failed context gate.
- SAML profile
- case=node-denied
- Assertion context validation
- Selected validation denied
- SP session boundary
- No new SP session
- The typed-ledger trust boundary was preserved
This branch explains association and intended-recipient boundaries; it runs no actual XML signature or parser operation. Attribute, role and tenant authorization remain separate policy after accepted authentication.
- SAML profile
- case=node-denied
- Assertion context validation
- Known: selected gate denial
- SP session boundary
- No broadened local authority
ASSUMPTION · BOUNDARY · CONTROL
A valid assertion cannot be used in any context
In the audience-denied branch the response reaches the correct ACS and the issuer and signature fixture remain valid, but the assertion is intended for the catalog SP. Atlas does not create a local session because its entity ID is missing from the audience restriction. Audiences inside one restriction are OR alternatives, while separate restriction groups combine with AND; flattening them into one large allowlist changes the condition. This is a failed intended-relying-party binding, not a transport or XML-format error.
In the expired branch Conditions have not ended, but now=1080 equals the bearer confirmation limit. After displaying SP receipt, the local time gate denies. request-B correlation, a different browser alias and a previously used assertion ID are other context questions. Profile signature validation does not permit those conditions to be skipped; evidence should identify the first failed gate and the local state that was not created.
A signature result does not hide node selection
The node-denied branch separates verified assertion-A from the business consumer’s assertion-other reference in a typed ledger alone. It contains no XML-signing example, parser manipulation or reproduction flow. The assumption to examine is which issuer/subject/condition node a successful signature result actually covered. Losing key provenance, coverage or consumption of the same node disconnects the identity decision from its evidence. Signed XML supplies integrity; attribute correctness and local role policy still require their own evaluation.
3. Blue · Secure development & defense
Read every scenario without motion
Confirmation time
- The bearer-confirmation window was selected
Normal Conditions uses NotBefore=1000 and NotOnOrAfter=1100. Bearer SubjectConfirmation has NotOnOrAfter=1080; the windows are separate gates.
- SAML decision ledger
- Conditions + confirmation
- Time/correlation review
- Time not compared
- SP evidence conclusion
- Acceptance not examined
- The selected clock profile was read
clockSkew=0; the integers are synthetic UTC timeline offsets. They are neither wire xs:dateTime strings nor production clock measurements.
- SAML decision ledger
- Clock skew=0
- Time/correlation review
- Synthetic UTC offsets
- SP evidence conclusion
- Acceptance not examined
- First and last eligible times were compared
now=1000 is eligible at NotBefore equality; now=1079 precedes both upper bounds. These rows are positive controls for the time gate.
- SAML decision ledger
- 1000 and 1079 eligible
- Time/correlation review
- Time expected=true
- SP evidence conclusion
- Other validation gates separate
- The earlier upper bound closed at equality
At now=1080 Conditions still precedes 1100, but bearer-confirmation NotOnOrAfter equality stops acceptance. The confirmation window is not interpreted merely as a delivery deadline.
- SAML decision ledger
- now=1080
- Time/correlation review
- Conditions valid; confirmation expired
- SP evidence conclusion
- Time acceptance=false
- Time denial was not confused with other gates
The expired row retains positive signature and request context. The reason is confirmation expiry, not a relabelled issuer, password or audience failure.
- SAML decision ledger
- Known: expired confirmation
- Time/correlation review
- Signature/context predicates unchanged
- SP evidence conclusion
- No inferred issuer compromise
- Time evidence remained within profile scope
The fixture’s expected time outcomes can be explained. Clock synchronization, multiple assertions/confirmations and actual SP acceptance need separate evidence; a new local session is not verified here.
- SAML decision ledger
- Known: selected time boundaries
- Time/correlation review
- Clock/runtime evidence separate
- SP evidence conclusion
- UNKNOWN: actual SP session
Request binding
- The pending-request scope was selected
Pending request-A is bound to browser-A. Response InResponseTo and bearer SubjectConfirmation InResponseTo are separate correlation fields for the same decision.
- SAML decision ledger
- request-A / browser-A
- Time/correlation review
- Correlation not read
- SP evidence conclusion
- Local session not examined
- The normal binding row was read
The row with responseRequest=request-A, subjectRequest=request-A, browserAlias=browser-A and pending=true gives expected=true. It is not reduced to matching only one request field.
- SAML decision ledger
- Both request links match
- Time/correlation review
- Browser/pending match
- SP evidence conclusion
- Correlation expected=true
- Response and subject mismatches were separated
Separate rows with response request-B or subject request-B have expected=false. One match does not compensate for the other mismatch; the fields are not flattened into one join.
- SAML decision ledger
- Distinct mismatch rows
- Time/correlation review
- Either request mismatch denies
- SP evidence conclusion
- Correlation expected=false
- Initiating-browser scope was preserved
Even with both request fields matching, browserAlias=browser-B gives expected=false. Seeing request-A does not establish local-session acceptance in another browser context.
- SAML decision ledger
- Request links match
- Time/correlation review
- Browser B ≠ pending Browser A
- SP evidence conclusion
- Correlation expected=false
- Audience grouping was read separately
Entity IDs within one AudienceRestriction are evaluated with OR, while different restrictions use AND. Correlation success does not complete intended-SP validation; separate audience evidence is required.
- SAML decision ledger
- Correlation policy known
- Time/correlation review
- Audience groups: OR within, AND across
- SP evidence conclusion
- Other gates remain separate
- The local-session conclusion was not broadened
The correlation matrix establishes only the request/browser binding. Issuer, signature coverage, consumed node, audience/recipient and time conditions are also required before SP authentication acceptance can be concluded. Local roles and resource permission remain separate application policy after authentication.
- SAML decision ledger
- Known: typed correlation rules
- Time/correlation review
- Other gate evidence required
- SP evidence conclusion
- UNKNOWN: actual SP acceptance
IMPLEMENTATION · SECURITY CONTROL · VERIFICATION
Trust configuration precedes the message
Atlas keeps the selected IdP entity ID, SP entity ID, ACS URL and signing-key provenance distinct in configuration. A current library algorithm policy is used; historical signature-algorithm recommendations from the 2005 standard are not carried forward as current deployment defaults. XML parser/schema/ID uniqueness, signature validation and business-node selection stay together within a reviewed library boundary. An unknown schema or a new key reference carried by a message is not an automatic network trust source.
The pending-request ledger binds the request ID and initiating browser context. No session is created until a local gate validates the selected bearer assertion’s issuer, signature coverage, Conditions, audience, recipient and InResponseTo. Multiple assertions require independent evaluation; one profile-valid bearer confirmation alternative may be sufficient for an assertion. The single-assertion, single-confirmation profile here does not claim to implement those multiplicity rules.
Separate session creation from assertion reuse
In the normal branch the SP creates a new local session only after all selected gates pass, consumes pending request state and retains the used assertion ID through confirmation validity. The POST profile requires this for bearer-reuse control; a real product separately verifies storage concurrency and clock policy. Accepting an assertion does not make the SP session indefinite; local session lifetime and any AuthnStatement SessionNotOnOrAfter context are tracked separately.
Compare normal acceptance with denials for audience, confirmation expiry and node binding. Response and bearer InResponseTo must refer to the same pending request, with browser context bound to the initiator. The table expresses these decisions using aliases and times; it does not establish actual XML canonicalization, digital signatures, parsing, SAML bindings, IdP/SP operation, browser forms or persistent sessions. Even after authentication acceptance, the application owner separately applies tenant and record policy.
NOW APPLY IT TO THE CASE
Which context gates remain beyond signature success?
Atlas’s single-bearer-assertion profile requires audience, the same verified node, request/browser binding and two time windows. The typed ledger is not an actual XML runtime.
Which issuer/recipient relationship supplies identity in the case? Separate login or delegation success from evidence for current tenant/object permission.
Open the related case file ↗READ THE EXAMPLE TOGETHER
SAML response/assertion context ledger
Select a field and examine what it supports and where the evidence ends.
Read the raw artifact and field explanations
{
"profile": {
"protocol": "SAML 2.0",
"selected": "SP-initiated Web Browser SSO; abstract Redirect request / POST response",
"idpEntityId": "https://identity.example.org/saml",
"spEntityId": "https://atlas.example.org/saml/entity",
"acsURL": "https://atlas.example.org/saml/acs",
"oneBearerAssertion": true,
"unsolicitedAccepted": false,
"noActualXML": true,
"noActualSignature": true,
"noActualNetwork": true,
"algorithmPolicy": "Configured current library policy; no legacy 2005 algorithm recommendation adopted",
"normalIdpAuthenticationDeclared": true,
"acsRegistrationCheckedDeclared": true
},
"normal": {
"response": {
"ID": "response-A",
"Version": "2.0",
"Issuer": "https://identity.example.org/saml",
"InResponseTo": "request-A",
"Destination": "https://atlas.example.org/saml/acs",
"Status": "Success"
},
"assertion": {
"ID": "assertion-A",
"Issuer": "https://identity.example.org/saml",
"NameID": {
"format": "persistent",
"value": "subject-A",
"nameQualifier": "https://identity.example.org/saml",
"spNameQualifier": "https://atlas.example.org/saml/entity"
},
"AuthnStatementPresent": true,
"Conditions": {
"NotBefore": 1000,
"NotOnOrAfter": 1100,
"AudienceRestrictions": [
[
"https://atlas.example.org/saml/entity"
]
]
},
"SubjectConfirmation": {
"method": "bearer",
"Recipient": "https://atlas.example.org/saml/acs",
"InResponseTo": "request-A",
"NotOnOrAfter": 1080
}
},
"signature": {
"selectedCoverage": "individual-assertion",
"signedNodeAlias": "assertion-A",
"consumedNodeAlias": "assertion-A",
"trustedKeyAlias": "configured-idp-signing-key",
"keyProvenanceDeclared": true,
"cryptographicValidDeclared": true,
"schemaAndUniqueIdsDeclared": true
},
"context": {
"now": 1050,
"clockSkew": 0,
"pendingRequestId": "request-A",
"browserAlias": "browser-A",
"pendingBrowserAlias": "browser-A",
"pending": true,
"assertionPreviouslyUsed": false
}
},
"cases": [
{
"case": "normal",
"ledger": {
"response": {
"ID": "response-A",
"Version": "2.0",
"Issuer": "https://identity.example.org/saml",
"InResponseTo": "request-A",
"Destination": "https://atlas.example.org/saml/acs",
"Status": "Success"
},
"assertion": {
"ID": "assertion-A",
"Issuer": "https://identity.example.org/saml",
"NameID": {
"format": "persistent",
"value": "subject-A",
"nameQualifier": "https://identity.example.org/saml",
"spNameQualifier": "https://atlas.example.org/saml/entity"
},
"AuthnStatementPresent": true,
"Conditions": {
"NotBefore": 1000,
"NotOnOrAfter": 1100,
"AudienceRestrictions": [
[
"https://atlas.example.org/saml/entity"
]
]
},
"SubjectConfirmation": {
"method": "bearer",
"Recipient": "https://atlas.example.org/saml/acs",
"InResponseTo": "request-A",
"NotOnOrAfter": 1080
}
},
"signature": {
"selectedCoverage": "individual-assertion",
"signedNodeAlias": "assertion-A",
"consumedNodeAlias": "assertion-A",
"trustedKeyAlias": "configured-idp-signing-key",
"keyProvenanceDeclared": true,
"cryptographicValidDeclared": true,
"schemaAndUniqueIdsDeclared": true
},
"context": {
"now": 1050,
"clockSkew": 0,
"pendingRequestId": "request-A",
"browserAlias": "browser-A",
"pendingBrowserAlias": "browser-A",
"pending": true,
"assertionPreviouslyUsed": false
}
},
"expected": true
},
{
"case": "audience-denied",
"ledger": {
"response": {
"ID": "response-A",
"Version": "2.0",
"Issuer": "https://identity.example.org/saml",
"InResponseTo": "request-A",
"Destination": "https://atlas.example.org/saml/acs",
"Status": "Success"
},
"assertion": {
"ID": "assertion-A",
"Issuer": "https://identity.example.org/saml",
"NameID": {
"format": "persistent",
"value": "subject-A",
"nameQualifier": "https://identity.example.org/saml",
"spNameQualifier": "https://atlas.example.org/saml/entity"
},
"AuthnStatementPresent": true,
"Conditions": {
"NotBefore": 1000,
"NotOnOrAfter": 1100,
"AudienceRestrictions": [
[
"https://catalog.example.org/saml/entity"
]
]
},
"SubjectConfirmation": {
"method": "bearer",
"Recipient": "https://atlas.example.org/saml/acs",
"InResponseTo": "request-A",
"NotOnOrAfter": 1080
}
},
"signature": {
"selectedCoverage": "individual-assertion",
"signedNodeAlias": "assertion-A",
"consumedNodeAlias": "assertion-A",
"trustedKeyAlias": "configured-idp-signing-key",
"keyProvenanceDeclared": true,
"cryptographicValidDeclared": true,
"schemaAndUniqueIdsDeclared": true
},
"context": {
"now": 1050,
"clockSkew": 0,
"pendingRequestId": "request-A",
"browserAlias": "browser-A",
"pendingBrowserAlias": "browser-A",
"pending": true,
"assertionPreviouslyUsed": false
}
},
"expected": false
},
{
"case": "expired",
"ledger": {
"response": {
"ID": "response-A",
"Version": "2.0",
"Issuer": "https://identity.example.org/saml",
"InResponseTo": "request-A",
"Destination": "https://atlas.example.org/saml/acs",
"Status": "Success"
},
"assertion": {
"ID": "assertion-A",
"Issuer": "https://identity.example.org/saml",
"NameID": {
"format": "persistent",
"value": "subject-A",
"nameQualifier": "https://identity.example.org/saml",
"spNameQualifier": "https://atlas.example.org/saml/entity"
},
"AuthnStatementPresent": true,
"Conditions": {
"NotBefore": 1000,
"NotOnOrAfter": 1100,
"AudienceRestrictions": [
[
"https://atlas.example.org/saml/entity"
]
]
},
"SubjectConfirmation": {
"method": "bearer",
"Recipient": "https://atlas.example.org/saml/acs",
"InResponseTo": "request-A",
"NotOnOrAfter": 1080
}
},
"signature": {
"selectedCoverage": "individual-assertion",
"signedNodeAlias": "assertion-A",
"consumedNodeAlias": "assertion-A",
"trustedKeyAlias": "configured-idp-signing-key",
"keyProvenanceDeclared": true,
"cryptographicValidDeclared": true,
"schemaAndUniqueIdsDeclared": true
},
"context": {
"now": 1080,
"clockSkew": 0,
"pendingRequestId": "request-A",
"browserAlias": "browser-A",
"pendingBrowserAlias": "browser-A",
"pending": true,
"assertionPreviouslyUsed": false
}
},
"expected": false
},
{
"case": "node-denied",
"ledger": {
"response": {
"ID": "response-A",
"Version": "2.0",
"Issuer": "https://identity.example.org/saml",
"InResponseTo": "request-A",
"Destination": "https://atlas.example.org/saml/acs",
"Status": "Success"
},
"assertion": {
"ID": "assertion-A",
"Issuer": "https://identity.example.org/saml",
"NameID": {
"format": "persistent",
"value": "subject-A",
"nameQualifier": "https://identity.example.org/saml",
"spNameQualifier": "https://atlas.example.org/saml/entity"
},
"AuthnStatementPresent": true,
"Conditions": {
"NotBefore": 1000,
"NotOnOrAfter": 1100,
"AudienceRestrictions": [
[
"https://atlas.example.org/saml/entity"
]
]
},
"SubjectConfirmation": {
"method": "bearer",
"Recipient": "https://atlas.example.org/saml/acs",
"InResponseTo": "request-A",
"NotOnOrAfter": 1080
}
},
"signature": {
"selectedCoverage": "individual-assertion",
"signedNodeAlias": "assertion-A",
"consumedNodeAlias": "assertion-other",
"trustedKeyAlias": "configured-idp-signing-key",
"keyProvenanceDeclared": true,
"cryptographicValidDeclared": true,
"schemaAndUniqueIdsDeclared": true
},
"context": {
"now": 1050,
"clockSkew": 0,
"pendingRequestId": "request-A",
"browserAlias": "browser-A",
"pendingBrowserAlias": "browser-A",
"pending": true,
"assertionPreviouslyUsed": false
}
},
"expected": false
}
],
"audienceRows": [
{
"restrictions": [
[
"https://atlas.example.org/saml/entity",
"https://catalog.example.org/saml/entity"
]
],
"expected": true
},
{
"restrictions": [
[
"https://atlas.example.org/saml/entity"
],
[
"https://catalog.example.org/saml/entity"
]
],
"expected": false
},
{
"restrictions": [
[
"https://atlas.example.org/saml/entity"
],
[
"https://atlas.example.org/saml/entity",
"https://catalog.example.org/saml/entity"
]
],
"expected": true
}
],
"timeRows": [
{
"now": 999,
"expected": false
},
{
"now": 1000,
"expected": true
},
{
"now": 1079,
"expected": true
},
{
"now": 1080,
"expected": false
},
{
"now": 1100,
"expected": false
}
],
"correlationRows": [
{
"responseRequest": "request-A",
"subjectRequest": "request-A",
"browserAlias": "browser-A",
"pending": true,
"expected": true
},
{
"responseRequest": "request-B",
"subjectRequest": "request-A",
"browserAlias": "browser-A",
"pending": true,
"expected": false
},
{
"responseRequest": "request-A",
"subjectRequest": "request-B",
"browserAlias": "browser-A",
"pending": true,
"expected": false
},
{
"responseRequest": "request-A",
"subjectRequest": "request-A",
"browserAlias": "browser-B",
"pending": true,
"expected": false
}
],
"signatureCoverage": {
"approvedPOSTAlternatives": [
"individual-assertion",
"covering-response"
],
"selected": "individual-assertion",
"sameVerifiedNodeConsumedRequired": true,
"certificateInMessageIsTrustAnchor": false,
"xmlEncryptionProvidesSignature": false
},
"localSession": {
"createdOnlyAfterAllSelectedGates": true,
"newSessionSeparateFromIdpSession": true,
"assertionIdRetainedThroughConfirmationValidity": true,
"storageConcurrencyNotExecuted": true,
"roleOrTenantPolicySeparate": true
},
"timeNotation": "Integer offsets in a synthetic UTC teaching timeline; not wire xs:dateTime strings",
"subjectConfirmationQualification": {
"noNotBeforeInBearerData": true,
"confirmationWindowNotDeliveryOnly": true,
"multipleConfirmationsAnyValidOneForEachAssertion": true,
"multipleAssertionsIndependentlyValidated": true
}
}- profile
- Selected SP-initiated binding and trust contexts; XML is not executed.
- normal.response
- Response ID, Destination and request correlation.
- normal.assertion
- Subject, audience, Conditions and bearer confirmation are separate fields.
- normal.signature
- Declared trusted key and the same verified/consumed-node relationship.
- timeRows
- UTC teaching offsets; the confirmation ending instant is excluded.
An inert alias and UTC-offset table; it produces no wire XML/xs:dateTime, certificate, signature, IdP authentication, browser binding or persistent session.
Two reality checks
Every assertion in a POST response must be individually signed.
Approved E26 permits an individual Assertion signature or a covering Response signature protecting the assertions.
A response reaching the ACS is already a valid login.
The SP creates no session until trusted issuer/key, coverage, audience, recipient, request and time gates pass after receipt.
YOUR TURN
Work through this story.
Predict the outcome, find the evidence boundary, and explain it in your own words.
Conditions last until 1100, but bearer SubjectConfirmation has NotOnOrAfter=1080. With now=1080 and clockSkew=0, is the assertion accepted?
- No. The subject-confirmation boundary has been reached.
- Yes. Conditions lasting to 1100 overrides every confirmation window.
Read the explained answer
No. The subject-confirmation boundary has been reached. — NotOnOrAfter excludes equality. The longer Conditions window does not override expired subject confirmation.
Why do two audiences within one restriction differ from two separate restrictions?
Selected lesson artifact fields; teaching example
- audienceRows
- [{"restrictions":[["https://atlas.example.org/saml/entity","https://catalog.example.org/saml/entity"]],"expected":true},{"restrictions":[["https://atlas.example.org/saml/entity"],["https://catalog.example.org/saml/entity"]],"expected":false},{"restrictions":[["https://atlas.example.org/saml/entity"],["https://atlas.example.org/saml/entity","https://catalog.example.org/saml/entity"]],"expected":true}]
- Every audience list is flattened; one match anywhere is enough.
- The SP must satisfy each restriction; one candidate within a restriction is enough.
Read the explained answer
The SP must satisfy each restriction; one candidate within a restriction is enough. — Atlas matches when Atlas and catalog share one restriction. Separate restrictions reject Atlas when the second requires catalog alone.
The signature has cryptographicValidDeclared=true. Why must the SP still check signedNodeAlias/consumedNodeAlias, InResponseTo, Destination and Recipient?
Read the explained answer
Trusted key provenance and signature coverage are required; a certificate in the message is not automatically a trust anchor. The consumed business node must be bound to the verified node. InResponseTo preserves the pending request/browser transaction, while Destination and Recipient bind the proper ACS. Time, audience and usage state are checked too. The SP session is separate from the IdP session, with role/tenant permission applied separately. This typed ledger does not execute XML or signature validation.
□ I did not substitute a signature result for all assertion/context checks.
□ I separated SP session, IdP session and resource permission.
Open the application console · request / response / browser
Also open request, URL, cookie and DOM examples
Sources and scope
- OASIS SAML 2.0 — Assertions and Protocols, OASIS Standard§2.5.1.1–2.5.1.4 conditions/time/audience · §3.2.2 response ID, InResponseTo, Destination · §5.1–5.4 signature coverage/inheritance/reference and KeyInfo
- OASIS SAML 2.0 — Profiles, OASIS Standard§4.1.3.3–4.1.3.6 browser SSO roles and session choice · §4.1.4.1–4.1.4.3 request/response usage and processing · §4.1.4.5 POST; §4.1.5 unsolicited responses
- OASIS SAML 2.0 Approved Errata 05 — 1 May 2012Status and latest approved alias · E26 response/bearer/POST signature and processing clarification · E46 audience OR within / AND between restrictions · E52 subject confirmation time is RP confirmation window
- OWASP SAML Security Cheat SheetValidate Signatures: trusted schema/key provenance and security element selection · Validate Protocol Processing Rules · X.509 Certificate Considerations: IdP/SP signing trust association