Samuel Arendt

O transparency log do Packagist torna mudanças de dependência auditáveis

O Packagist processa 100 milhões de instalações por dia. São 400 mil pacotes. E até agora, se alguém trocasse o dono de um pacote, alterasse a URL do repositório ou removesse um mantenedor, isso acontecia em silêncio.

Isso está mudando. O Packagist está implementando um transparency log — um registro público e auditável de eventos que afetam a cadeia de dependências PHP.

O que vai ser rastreado: mudanças de ownership de pacotes, alterações de URL de repositório, adição e remoção de mantenedores, releases e remoção de versões, mudanças em tags git subjacentes. No lado de contas, eventos como ativação/desativação de 2FA e resets de senha.

Tudo acessível via interface web e API. Pesquisadores, empresas e ferramentas de segurança vão poder monitorar mudanças em dependências, identificar padrões suspeitos e investigar incidentes com dados reais, não com suposição.

O projeto é financiado pela Sovereign Tech Agency, uma iniciativa do governo alemão que investe em infraestrutura open source crítica. A implementação está sendo coordenada pela PHP Foundation.

Na prática, o que muda Para quem lidera projetos PHP: visibilidade. Hoje, se uma dependência que você usa muda de mãos, você provavelmente só descobre quando algo quebra. Com o log, dá pra automatizar alertas, integrar com pipelines de CI e ter um registro auditável de tudo que aconteceu no ecossistema ao redor do seu projeto.

Isso segue o padrão Level 3 do Principles for Package Repository Security da OpenSSF. Npm já tem algo parecido. PyPI também. O PHP estava atrasado nessa frente.

Fico pensando quantas equipes PHP hoje sequer monitoram mudanças de ownership nos pacotes que usam. Meu palpite é que a maioria não monitora. E esse é exatamente o tipo de risco invisível que um transparency log torna visível.

Sem assinante, o log é arquivo morto

O anúncio descreve interface web e API. A implementação segue por etapas: eventos restantes e interfaces públicas entram aos poucos. Isso significa que o valor para um time de produto não nasce no dia do post. Nasce quando alguém assina o recorte que importa e responde a um evento.

Defina o recorte a partir do composer.lock, não a partir dos 400 mil pacotes. Pacotes diretos e transitivos que vocês realmente instalam. Ownership, URL de source, mantenedor e tag git desses nomes. Conta de um maintainer famoso que vocês não usam pode ficar de fora. O volume de ruído de um registro público é o que mata a adoção de alerta.

Nomeie um dono. Segurança, plataforma ou o time que já olha Dependabot. Sem dono, o webhook cai no canal aberto do time e vira wallpaper. Com dono, o evento vira fila: triagem, ticket, ou silêncio justificado.

Ferramentas de terceiros vão aparecer. Trate-as como qualquer outro sensor: o log público é a fonte, o vendor é o filtro. Se o filtro sumir, vocês ainda precisam consultar a API. Não terceirize a única cópia da política.

Mudança de dono e de URL merecem prioridade

Release novo é o evento mais comum e o menos informativo sozinho. Composer já mostra o bump no lockfile da PR. O que o transparency log adiciona é o que o lockfile não conta: o pacote trocou de dono, o GitHub apontado mudou, um maintainer saiu, uma tag foi reescrita, o 2FA da conta foi desligado.

Esses eventos têm densidade de risco maior. Compromisso clássico de cadeia passa por tomar a conta, apontar o source para um fork e publicar uma versão que o semver aceita. Se o alerta de vocês trata "nova tag 1.4.3" igual a "ownership transferido", o canal explode no primeiro dia útil e alguém silencia o restante.

Monte a política em duas camadas. Camada A, acordar alguém: transferência de ownership, mudança de URL, remoção de maintainer, alteração de tag já publicada, 2FA desativado na conta que publica o pacote. Camada B, registro para auditoria: releases e remoções de versão, para reconstruir linha do tempo depois. A camada B pode ir para um índice. A camada A vai para o pager ou para o checklist da PR.

Reset de senha e 2FA são eventos de conta, não de pacote. Correlacione com os pacotes que essa conta controla. Sem essa junção, o sinal fica abstrato.

Alerta no pipeline precisa filtrar release rotineiro

O lugar operacional natural é o CI que já lê composer.lock. Numa PR que atualiza dependência, consulte o log para aquele pacote no intervalo desde o último lock conhecido. Se houver evento da camada A, a PR não mistura "bump de patch" com "o source mudou". O revisor vê o fato ao lado do diff.

Fora da PR, um job diário no lock de produção pega o que ninguém atualizou. Pacote abandonado que muda de dono sem bump é o caso que o Dependabot clássico deixa passar. O log existe para esse silêncio.

Calibre volume. Se o job emitir dezenas de linhas por dia, a regra está larga demais ou o recorte inclui pacotes de dev que não vão para produção. Separe require de require-dev. Produção primeiro.

O Packagist avisa que a cobertura cresce por incrementos. O job precisa tolerar evento ainda não emitido, sem tratar ausência como "nada aconteceu no mundo". Log incompleto é melhor que silêncio total; ainda assim, documente o que já está coberto.

Pin e hash continuam sendo a defesa de instalação

Registro público não impede o composer update de baixar o tarball. Pin de versão, composer.lock commitado, composer audit e revisão de diff continuam sendo o controle que a máquina de build obedece. O log alimenta a pergunta "devemos instalar isto agora?" e a pergunta posterior "quando este pacote mudou de mãos?".

Investigação de incidente ganha história. Em vez de um print de página de pacote, a equipe pode pedir à API os eventos entre duas datas. Isso é o que o nível 3 da OpenSSF pede a repositórios: capacidade de ver o que mudou. Npm e PyPI já caminharam nessa direção. PHP chega com financiamento da Sovereign Tech Agency e coordenação da PHP Foundation. O próximo bloco anunciado, ownership organizacional, ataca a conta compartilhada que hoje impede 2FA de verdade.

Nada disso substitui o hábito de não dar update cego em pacote que autentica usuário. O log torna o hábito verificável. Sem assinante, sem recorte e sem distinção entre bump e troca de dono, o registro público fica disponível para pesquisador e invisível para o time que instala 100 milhões de vezes por dia, no agregado, e zero vezes com alerta, no projeto de vocês.

Referências

#Arquitetura, #Operações, #Qualidade de Software