You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
licensing: âncora ML-DSA embutida ausente e híbrido ainda opcional no guard (canon: Ed25519 + ML-DSA obrigatório) #2042
Canon do operador (repetido várias vezes): a licença do Boar e de todo o roster bestial é híbrida Ed25519 + ML-DSA-65, obrigatória — é o modo mínimo de licença, não uma opção. Em 2026-10-05 um levantamento dos verificadores mostrou onde o data-boar ainda não cumpre isso. Estado verificado via gh api em DataBoar/data-boar@main, não pelo clone local.
O que existe hoje
Âncora ML-DSA ausente.core/licensing/ traz só license-pub-v1.pem (Ed25519). guard.py carrega a âncora por trust_anchor.load_embedded_mldsa_anchor_pem(), que não tem arquivo para ler. Os consumidores irmãos já documentam essa espera: faithful-ferret (trust_anchor.clj: "data-boar main does not ship license-mldsa-pub-v1.pem") e sage-remora (trust_anchor.clj, mesma frase). O resultado nos dois foi um verificador que recusava ou degradava, até que cada um vendorizou a chave por conta própria.
Híbrido opcional no verify/guard.core/licensing/guard.py::_token_has_mldsa_claim diz no docstring: "only an absent key selects Ed25519-only verification". Token sem dbmldsa_sig verifica só com Ed25519. verify.py descreve o claim como "Optional hybrid PQC claim".
Cadeia verificada em 2026-10-05 com kp-license-check -verify-cross-sign: OK Ed25519 signs ML-DSA-65 pubkey e OK ML-DSA-65 signs Ed25519 pubkey (PKIX DER).
O kp-license-check já é obrigatório (verifyTokenHybridRequired). O sage-remora está na branch fix/hybrid-license-required (commit d474be2, sem push) e o faithful-ferret recebe a mesma correção.
Escopo proposto (cada item é um commit)
Vendorizar core/licensing/license-mldsa-pub-v1.pem = a chave canônica acima, com teste que fixa o sha256.
dbmldsa_sig ausente deixa de selecionar Ed25519-only: token sem a claim é inválido. null, vazio e não-string já falham fechado.
Âncora ausente = falha fechada, sem cair para Ed25519.
Atualizar docs e docstrings que descrevem o híbrido como opcional.
Cuidado de compatibilidade
Tornar o híbrido obrigatório rejeita licenças emitidas só com Ed25519 (por exemplo os .lic curtos antigos). O release 1.7.4 GA já saiu com o híbrido opcional, então isso é mudança de comportamento para 1.8.x. Precisa de nota no CHANGELOG e de um caminho de reemissão. O emissor de dev tem issue própria (ver "Relacionado").
Fora de escopo
Rotação de chave. O contrato de rotação (attestation assinada pelas duas âncoras) já existe e não muda.
Relacionado
Épico #1462 (crypto agility + hybrid PQC). KP#375 (Remora recusava o JWT híbrido por falta da âncora). Emissor de dev sem ML-DSA: issue irmã.
Verifique antes de implementar: gh api repos/DataBoar/data-boar/contents/core/licensing/guard.py (as linhas citadas acima) — não confiar no clone local.
Atualização de escopo (auditoria, tom recomendatório) — verificado contra origin/main @ 9fdd2434, 2026-10-19.
Canon confirmado pelo operador: toda licença é híbrida Ed25519 + ML-DSA-65, sem modo opcional. Não há decisão pendente aqui; o que resta é fechar o que a main ainda não cumpre.
Ainda aberto (confirmar por símbolo com git grep -n, as linhas mudaram):
core/licensing/guard.py::_token_has_mldsa_claim — o docstring ainda diz que só a chave ausente seleciona verificação Ed25519-only; core/licensing/verify.py::decode_license_jwt_hybrid e o comentário de CLAIM_MLDSA_SIG ("Optional hybrid PQC claim") descrevem o híbrido como opcional. Token sem a claim precisa ser inválido, e âncora ausente também falha fechada (sem queda para Ed25519).
Docs/docstrings que chamam o híbrido de opcional (inclui LICENSING_SPEC).
CHANGELOG + caminho de reemissão: o 1.7.4 GA saiu com o híbrido opcional, então licenças só-Ed25519 deixam de valer em 1.8.x.
Recomendações:
Teste vermelho primeiro: token sem dbmldsa_sig recusado; depois a correção.
Resolvida pela PR #2114 (merge 87f1fe0). Commit 0c0adbb: em modo enforced, dbmldsa_sig é obrigatório e âncora ML-DSA ausente falha fechada. Testes em tests/test_decode_license_jwt_hybrid_invalid_mldsa_claim.py: test_license_guard_missing_mldsa_anchor_is_invalid e a rejeição hybrid_claim_required. Verificação via Robin segue em homing-robin#75, fora deste escopo.
Activity
FabioLeitao commentedon Oct 20, 2026
Atualização de escopo (auditoria, tom recomendatório) — verificado contra
origin/main@9fdd2434, 2026-10-19.Canon confirmado pelo operador: toda licença é híbrida Ed25519 + ML-DSA-65, sem modo opcional. Não há decisão pendente aqui; o que resta é fechar o que a main ainda não cumpre.
Já feito na main (marcar no escopo):
core/licensing/license-mldsa-pub-v1.pem+trust_anchor.py(feat(licensing): vendor ML-DSA-65 trust anchor + PLANS_TODO entry for shell hardening (#2042, #1926) #2075).dbmldsa_sigpresente e inválida falha fechada (fix(licensing): fail-closed on present invalid dbmldsa_sig (#1996) #2002); rotação cruzada sem override de chave crua (security(licensing): cross-signed key rotation, no raw key override #1994).Ainda aberto (confirmar por símbolo com
git grep -n, as linhas mudaram):core/licensing/guard.py::_token_has_mldsa_claim— o docstring ainda diz que só a chave ausente seleciona verificação Ed25519-only;core/licensing/verify.py::decode_license_jwt_hybride o comentário deCLAIM_MLDSA_SIG("Optional hybrid PQC claim") descrevem o híbrido como opcional. Token sem a claim precisa ser inválido, e âncora ausente também falha fechada (sem queda para Ed25519).LICENSING_SPEC).Recomendações:
dbmldsa_sigrecusado; depois a correção.-tags licensetestdokp-license-check.Closessó quando os critérios de aceite forem cumpridos de fato.Rodapé: comentário gerado por Claude (auditor RO), sem alteração de código.
FabioLeitao commentedon Oct 20, 2026
Resolvida pela PR #2114 (merge 87f1fe0). Commit 0c0adbb: em modo enforced, dbmldsa_sig é obrigatório e âncora ML-DSA ausente falha fechada. Testes em tests/test_decode_license_jwt_hybrid_invalid_mldsa_claim.py: test_license_guard_missing_mldsa_anchor_is_invalid e a rejeição hybrid_claim_required. Verificação via Robin segue em homing-robin#75, fora deste escopo.