# Assinatura eletrônica

<https://unifokal.com/docs/modulos/assinatura>

## Assinatura eletrônica

! **Ainda não está aberto para venda.** O módulo aparece na [tabela de preços](https://unifokal.com/precos) com preço e com o selo "Em breve", e o `create` de flow o recusa até a abertura. O contrato de resposta abaixo é o que o backend já emite, para você planejar a integração.

O módulo `assinatura` transforma a verificação aprovada em **assinatura eletrônica avançada** do documento que você indicar. Você cria a sessão com o hash SHA-256 do documento; o titular passa pela verificação de identidade completa (documento, face match e prova de vida, que o flow exige junto); e, se a verificação aprovar, a plataforma emite o **dossiê de assinatura**: um manifesto que amarra o hash do documento à verificação aprovada e ao instante, assinado com a chave Ed25519 da plataforma. **O documento em si nunca é enviado**: você continua guardando os bytes, e o hash não revela o conteúdo.

```
// criação de sessão com o bloco assinatura (obrigatório quando o flow tem o módulo)
POST /v1/verification-sessions
{ "flow_id": "flow_...", "reference_id": "contrato-8841",
  "assinatura": { "document_sha256": "f2ca1bb6c7e907d06dafe4687e579fce76b37e4e93b7605022da52e6ccc26fd2" } }
```

**Por link, um a um ou em lote.** O link de verificação hospedado aceita o mesmo bloco `assinatura` em `POST /v1/verification-links`, e o hash fica fixo no link desde a emissão. No painel, uma planilha com `reference_id` e `document_sha256` por linha gera um link por linha; o arquivo com os links sai uma única vez. Quem avisa o signatário é você. Para acompanhar cada etapa, o webhook do flow recebe `verification_link.claimed` quando o signatário abre o link e começa a verificação (um aviso por link, com `link_id`, `session_id` e o seu `reference_id`), e `verification.completed` com o dossiê quando ele assina.

```
// assinatura no check_details: o dossiê completo
{ "module": "assinatura", "passed": true, "outcome": "approved",
  "data": { "assinatura": {
      "signed": true,
      "document_sha256": "f2ca1bb6...cc26fd2",   // o hash que você mandou na criação
      "algorithm": "Ed25519",
      "key_id": "1f60c078f27b",                   // identifica a chave da plataforma
      "public_key": "SGVsbG8t...",                // chave pública, base64 (32 bytes)
      "signed_at": "2026-09-07T12:00:00.000Z",
      "manifest_json": "{\"v\":1,\"type\":\"unifokal/assinatura-avancada@1\",...}",
      "signature": "kqYw3...==" } } }             // assinatura do manifest_json, base64
```

**Qualquer pessoa confere o dossiê, sem nos consultar.** A âncora é a lista de chaves públicas da UNIFOKAL logo abaixo: a chave que viaja no dossiê (`public_key`, com o `key_id`) só vale se for igual a uma chave da lista, já em vigor no instante `signed_at`. A assinatura cobre exatamente os bytes UTF-8 de `manifest_json` (use a string literal recebida, nunca uma re-serialização sua: outra ordem de campos muda os bytes). Depois, o `document_sha256` do manifesto tem de ser o SHA-256 do seu contrato: se qualquer byte do documento mudar depois, o hash muda e o dossiê deixa de casar com ele. É essa a detecção de alteração posterior que a lei exige.

```
// chaves públicas da assinatura (Ed25519, 32 bytes em base64). A âncora é ESTA lista:
// a chave que viaja no dossiê só vale se for igual a uma destas, já em vigor em signed_at.
ASSINATURA_PUBLIC_KEYS = []
// A chave de produção entra nesta lista antes da abertura da venda.
```

```
// Node 20+ (só node:crypto, sem rede)
const { createPublicKey, verify, createHash } = require("node:crypto");
const SPKI = Buffer.from("302a300506032b6570032100", "hex");

function confereDossie(dossie, contrato, pinadas) {
  const k = pinadas.find((p) => p.key_id === dossie.key_id && p.public_key === dossie.public_key &&
    p.environment === "production" && dossie.signed_at >= p.not_before);
  if (!k) return false; // chave fora da lista: o dossiê não foi emitido pela UNIFOKAL
  const chave = createPublicKey({ key: Buffer.concat([SPKI, Buffer.from(k.public_key, "base64")]), format: "der", type: "spki" });
  if (!verify(null, Buffer.from(dossie.manifest_json, "utf8"), chave, Buffer.from(dossie.signature, "base64"))) return false;
  const m = JSON.parse(dossie.manifest_json);
  return m.type === "unifokal/assinatura-avancada@1" && m.decision === "approved" &&
    m.signed_at === dossie.signed_at && m.document_sha256 === dossie.document_sha256 &&
    m.document_sha256 === createHash("sha256").update(contrato).digest("hex");
}
```

! **Avançada, não qualificada.** É assinatura eletrônica AVANÇADA nos termos da MP 2.200-2 (art. 10, § 2º) e da Lei 14.063 (art. 4º, II): vale entre particulares quando as partes a aceitam, e a associação unívoca ao signatário é a verificação biométrica. Atos que exigem assinatura QUALIFICADA com certificado ICP-Brasil, como nota fiscal eletrônica e transferência de imóvel, precisam de outro instrumento. Não emitimos assinatura eletrônica qualificada. Não emitimos carimbo de tempo RFC 3161 nesta fase.

**Consignado do trabalhador.** Desde 25 de julho de 2025, as instituições consignatárias devem adotar **verificação biométrica da identidade do trabalhador** nas operações de crédito consignado feitas por plataforma digital (Lei 10.820/2003, art. 2º-I, incluído pela Lei 15.179/2025), com **prova de vida** (Decreto 12.564/2025, art. 2º, I). O contrato digital pode ser firmado por assinatura qualificada ou por assinatura **avançada**, e a avançada precisa cumprir, junto com a Lei 14.063, dois requisitos: **autenticação biométrica com prova de vida no ato da assinatura** e **geração de evidências técnicas** que comprovem a autenticação e a integridade do ato, utilizáveis em processo administrativo ou judicial (Lei 10.820, art. 2º-I, § 3º, I e II; Decreto 12.564, art. 3º, II, alíneas a e b). Os dois valem para quem contrata daqui em diante por assinatura avançada que não estava homologada em 25 de julho de 2025: o § 4º do mesmo artigo considera adequadas também a avançada já homologada pelo Poder Executivo federal ou pelo Poder Judiciário naquela data e a assinatura digital nos termos do regulamento (Decreto 12.564, art. 3º, III).

O módulo entrega as duas coisas no mesmo fluxo: a verificação com documento, face match e prova de vida acontece no ato em que o trabalhador assina, e o dossiê que amarra o hash do contrato à identidade verificada e ao instante é a evidência técnica, que qualquer pessoa confere com a chave pública publicada pela UNIFOKAL, sem nos consultar. A guarda do dossiê é da consignatária: ele chega inteiro no webhook para você arquivar pelo prazo do seu contrato. Não emitimos assinatura eletrônica qualificada.

**Quando não cobra.** O dossiê só existe se a verificação aprovar. Verificação recusada ou em revisão devolve `"signed": false` com o motivo nomeado (`verification_not_approved`) e o módulo sai do preço daquela verificação. O bloco `assinatura` da criação é obrigatório quando o flow contém o módulo (422 `assinatura_document_required`) e recusado quando não contém (422 `assinatura_not_supported`): nunca aceito e ignorado em silêncio. O link hospedado não leva o documento: a emissão de link para um flow com o módulo é recusada com o mesmo 422 `assinatura_document_required`, e a sessão desse flow nasce pela API.
