Pular para o conteúdo

Audit: exportação determinística de evidências de conformidade

O módulo Audit transforma o conjunto de dados de claims de conformidade do engine em um pacote determinístico de evidências, com PII higienizada, adequado para um auditor de conformidade. Ele ordena cada coleção para gerar uma saída byte-estável, valida o pacote contra um esquema e pode projetá-lo para uma versão estável.

Estabilidade: experimental. O exporter em si é determinístico e bem testado, mas o conjunto de dados claims.json upstream que ele consome é uma matriz de conformidade em andamento (o próprio _status reflete isso). Até que o pipeline de evidências chegue a GA, trate a saída deste módulo como evidência de engenharia, não como uma atestação certificada.

Terminal window
composer require nextpdf/core:^3

AuditExporter é o único ponto de entrada. buildBundle() recebe um conjunto de dados de claims decodificado e um AuditExportContext e retorna um AuditExportBundle. buildBundleFromFile() é um atalho conveniente para carregar a partir de um arquivo. encode() serializa o pacote para JSON. A construção é puramente funcional. Com um AuditExportContext::generatedAt fixo (por exemplo, via SOURCE_DATE_EPOCH) e um conjunto de dados de claims estável, a saída é byte-idêntica entre execuções porque os claims[] são ordenados por (standard, clause_id), os evidence[] por ref_id e os clause_hashes[] por clause_id. É por isso que o perfil de reprodutibilidade é bitwise.

O pacote é uma árvore tipada: AuditExportClaim (uma claim de conformidade), AuditExportEvidence (o registro de evidência de suporte), AuditExportClauseHash (o digest do conteúdo da cláusula) e AuditExportContext (o contexto de geração). Cada um disponibiliza um toArray() para serialização.

O módulo segue privacy-by-default (privacidade por padrão). O construtor instala um DefaultPiiSanitiser (uma implementação de PiiSanitiser) que limpa as strings de metadados de evidência antes da serialização. Um sanitiser diferente pode ser injetado. O exporter valida os hashes de cláusula, os digests de evidência e as âncoras de citação RAG contra um padrão SHA-256 estrito de 64 caracteres em hexadecimal minúsculo, e emite um aviso estruturado (em vez de um descarte silencioso) quando uma cláusula não tem um hash válido ou metadados de avaliador. validateAgainstSchema() verifica o pacote construído. projectToV1() produz uma projeção v1 estável. O design do exporter está alinhado com OWASP ASVS V8.3, NIST CSF 2.0 PR.PT-1, NIST SP 800-53 r5 AU-2/AU-3 e ISO/IEC 27001 A.12.4 — esses são alinhamentos de design documentados na fonte, não claims normativas fixadas a chunks.

ClasseMembros principaisFunção
AuditExporterbuildBundle(), buildBundleFromFile(), encode(), validateAgainstSchema(), projectToV1()Builder/validator de pacote determinístico
AuditExportBundletoArray()O pacote de evidências montado
AuditExportClaimtoArray()Um registro de claim de conformidade
AuditExportEvidencetoArray()Um registro de evidência de suporte
AuditExportClauseHashtoArray()Um registro de digest do conteúdo da cláusula
AuditExportContextGENERATOR_VERSIONContexto de geração (fixe o timestamp para determinismo)
PiiSanitiser (interface)sanitise(string): stringLimpador de metadados de evidência plugável (@since 5.2.0)
DefaultPiiSanitisersanitise()Sanitiser privacy-by-default (@since 5.2.0)

Execute composer docs:generate-api-php -- --module=Audit para obter a tabela PHPDoc completa.

Crie e serialize um pacote a partir de um arquivo de claims.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Audit\AuditExportContext;
use NextPDF\Audit\AuditExporter;
$exporter = new AuditExporter();
$bundle = $exporter->buildBundleFromFile(
'/srv/nextpdf/claims.json',
new AuditExportContext(/* pin generatedAt for determinism */),
);
file_put_contents('/srv/out/audit-bundle.json', $exporter->encode($bundle));

Valide o pacote e trate avisos de esquema ou de hash como um gate rígido.

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Audit\AuditExportContext;
use NextPDF\Audit\AuditExporter;
use Psr\Log\LoggerInterface;
final readonly class EvidenceGate
{
public function __construct(
private AuditExporter $exporter,
private LoggerInterface $logger,
) {}
/** @param array<string, mixed> $claims Decoded claims dataset. */
public function export(array $claims, AuditExportContext $context): string
{
$bundle = $this->exporter->buildBundle($claims, $context);
$errors = $this->exporter->validateAgainstSchema($bundle->toArray());
if ($errors !== []) {
$this->logger->error('Audit bundle failed schema validation.', ['errors' => $errors]);
throw new \RuntimeException('Audit evidence bundle is not schema-valid; refusing to publish.');
}
return $this->exporter->encode($bundle);
}
}
  • O determinismo exige um AuditExportContext::generatedAt fixo. Sem ele, o timestamp varia e a saída não é byte-estável, anulando o perfil bitwise.
  • Uma cláusula sem um clause_hash válido de 64 caracteres hex ou sem metadados de avaliador é ignorada com um aviso estruturado, não incluída silenciosamente. Verifique os avisos; uma cláusula ignorada significa evidência ausente, não aprovação.
  • O PiiSanitiser padrão é executado, a menos que você injete outro. Desativar a higienização é uma escolha explícita com consequências de privacidade — não faça isso em uma exportação regulamentada.
  • validateAgainstSchema() é apenas consultivo, a menos que você aja sobre o que ele retorna. Trate um resultado não vazio como um erro que bloqueia a publicação em produção.
  • O pacote reflete a maturidade do conjunto de dados de entrada. Um conjunto de dados de claims em andamento (WIP) produz um pacote em andamento; o exporter não melhora a qualidade da evidência.

A construção é linear em relação ao número de claims e registros de evidência, e é dominada pela ordenação. Não há I/O em buildBundle() (o chamador é responsável pelo acesso ao arquivo). A carga de trabalho de referência padrão fica bem dentro do orçamento de 1500 ms de wall / 64 MB de pico. O perfil de reprodutibilidade é bitwise com um contexto fixo e uma entrada estável, por design.

Este módulo lida com evidências de conformidade, que podem conter metadados sensíveis. A higienização de PII está ativada por padrão (alinhamento com o Art. 32 do GDPR). Mantenha-a ativada para qualquer pacote compartilhado externamente. O exporter valida cada digest e âncora de citação contra um padrão SHA-256 estrito, de modo que um hash malformado ou truncado é rejeitado em vez de ser considerado confiável. Trate o conjunto de dados de claims de entrada como a raiz de confiança: o exporter serializa fielmente o que recebe, portanto a evidência é tão confiável quanto esse conjunto de dados. Consulte o modelo de ameaças do engine em /modules/core/security/.

Este módulo não afirma nenhuma claim normativa da especificação PDF. Ele exporta evidências sobre conformidade; ele próprio não implementa uma cláusula PDF citada. Seus alinhamentos de design (OWASP ASVS V8.3, NIST CSF 2.0, NIST SP 800-53 r5, ISO/IEC 27001 A.12.4) estão documentados na fonte e são alinhamentos de control-framework, não citações PDF fixadas a chunks. A conformidade que o pacote relata é produzida e validada pelo oracle e pelas golden suites descritos em /modules/core/conformance/.