# Task: Emitir un e-CPF con validación facial

I want my application to do what Lacuna's "Emitir un e-CPF con validación facial" demo does: Demuestre quién es con su rostro, cotejado con los registros del Gobierno, y obtenga un e-CPF de prueba, A1 o A3.

- Docs: https://docs.lacunasoftware.com/en-us/articles/amplia/integration/issue-from-csr
- Live demo: https://try.lacunasoftware.com/es/amplia/issue-an-ecpf-with-your-face
- This demo for AI agents: https://try.lacunasoftware.com/es/amplia/issue-an-ecpf-with-your-face.md

## Samples

Lacuna lists no sample for this task: rely on the docs and the call sequence below.

## Call sequence

No call sequence is recorded for this demo, so none is shown here: this page doesn't guess calls. Its first call, the Serpro check, carries a real person's CPF, name and birth date, so it is not recorded, by choice. The docs and samples below show the calls; the live demo makes them.

## Patterns to copy

- Run Serpro's Datavalid `pf-basica` check before any face capture, returning users included: the name must match exactly, the birth date match, the CPF be regular, and a CNH exist, since Datavalid compares the face with the CNH photo.
- Start a Face authentication of the CPF's digits first: one that starts is a returning user's, who never gets a Liveness check or a Datavalid call. On `BioSubjectNotFound`, run a Liveness check, with no Subject identifier, then read the face it captured with `GET api/bio/sessions/{id}/result-data`. The Demo uses a Rest PKI Core subscription of its own for these faces.
- Run the Datavalid validation yourself, from the server, on Datavalid v4's `pf-facial`, with the CPF and that face only, and sort its similarity: GoodMatch at 0.93 or more, UncertainMatch at 0.85 or more. Don't ask Rest PKI Core for it with `VerifyFaceIdentityExternally = true`: its validation still calls Datavalid v3, which Serpro refuses.
- Only on a GoodMatch, enroll that same image under the CPF's digits with `POST api/bio/enrollments` and `VerifyFaceIdentityExternally = false`. On `BioSubjectAlreadyEnrolled`, start a Face authentication instead, never replacing the enrollment.
- Hold the face in memory for the Datavalid call and the enrollment only: never store, log or show it. Never turn on the Serpro client's sensitive-data logging: it would log the face, the CPF, the name and the birth date.
- Treat the session URL and the widget's ticket as credentials: never log or show them.
- Once the face passes, issue the e-CPF from a CSR, as in the e-CNPJ flow, with no Amplia issue page and no return trip.

## What to do

Implement this in my project with its existing stack, language, framework and conventions, following the call sequence and the patterns above, and adapting the samples rather than copying them whole. Ask me before adding any dependency or package. Keep API keys and private keys out of the browser and out of the repository.
