Skip to main content

Fail-closed by design

Success with verified_human is issued only for a complete session with liveness detected and intent confirmed. Any strong deepfake signal vetoes the pass outright. Missing evidence produces a denial, never a pass. If the analysis backing a verdict cannot be completed, FaceSign refuses rather than issuing an assertion that skipped a security layer.

Scope of the attestation

A verified_human verdict attests that a real, willing person is present. It does not attest that the person is the directory identity your service provider authenticated.
This boundary is deliberate. FaceSign holds no directory and performs no one-to-one match against a user record — it answers presence and intent, and nothing else. That is what makes it safe to place in front of an account your SP has already authenticated: FaceSign cannot become a second, weaker source of identity truth. The practical consequence is on the <Subject> NameID. When your AuthnRequest carries one, FaceSign echoes it back in the assertion — for explicitly registered service providers only. That echo binds the assertion to the identity you supplied; it is not independent confirmation of it. Any SP that treats an echoed NameID as proof of identity has built an impersonation path. Keep the directory binding on your own first factor.

Responsibilities

Replay rejection is worth calling out: it is a standard SAML service-provider responsibility and FaceSign does not enforce it on your behalf. Record assertion IDs and reject duplicates.

Limits to design for

If your platform enforces its own hard timeout on the redirect, set it comfortably above five minutes, or ask us to lower the authentication deadline to sit inside yours. Mismatched deadlines are the most common cause of an integration appearing to fail for reasons unrelated to verification.

Current limitations

Stated plainly so you can design around them rather than discover them. Signed AuthnRequests are not supported. The metadata declares WantAuthnRequestsSigned="false". If your SP signs by default and cannot be configured otherwise, raise it before integration begins. Denial reasons are not differentiated on the wire. A refused verification and a verdict we could not produce currently return the same signed status-only shape. If your fallback policy needs to treat “the check failed” differently from “the check could not run”, tell us — it changes what we expose. facesign.repudiationArtifactPresent is reserved. The field is present and currently always "false". Do not branch on it.

Assurance posture

What has been validated, and how, so a security reviewer can judge the evidence rather than take a claim on trust. Validated against FaceSign’s loopback service provider. A real SP-initiated round-trip completes against the live IdP, with signature and audience validated at the loopback ACS. Both the root Response and the nested Assertion are signed on success. A refusal returns signed, status-only SAML with no assertion. Subject echo is refused for service providers not registered for it. Validated independently. The success and denial contracts have been reproduced offline against a third-party php-saml service provider — signatures verified against the published certificate, with correct Audience, Recipient and Conditions. Reproduce it yourself. Run the sandbox, capture the response at your own ACS, and verify both signatures against the certificate in the live metadata. If your service provider validates only one of the two signatures, it will accept material this implementation considers invalid. Your own integration is validated when you validate it. Interoperability with any specific service provider is established by registering your sandbox SP and running a joint test — see Test the live sandbox. We do not claim it before you have seen it.

Service health

Service health checks that the IdP can generate metadata and that its signing key matches the certificate it advertises. It does not run an end-to-end verification, so it cannot tell you a round-trip will succeed. A failing signing-key check means assertions issued since the last deploy may be unverifiable at your ACS — that is an incident, not a status colour.