Especificação dos formatos humanproof
16. A revisão 2
Desde 2026-10-30 os quatro formatos têm uma revisão 2, marcada pelo membro "revisao": 2. Não é formato novo: formato continua humanproof/1, humanproof-acesso/1, humanproof-ponto/2 e humanproof-ancoragem/1. Objeto sem revisao é da revisão 1 e segue as seções 6 a 10 e 15; objeto com revisao 2 segue as seções 16 a 20; qualquer outro valor de revisao DEVE ser recusado. Canonicalização, hash e cadeia (seções 3, 4 e 9) são os mesmos nas duas revisões, e uma cadeia pode ter recibos das duas.
Data de corte: 2026-10-30T05:21:39Z, o instante em que o emissor da Hummand passou a emitir a revisão 2. Um recibo do ato sem revisao com ts_concluido posterior a esse instante DEVE ser recusado na coerência, mesmo com a assinatura válida: depois do corte, a revisão 1 não serve para fugir das regras da 2. Os recibos da revisão 1 concluídos até o corte continuam válidos.
Data de corte do ponto: 2026-11-01T22:51:16Z, o instante em que o emissor deixou de emitir o humanproof-ponto/1 e o /2 sem revisao. Um ponto sem revisao com ts posterior a esse instante, ou com ts que não é RFC 3339, DEVE ser recusado na coerência, mesmo com a assinatura válida, pelo mesmo motivo do recibo: sem o corte, o ponto da revisão 1, que não tem validade por chave, serviria para fugir da revogação da revisão 2. É outra data porque o ponto da revisão 1 continuou saindo depois do corte do recibo. Os pontos sem revisao emitidos até esse instante continuam válidos.
Schemas da revisão 2: humanproof-1-revisao-2.schema.json e humanproof-acesso-1-revisao-2.schema.json, fechados como os da revisão 1.
16.1 Assinaturas
Na revisão 2, kid, alg e assinatura saem e entra assinaturas, uma lista de { papel, kid, alg, valor }:
- cada entrada assina o JCS de
{ "recibo": <o objeto sem o membro assinaturas>, "assinatura": { "papel", "kid", "alg" } }, de modo que o papel, a chave e o algoritmo de cada assinatura ficam cobertos por ela mesma, e outra assinatura pode entrar depois sem invalidar as anteriores; valorcom a codificação da seção 5;- papéis:
emissor, obrigatório, e os reservadosemissor_complementar,testemunhaecliente. O verificador DEVE exigir ao menos uma assinaturaemissore DEVE conferir todas as que houver; - o hash do objeto (seção 4) continua sendo o do JCS do objeto inteiro, com as assinaturas.
A mesma regra vale para o recibo de acesso e para o ponto da revisão 2.
16.2 Chaves com validade
Na revisão 2, cada chave do JWKS PODE trazer valida_de, valida_ate, estado (ativa, aposentada ou comprometida) e, quando comprometida, comprometida_desde. O verificador DEVE recusar a assinatura cuja chave, no instante ts_emitido do objeto, ainda não valia, já não valia ou estava comprometida; estado desconhecido também é recusa. A validade por chave é admitida pelo formato, não exigida: chave sem esses membros vale sempre, como na revisão 1, e não ter prazo declarado não torna a chave inválida. A chave atual do emissor não tem prazo declarado. kid repetido no JWKS DEVE ser recusado, porque o verificador teria de escolher uma das chaves. Uma chave aposentada continua publicada no JWKS do emissor, para que recibos antigos continuem conferíveis depois de uma troca.
17. O recibo do ato, revisão 2
| Membro | Conteúdo |
|---|---|
formato, revisao |
"humanproof/1" e 2 |
recibo_id, ato_id |
identificadores opacos |
emissor |
{ id, jwks_uri }: quem emitiu e onde estão as chaves |
tenant |
{ id, nome_publico } |
tipo |
tipo do ato, como na revisão 1 |
resultado |
positivo, negativo, expirado, cancelado, falhou ou revogado |
motivo |
null no positivo; nos demais, um código do registro daquele resultado (17.1) |
nivel |
{ exigido, atingido }, inteiros de 0 a 3: o que a política pedia e o que o ato atingiu |
politica |
{ versao, hash }: a versão e o hash do JCS da política aplicada ao tipo |
sujeito |
ref_compromisso e ref_sal, juntos ou ambos ausentes, e referencia quando houve comparação (17.2) |
contexto |
{ hash, chaves_declaradas }, com as chaves em ordem e sem repetição |
consentimentos |
[{ camada, versao, idioma, texto_hash, ts }], com camada em geral, biometrico ou escopo (17.3) |
etapas |
[{ nome, resultado, ts, medido }]; medido diz se o instante foi medido ou herdado do fim do ato |
fontes |
[{ fonte, fornecedor, componente, versao_componente, versao_adaptador, ambiente, certificacao? }]; versao_componente pode ser nao_informada; certificacao = { esquema, laboratorio, relatorio, data } |
garantias |
humano_vivo, mesma_pessoa_da_referencia, identidade_civil e consentiu, cada uma { valor, sustentada_por }; biometria_retida, sempre false (17.4) |
evidencia_tecnica |
o que a fonte mediu, sem escore: deteccao_ataque, deteccao_injecao e dispositivo quando houver, e politica_de_limiar com o id e o hash da política de comparação, nunca os valores calibrados |
participantes |
[{ papel, ref_compromisso, ref_sal, presenca_recibo_hash? }], com ref_compromisso e ref_sal calculados como em 17.2, com papel em sujeito, assistente, mandatario, testemunha, revisor ou operador |
revisao_humana |
null ou { via, revisor, protocolo, ts } (17.5) |
mandato |
null ou exatamente um de concessao, uso e revogacao (17.6) |
ingredientes |
[{ papel, alg, hash }]: o termo exibido, o documento anexo, o gatilho e outras evidências, só pelo hash |
ts_criado, ts_concluido, ts_emitido |
RFC 3339 em UTC com milissegundos; ts_emitido é o instante da assinatura |
expira_em |
o prazo do ato |
retencao |
{ ate, base }: até quando o emissor guarda o registro do ato, e por qual base |
prev_hash |
hash do recibo anterior do tenant, ou o gênesis de atos (seção 4) |
assinaturas |
seção 16.1 |
Opcionais: inclusao, reservado para a prova de inclusão num log; extensoes, um mapa { "<espaço de nomes>": { ... } }; e crit, a lista das extensões que o verificador precisa entender. Extensão citada em crit e ausente, ou citada e desconhecida do verificador, DEVE ser recusada; as demais extensões PODEM ser ignoradas.
17.1 Motivos por resultado
resultado |
motivo |
|---|---|
positivo |
null |
negativo |
presenca_negada, comparacao_negada, identidade_negada, passkey_negada, consentimento_recusado, revisao_negou, mandato_invalido, mandato_revogado, mandato_vencido, fora_de_escopo |
expirado |
prazo |
cancelado |
cancelado_pelo_cliente, cancelado_pela_pessoa |
falhou |
falha_tecnica_fonte, falha_tecnica_emissor |
revogado |
revogado_pelo_mandante |
17.2 O compromisso da referência
O recibo não traz a referência que o cliente deu à pessoa, como CPF, matrícula ou número de benefício. Traz:
ref_sal: 16 bytes aleatórios, novos a cada recibo, em 32 hexadecimais;ref_compromisso="sha256:" + hex(HMAC-SHA256(chave, bytes(ref_sal) || UTF-8(referência))), em quechaveé a chave de referência do tenant, de 32 bytes, ebytes(ref_sal)são os 16 bytes que o hexadecimal representa.
Sem a chave, o compromisso não revela a referência nem liga dois recibos da mesma pessoa, porque o sal muda; referencia.hash, quando presente, é igual em recibos que usaram a mesma imagem. Com a chave, que o cliente obtém no painel, ele recalcula o compromisso a partir da referência e confere sozinho que o recibo é daquela pessoa. referencia, quando houve comparação, é { tipo, origem, hash, anexada_em }: o hash da imagem de referência usada, a origem (api, painel, ato_anterior ou base_oficial) e quando ela foi anexada. Quem guardou a imagem confere o hash.
17.3 O texto do consentimento
texto_hash é hash(JCS(texto)): o SHA-256 da forma canônica da string do texto que a pessoa viu, na versão e no idioma indicados. Os textos estão publicados em https://hummand.com.br/consentimentos, com o hash de cada um, e um texto publicado não muda: redação nova é versão nova. ts é o instante em que o emissor registrou o aceite, pelo relógio dele. É a diferença para a revisão 1, cujo texto_hash era o hash do identificador do consentimento (seção 6).
17.4 Quem sustenta cada garantia
valor é verdadeiro, falso ou null (a etapa não ocorreu). sustentada_por diz de onde vem a afirmação: componente (o componente técnico da fonte), revisao (revisão humana), declaracao_cliente, base_oficial ou mandato; é null exatamente quando valor é null.
17.5 Revisão humana
via é emissor ou cliente. Na revisão pelo emissor, revisor é o hash do recibo em que quem revisou provou a própria presença; na revisão pelo cliente, é apikey:<id>, a chave com que a integração decidiu. A revisão decide o ato, não a presença: nenhuma garantia biométrica é sustentada por revisao.
17.6 Mandato
concessao:{ escopo, mandatario }, nos tiposmandato.pessoaemandato.agente.escopotrazacoes,limitestipados ({ valor, unidade, moeda?, janela? }),validade_ateerevogavel;mandatariotraztipo(pessoaouagente, coerente com o tipo do ato),ref_compromissoeref_sal, calculados como em 17.2, e PODE trazerchave_agente.uso:{ mandato_recibo_hash, acao, valores_hash, executor, nonce, expira_em, chave_agente?, verificacao }, no tipoato.delegado, comverificacao={ valido, dentro_escopo, dentro_validade, revogado }.revogacao:{ mandato_recibo_hash }, no resultadorevogado.
O mandato é apontado pelo hash do recibo da concessão, não por um id: quem tem os dois recibos confere que um aponta para o outro.
18. Coerência da revisão 2
Além do schema e das assinaturas (16.1 e 16.2), o verificador DEVE aplicar:
motivonullexatamente no positivo, e do registro do resultado nos demais (17.1).- Positivo exige
nivel.atingido≥nivel.exigidoe todas as etapasok. - Positivo de nível 2 ou mais, fora do
ato.delegado, exige etapapresencaokehumano_vivoverdadeiro sustentado porcomponente, com a fontehummand.presencadeclarada. Comsujeito.referencia, exige também etapacomparacaookemesma_pessoa_da_referenciaverdadeira sustentada porcomponente. - Positivo de nível 3 exige
identidade_civilverdadeira sustentada porbase_oficial. Positivo de nível 1 exige etapapasskeyok. ato.delegadoé sempre de nível 0: não há humano novo.- Garantia
nullsemsustentada_por, e garantia afirmada comsustentada_por. Nenhuma garantia biométrica sustentada porrevisao. - Etapa biométrica (
presenca,comparacao) exige consentimento da camadabiometricoanterior a ela econsentiuverdadeiro. - Nenhuma etapa repetida;
ts_criado≤ts_concluido≤ts_emitido; etapas e consentimentos não posteriores ats_concluido; etapas em ordem não decrescente. contexto.chaves_declaradasem ordem e sem repetição;ref_compromissoeref_saljuntos.revisao_humanasó em positivo ou negativo; pelo emissor, com o hash de um recibo; pelo cliente, comapikey:.operador.dupla: a dupla aprovação são duas posições encadeadas, e só a que fecha o par lista operadores. Quando o recibo lista dois ou mais participantesoperador, são no máximo dois, comref_compromissodiferentes (pessoas distintas), e o primeiro trazpresenca_recibo_hash, o hash do recibo da posição anterior; o segundo é o próprio ato e não traz presença. Com menos de dois operadores listados (a primeira posição), a regra não se aplica.- Mandato: cada variante no tipo de 17.6;
ato.delegadoexigeuso; o uso é positivo exatamente quando a verificação autoriza (as três primeiras afirmações verdadeiras erevogadofalso), com omotivosustentado por ela, e não conclui positivo depois deexpira_em; a concessão temvalidade_ateposterior ats_criado. critcomo na seção 17.
Como na revisão 1, coerência é ausência de contradição interna, não confirmação externa.
19. Acesso e ponto, revisão 2
Recibo de acesso. O mesmo papel da seção 8, com revisao 2, emissor, ts_emitido e assinaturas (16.1), e:
ato_recibo_hash: o hash do recibo do ato cuja evidência foi aberta, além doato_id;motivo_hash=hash(JCS({ "motivo": <texto>, "sal": <motivo_sal> })), commotivo_salno próprio recibo: sem o sal, o mesmo motivo daria o mesmo hash em todos os acessos;- cada componente traz também
conteudo_hash, o hash do que foi entregue, emodo,telaouarquivo; cada um pode sernull.
A coerência da seção 8 vale igual.
Ponto de conferência. O humanproof-ponto/2 da revisão 2 ganha revisao, emissor, assinaturas e ponto_anterior_hash, o hash do ponto anterior do mesmo tenant (null no primeiro): os pontos de um tenant formam uma cadeia, e um ponto suprimido do meio fica visível para quem guardou os vizinhos. cadeias passa a ser um mapa aberto, em que atos e acessos são obrigatórios e outras cadeias podem entrar depois. O ts vai em milissegundos. A conferência de um lote contra o ponto é a da seção 10.
20. Ancoragem, revisão 2
A prova humanproof-ancoragem/1 da revisão 2 traz, além do que a seção 15 descreve, revisao, arvore, tamanho e cabeca_anterior:
- Árvore completada. As folhas reais, pontos e recibos como na seção 15, são seguidas de folhas de preenchimento até
tamanho, a menor potência de dois que é ao mesmo tempo ≥ 1024 e ≥ o número de folhas reais. A folha de preenchimentoiéSHA-256(0x00 || "humanproof-ancoragem/1:preenchimento:" || i), comiem decimal. Assim o tamanho da árvore não revela quantos clientes e recibos houve no ciclo.arvoreé a raiz dessa árvore, e o caminho tem exatamente log2(tamanho) irmãos. - Cabeça encadeada. O carimbo da ACT cobre a cabeça, não a árvore:
cabeça = SHA-256(0x02 || cabeça anterior || arvore || tamanho), com a cabeça anterior em 32 bytes (32 zeros no primeiro ciclo) etamanhoem 8 bytes big-endian.raizé essa cabeça, ecabeca_anterioré a do ciclo anterior, ounull. - Lista pública. O emissor publica as cabeças dos ciclos em
https://gateway.hummand.com.br/v1/ancoragens/cabecas, com a árvore, o tamanho, a anterior e o carimbo de cada uma. Quem guarda a lista vê que cada ciclo cobre o anterior e que o emissor não carimbou duas histórias.
Conferir a prova da revisão 2: as etapas da seção 15, com a folha subindo até arvore em vez de raiz; o caminho com o comprimento da árvore completa; tamanho potência de dois e ≥ 1024; e raiz igual à cabeça calculada de cabeca_anterior, arvore e tamanho.
Estado em produção. A ancoragem ainda não está ativa em produção; a lista existe e fica vazia até lá.