The checklist
1
Both signatures
On success the root Response and the nested Assertion are each signed. Verify both
against the X.509 certificate published in the
live metadata.
2
Status
Success means a pass. Top-level Responder with nested AuthnFailed means a refusal —
a real, signed, deliberate “no”, with no assertion attached. Never treat a refusal as a
login.3
InResponseTo
Must match the ID of the AuthnRequest you issued. This is what stops a response captured
from an earlier login being replayed into a new one.
4
Audience
The
Conditions/AudienceRestriction must name your entityID. A response minted for a
different SP must not be accepted.5
Time conditions
Honour
NotBefore and NotOnOrAfter on both Conditions and
SubjectConfirmationData, with whatever clock skew you allow.6
Recipient and Destination
Recipient must be your ACS URL.7
Single use
Record the assertion ID and reject duplicates. This is your responsibility — the
loopback does not stand in for it, and FaceSign does not enforce it on your behalf.
What a pass does not tell you
Re-stating it here because this is the page an integrator reads while writing the code that grants access:- A pass attests a live, willing human was present. It does not attest who they are.
- An echoed NameID is the value you supplied. It is a correlation hint, not proof.
- Keep the directory-identity binding on your own first factor.
- The access decision is yours.
Deny, timeout, and unavailable
Design your fallback for three distinct situations, because they mean different things:The first two are currently indistinguishable on the wire. A status taxonomy that separates
“the check failed” from “we could not run the check” is not available in this release. If your policy needs to tell
them apart, raise it before you build against the current behaviour.
Related
Troubleshooting
Concrete errors and what they mean.