Перейти к содержимому

Audit: детерминированный экспорт доказательств соответствия

Модуль Audit преобразует сформированный движком набор данных утверждений о соответствии в детерминированный пакет доказательств, очищенный от PII и пригодный для аудитора по соответствию. Он сортирует каждую коллекцию, чтобы вывод был побайтово стабильным, проверяет пакет по схеме и может спроецировать его на стабильную версию.

Стабильность: экспериментальная. Сам экспортёр детерминирован и хорошо протестирован, но используемый им вышестоящий набор данных claims.json — это незавершённая матрица соответствия, что отражено в её собственном поле _status. Пока конвейер доказательств не достигнет стадии GA, рассматривайте вывод этого модуля как инженерные доказательства, а не сертифицированное подтверждение.

Окно терминала
composer require nextpdf/core:^3

AuditExporter — единственная точка входа. buildBundle() принимает декодированный набор данных утверждений и AuditExportContext и возвращает AuditExportBundle. buildBundleFromFile() — удобный метод загрузки из файла. encode() сериализует пакет в JSON. Процесс сборки чисто функционален. При фиксированном AuditExportContext::generatedAt (например, через SOURCE_DATE_EPOCH) и стабильном наборе данных утверждений вывод побайтово идентичен от запуска к запуску, поскольку claims[] сортируются по (standard, clause_id), evidence[] — по ref_id, а clause_hashes[] — по clause_id. Именно поэтому профиль воспроизводимости — bitwise.

Пакет представляет собой типизированную структуру: AuditExportClaim (утверждение о соответствии), AuditExportEvidence (подтверждающая запись доказательства), AuditExportClauseHash (дайджест содержимого пункта) и AuditExportContext (контекст генерации). У каждого есть toArray() для сериализации.

Модуль по умолчанию работает с учётом конфиденциальности. Конструктор устанавливает DefaultPiiSanitiser (реализацию PiiSanitiser), который очищает строки метаданных доказательств перед сериализацией. Можно внедрить другой санитайзер. Экспортёр проверяет хеши пунктов, дайджесты доказательств и якоря цитирования RAG по строгому шаблону SHA-256: 64 шестнадцатеричных символа в нижнем регистре. Если у пункта нет действительного хеша или метаданных оценщика, экспортёр выдаёт структурированное предупреждение, а не отбрасывает его молча. validateAgainstSchema() проверяет собранный пакет. projectToV1() формирует стабильную проекцию v1. Архитектура экспортёра согласована с OWASP ASVS V8.3, NIST CSF 2.0 PR.PT-1, NIST SP 800-53 r5 AU-2/AU-3 и ISO/IEC 27001 A.12.4 — это проектные соответствия, задокументированные в исходном коде, а не нормативные утверждения, привязанные к фрагментам.

КлассКлючевые членыРоль
AuditExporterbuildBundle(), buildBundleFromFile(), encode(), validateAgainstSchema(), projectToV1()Детерминированный builder/validator пакета
AuditExportBundletoArray()Собранный пакет доказательств
AuditExportClaimtoArray()Одна запись утверждения о соответствии
AuditExportEvidencetoArray()Одна подтверждающая запись доказательства
AuditExportClauseHashtoArray()Запись дайджеста содержимого пункта
AuditExportContextGENERATOR_VERSIONКонтекст генерации (зафиксируйте отметку времени для детерминизма)
PiiSanitiser (интерфейс)sanitise(string): stringПодключаемое средство очистки метаданных доказательств (@since 5.2.0)
DefaultPiiSanitisersanitise()Санитайзер с конфиденциальностью по умолчанию (@since 5.2.0)

Запустите composer docs:generate-api-php -- --module=Audit, чтобы получить полную таблицу PHPDoc.

Соберите пакет из файла утверждений и закодируйте его.

<?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));

Проверьте пакет и считайте предупреждения о схеме или хеше жёстким барьером.

<?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);
}
}
  • Для детерминизма нужен зафиксированный AuditExportContext::generatedAt. Без него отметка времени будет меняться, и вывод не будет побайтово стабильным, что сводит на нет профиль bitwise.
  • Пункт без действительного 64-символьного шестнадцатеричного clause_hash или метаданных оценщика пропускается со структурированным предупреждением, а не включается молча. Проверяйте предупреждения: пропущенный пункт означает отсутствие доказательства, а не успешное прохождение.
  • По умолчанию используется PiiSanitiser, если вы не внедрите другой. Отключение очистки — явный выбор с последствиями для конфиденциальности; не делайте этого для регулируемого экспорта.
  • validateAgainstSchema() носит рекомендательный характер, если вы не обрабатываете возвращаемое значение. В продакшене рассматривайте непустой результат как ошибку, блокирующую публикацию.
  • Пакет отражает зрелость входного набора данных. Незавершённый набор данных утверждений даст незавершённый пакет; экспортёр не повышает качество доказательств.

Сборка линейна по числу утверждений и записей доказательств; основную работу даёт сортировка. В buildBundle() нет операций ввода-вывода: доступ к файлам обеспечивает вызывающая сторона. Эталонная нагрузка по умолчанию с большим запасом укладывается в бюджет 1500 мс по времени / 64 МБ по пику. По замыслу профиль воспроизводимости — bitwise при зафиксированном контексте и стабильном вводе.

Этот модуль работает с доказательствами соответствия, где могут быть чувствительные метаданные. Очистка PII включена по умолчанию (соответствие GDPR, ст. 32). Оставляйте её включённой для любого пакета, передаваемого вовне. Экспортёр проверяет каждый дайджест и якорь цитирования по строгому шаблону SHA-256, поэтому некорректный или усечённый хеш отклоняется, а не принимается на веру. Рассматривайте входной набор данных утверждений как корень доверия: экспортёр точно сериализует то, что ему передано, поэтому доказательства настолько же надёжны, насколько надёжен этот набор данных. См. модель угроз движка в /modules/core/security/.

Этот модуль не заявляет нормативных утверждений по спецификации PDF. Он экспортирует доказательства о соответствии; сам модуль не реализует цитируемый пункт PDF. Его проектные соответствия (OWASP ASVS V8.3, NIST CSF 2.0, NIST SP 800-53 r5, ISO/IEC 27001 A.12.4) задокументированы в исходном коде и относятся к каркасу контролей, а не к привязанным к фрагментам цитатам PDF. Соответствие, о котором сообщает пакет, формируется и проверяется наборами oracle и golden, описанными в /modules/core/conformance/.