Hacker DirectoryHacker Directory

WEB / WEB-15.S02

Introduction to the SAML federation model

Bind an IdP authentication result to SP transaction, recipient and signature contexts.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mechanism

Read every scenario without motion

Normal SSO

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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

  1. 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
  2. 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
  3. 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
  4. 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
  5. 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
  6. 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?

  1. No. The subject-confirmation boundary has been reached.
  2. 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}]
  1. Every audience list is flattened; one match anywhere is enough.
  2. 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