# Task: Cadastre e autentique seu rosto

I want my application to do what Lacuna's "Cadastre e autentique seu rosto" demo does: Cadastre seu rosto com a sua câmera e depois autentique-o um a um contra esse cadastro, com o Rest PKI Core.

- Docs: https://docs.lacunasoftware.com/pt-br/articles/rest-pki/core/integration/bio-sessions
- Live demo: https://try.lacunasoftware.com/pt/lacuna-bio/enroll-and-authenticate-your-face
- This demo for AI agents: https://try.lacunasoftware.com/pt/lacuna-bio/enroll-and-authenticate-your-face.md

## Samples

- Lacuna's samples for this product: https://github.com/LacunaSoftware/RestBioSamples

## Call sequence

Recorded on 2026-10-12 against the real products with Lacuna's public test certificates and data. Keys, tokens, sessions, ids, file contents and personal data are masked.

### 1. Rest PKI Core starts a Face enrollment session for the Demo's random Subject identifier, with the page's origin as trusted origin and Datavalid off; the browser gets the session URL alone.

On the server: `IRestBioService.StartEnrollmentSessionAsync`

`POST https://core.pki.rest/api/bio/sessions/enrollment` → 200

Request:

```json
{
  "SubjectIdentifier": "***",
  "CaptureIdentificationDocument": false,
  "DangerousOverrideIfAlreadyEnrolled": false,
  "VerifyFaceIdentityExternally": false,
  "TrustedOrigin": "https://try.lacunasoftware.com/",
  "PlatformPreference": 2
}
```

Response:

```json
{
  "sessionType": "Enrollment",
  "sessionId": "***",
  "sessionUrl": "***"
}
```

### 2. Lacuna's capture widget opens the session URL over the page and gives back a ticket to complete the enrollment with; it needs a person, so the rest, authentication included, is not recorded.

In the browser: `widget.performBioSession(sessionUrl)`

## Patterns to copy

- Enrollment and authentication are two separate sessions, each start (server), capture (browser widget), complete (server), tied together only by the Subject identifier: trim it and keep it within 200 characters.
- On an enrollment, always set `VerifyFaceIdentityExternally` explicitly: left unset, the subscription's default decides whether Datavalid runs.
- `RestPkiExceptionV2` with `BioSubjectAlreadyEnrolled` (enroll) or `BioSubjectNotFound` (authenticate) is an expected answer with no session started: send the user to the other step. The Demo never sends the override that replaces an enrollment.
- The identifier names a person: never log it, and log only Rest PKI Core's error code, never the client's exception message. Treat the session URL and the widget's ticket as credentials too.

## 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.
