Aller au contenu
getnextpdf.com

Enterprise édition

Validation — référence approfondie

Le module Validation exécute des politiques de conformité structurelles prédéfinies, en lecture seule, sur les octets bruts d’un PDF. Compliance::assess() applique exactement une CompliancePolicy et renvoie un ComplianceReport contenant des constats partitionnés par gravité et une clause de non-responsabilité juridique obligatoire. Des politiques sont fournies pour PDF/A-4 (ainsi que les variantes e et f), la structure PAdES baseline, un profil structurel eIDAS, la santé LTV/DSS, ZUGFeRD / Factur-X, la FDA 21 CFR Part 11 et l’archivage WORM au titre de la règle SEC 17a-4. Chaque politique est une fonction pure : des octets en entrée, des constats en sortie. La validation ne modifie jamais le document et n’effectue jamais de vérification cryptographique.

Cette fonctionnalité est fournie dans NextPDF Enterprise (nextpdf/enterprise) et s’active avec une enveloppe de licence de niveau Enterprise. Un déploiement dépourvu de ce droit ne charge pas les classes de la fonctionnalité. Compare les éditions et obtiens une licence.

La surface Validation/Evidence est concédée sous licence par la capacité enterprise.compliance.evidence. Un droit refusé refuse la fonctionnalité plutôt que de se dégrader silencieusement.

NiveauSurface de validation
CoreValidateurs de flux d’octets en cours de processus et vérification croisée de la grammaire ; un résultat sans constat est un résultat vérifié, pas un certificat.
ProValidation EN 16931 / Factur-X / ZUGFeRD en cours de processus au niveau de la facture électronique ; aucune politique prédéfinie PDF/A-4, PAdES, LTV, FDA ou SEC.
EnterprisePolitiques structurelles prédéfinies pour PDF/A-4, PAdES, LTV, ZUGFeRD, FDA Part 11 et SEC 17a-4 avec un rapport unifié (ce module).

La passerelle sidecar externe Enterprise Compliance est un module séparé et distinct.

Fenêtre de terminal
composer require nextpdf/enterprise:^3
SymboleParamètresComportement par défautRetourneLève ou échoue avecRemarques
Compliance::__construct?ClockInterface $clock = nullHorloge système lorsqu’aucune horloge n’est injectéeForme d’instance compatible avec l’injection de dépendances ; l’horloge horodate validatedAt
Compliance::runstring $pdfData, CompliancePolicy $policy, array $context = []Applique exactement une politique et mesure la durée d’horloge muraleComplianceReportPropage les exceptions des politiques personnalisées ; les politiques intégrées collectent les constats au lieu de lever une exceptionMéthode d’instance
Compliance::assess (statique)string $pdfData, CompliancePolicy $policy, array $context = []Construit une instance par défaut et délègue à run()ComplianceReportIdentique à run()Voie rapide sans configuration
Policies::pdfA4 / ::pdfA4e / ::pdfA4f (statique)Politique structurelle PDF/A-4 selon ISO 19005-4:2020CompliancePolicye autorise les annotations 3D/rich-media ; f ajoute des vérifications de relation de fichiers incorporés
Policies::padesBaseline (statique)Vérifications structurelles PAdES B-BCompliancePolicyStructure uniquement ; aucune vérification cryptographique
Policies::eidasQualified (statique)Vérifications structurelles PAdES sous un profil étiqueté eIDASCompliancePolicyLa qualification dépend du TSP et du certificat qualifié
Policies::ltvHealth (statique)Vérification de santé structurelle du DSSCompliancePolicyPrésence du DSS résolue à partir du graphe d’objets actif, sécurisation par défaut
Policies::zugferd (statique)string $profile = 'BASIC'Normalise l’alias de profil et construit le validateur ZUGFeRDCompliancePolicy\ValueError (profil inconnu)Profils : MINIMUM, BASIC, BASIC_WL, EN16931, EXTENDED
Policies::fdaPart11 (statique)Politique structurelle FDA 21 CFR Part 11CompliancePolicySept vérifications structurelles, dont l’intégrité de la chaîne de hachage de la piste d’audit
Policies::sec17a4 / ::sec17a4Compatible / ::sec17a4Structural / ::sec17a4PreSign (statique)Politique WORM SEC 17a-4 au niveau de rigueur nomméCompliancePolicyLa rigueur correspond à WormComplianceLevel
CompliancePolicy (interface)Contrat de stratégie pour une normegetName(), getIdentifier(), getStandardReference(), validate() ; implémentable par le client
ComplianceReportObjet-valeur en lecture seuleConstats partitionnés par gravité à la constructionpasses(), fails(), totalFindings(), getDisclaimer() ; findings, errors, warnings, infos, policyName, policyId, standard, validatedAt, durationMs publics
ComplianceFindingSeverity $severity, string $ruleId, string $message, string $clause = '', string $suggestion = ''Résultat d’une règle avec référence de clause et conseil de remédiationerror() / warning() / info() statiques ; isError()
Severity (enum)3 cas adossés à des chaînesError, Warning, InfoSeul Error fait échouer un rapport
WormComplianceLevel (enum)4 cas adossés à des chaînesFull, Compatible, Structural, PreSignrequiresSignature(), requiresDocMdp(), requiresLtv(), maxDocMdpLevel()
PdfAPolicy, PadesValidator, LtvHealthCheck, ZugferdValidator, Sec17a4WormPolicy, Fda\FdaPart11PolicyConstructeurs propres à chaque classeImplémentent CompliancePolicy pour une norme chacunelist<ComplianceFinding> depuis validate()À obtenir via Policies ; Sec17a4WormPolicy::getLevel() expose la rigueur configurée
Fda\FdaSigningIntent (enum)6 cas adossés à des chaînesAuthoring, Review, Approval, Certification, Verification, RejectiontoPdfReasonString() produit la chaîne /Reason canonique
Fda\FdaAuditEvent::__constructDateTimeImmutable $timestamp, string $actor, FdaSigningIntent $action, string $documentHash, string $certificateSerial, string $previousEventHash = ''Calcule le hachage de chaîne SHA-256 à la constructionInvalidArgumentException (horodatage non-UTC)eventHash public ; toXmpRdf() sérialise un élément de liste XMP
Fda\FdaAuditTrail::addEventFdaAuditEvent $eventAjoute l’événement lorsque son maillon de chaîne correspond à la fin de la pisteselfInvalidArgumentException (chaîne de hachage rompue)Également createEvent(), verifyChain(), getLastEventHash(), getEvents(), embedInMetadata()
Fda\FdaSignatureEnforcer::configureSeedValueFdaSigningIntent $intent, string $tsaUrlConstruit une configuration de valeurs de départ de signature contrainte par la FDASeedValueConfigExige l’ensemble de motifs FDA, un horodatage et des condensats SHA-256 ou plus robustes
Fda\FdaSignatureEnforcer::applyToSequentialSigner $signer, SigningStrategy $strategy, string $signerName, FdaSigningIntent $intent, string $tsaUrl, string $fieldName = '', ?string $reason = nullAjoute un signataire contraint par la FDA à un SequentialSigner ProSequentialSignerSérialise les contraintes dans le champ de signature produit
namespace NextPDF\Enterprise\Validation;
final readonly class Compliance
{
public function __construct(?ClockInterface $clock = null);
/** @param array<string, mixed> $context */
public function run(string $pdfData, CompliancePolicy $policy, array $context = []): ComplianceReport;
/** @param array<string, mixed> $context */
public static function assess(string $pdfData, CompliancePolicy $policy, array $context = []): ComplianceReport;
}
final class Policies
{
public static function pdfA4(): CompliancePolicy; // also pdfA4e(), pdfA4f()
public static function padesBaseline(): CompliancePolicy;
public static function eidasQualified(): CompliancePolicy;
public static function ltvHealth(): CompliancePolicy;
public static function zugferd(string $profile = 'BASIC'): CompliancePolicy;
public static function fdaPart11(): CompliancePolicy;
public static function sec17a4(): CompliancePolicy; // also sec17a4Compatible(), sec17a4Structural(), sec17a4PreSign()
}
interface CompliancePolicy
{
public function getName(): string;
public function getIdentifier(): string;
public function getStandardReference(): string;
/**
* @param array<string, mixed> $context
* @return list<ComplianceFinding>
*/
public function validate(string $pdfData, array $context = []): array;
}
final readonly class ComplianceReport
{
public const string LEGAL_DISCLAIMER;
public function passes(): bool;
public function fails(): bool;
public function totalFindings(): int;
public function getDisclaimer(): string;
}

Compliance::assess() (statique) et Compliance::run() (instance, avec un Psr\Clock\ClockInterface injectable) appliquent exactement une politique et renvoient un ComplianceReport. Règles observables de l’extérieur :

  • Lecture seule pure. Chaque CompliancePolicy::validate() est une fonction pure : des octets en entrée, des constats en sortie. Une politique ne modifie jamais les octets d’un PDF. Cet invariant architectural garde la validation distincte de la correction automatique et du module Evidence.
  • Filtre de gravité. ComplianceReport::passes() n’est vrai que lorsque errors === []. Les avertissements et les infos ne font jamais échouer un rapport. fails() est le complément.
  • Clause de non-responsabilité obligatoire. ComplianceReport::getDisclaimer() renvoie le texte constant de la clause de non-responsabilité juridique. Le contrat exige de l’afficher dans toute sortie destinée à l’utilisateur.
  • Provenance du rapport. Le rapport porte le nom, l’identifiant et la référence de norme de la politique, l’horodatage de validation issu de l’horloge injectée ou système, et la durée mesurée en millisecondes.
  • Collecter, ne pas interrompre. Les politiques intégrées exécutent toutes les vérifications applicables et collectent chaque constat plutôt que de s’arrêter à la première erreur.
  • DSS uniquement atteignable via le catalogue. LtvHealthCheck résout la présence du DSS à partir du graphe d’objets actif : trailer actif, puis catalogue /Root, puis /DSS et ses sous-clés. Les octets-marqueurs plantés dans des commentaires, des chaînes, des objets orphelins ou des révisions remplacées ne comptent pas. Une entrée non analysable est traitée comme une absence de DSS, si bien que la vérification se sécurise par défaut. La vérification est structurelle ; elle ne vérifie pas cryptographiquement les données OCSP/CRL incorporées.
  • Vérifications structurelles de signature. Policies::padesBaseline() et Policies::eidasQualified() valident la structure PAdES au seul niveau du PDF. La qualification au titre d’eIDAS dépend du TSP et du certificat qualifié, qui sont hors de ce module.
  • Les politiques des secteurs réglementés sont structurelles. FdaPart11Policy vérifie la présence de signature, l’intention /Reason, l’heure de signature /M, l’identité /Name, l’absence de JavaScript, l’espace de noms de la piste d’audit FDA et l’intégrité de la chaîne de hachage. Sec17a4WormPolicy vérifie jusqu’à 13 règles WORM ; WormComplianceLevel sélectionne la rigueur. Full exige DocMDP niveau 1, Compatible accepte le niveau 2, et Structural / PreSign ignorent les règles de signature, DocMDP et DSS. Aucune de ces politiques n’établit une conformité juridique.
  • Contexte ZUGFeRD. Policies::zugferd() vérifie toujours les exigences au niveau du PDF. Elle valide le XML de facture uniquement lorsque l’appelant passe ['xml' => $xmlData] dans $context ; sinon elle émet le constat d’information zugferd-xml-skipped.
  • Piste d’audit inviolable. FdaAuditTrail est une chaîne de hachage SHA-256 à ajout seul. addEvent() rejette un maillon rompu, verifyChain() redérive chaque hachage, et embedInMetadata() écrit la piste dans le XMP sous http://ns.nextpdf.dev/fda/1.0/ avec un schéma d’extension PDF/A.
  • Une entrée non-PDF ou vide produit des constats d’erreur plutôt qu’une exception dans les politiques intégrées. Vérifie toujours passes() et affiche la clause de non-responsabilité.
  • Policies::zugferd() normalise les alias de profil (BASIC_WL, EN16931, EN_16931). Un profil inconnu lève \ValueError au moment de la fabrique, avant l’exécution de toute validation.
  • Un DSS avec des CRL mais sans réponses OCSP satisfait la vérification du matériel de révocation ; le constat indique l’alternative acceptable. L’absence des deux constitue une erreur.
  • Un dictionnaire /VRI ou un tableau /Certs manquant produit des avertissements, pas des erreurs ; le rapport peut tout de même réussir.
  • FdaAuditEvent rejette tout horodatage non-UTC avec InvalidArgumentException à la construction.
  • FdaAuditTrail::verifyChain() renvoie faux pour tout événement altéré ou réordonné ; elle ne lève jamais d’exception.
  • Les implémentations personnalisées de CompliancePolicy peuvent lever une exception depuis validate() ; Compliance::run() ne l’intercepte pas, si bien que ces exceptions se propagent à l’appelant.

Ce module n’effectue aucune signature, aucune vérification cryptographique et aucune conservation de clé. La politique d’algorithmes en mode FIPS est régie par les modules Security et Signature. Les valeurs de départ de FdaSignatureEnforcer contraignent les champs de signature liés à la FDA aux méthodes de condensation SHA-256, SHA-384 ou SHA-512.

Ces politiques vérifient des attributs structurels par rapport aux normes citées. Le verdict de conformité pour les profils ISO/ETSI reste une propriété du fichier final combiné à un validateur externe.

ComportementRéférence
Conformité déterminée par rapport à la norme, pas au producteurISO 19005-4:2020 §5.2
Dictionnaire de signature numérique / DSS pour la validation à long termeISO 32000-2:2020 §12.8
Le DSS est un dictionnaire détenu par la clé DSS du catalogue du documentISO 32000-2:2020 §12.8.4.3
Niveaux de signature PAdES baselineETSI EN 319 142-1 §5.4.3
Modèle sémantique du profil EN 16931 (référence de soutien)Factur-X 1.08 (EN 16931)

Les politiques FDA 21 CFR Part 11 et SEC 17a-4 vérifient uniquement des attributs structurels ; ces réglementations sont hors du corpus de vérification et ne portent aucune affirmation de conformité vérifiée. Les chaînes de clause figurant dans les constats FDA (par exemple §11.50, §11.10(e)) sont des références de règle émises par le produit. La ligne EN 16931 est une référence de soutien située sous le seuil de récupération ; ce n’est pas une affirmation de conformité ferme. La prise en charge d’une norme n’est pas la conformité à celle-ci, et la conformité n’est pas la certification — NextPDF ne détient aucune certification et n’en accorde aucune. Cette référence n’est pas un avis juridique ; consulte ton équipe de conformité pour la suffisance juridique.

  • La validation s’exécute en cours de processus et en local, sans E/S réseau. Une politique ne peut pas altérer l’entrée.
  • Traite les octets d’un PDF issu de sources non fiables comme hostiles. Les politiques intégrées sont totales sur des octets arbitraires et se sécurisent par défaut lorsque la structure ne peut pas être résolue.
  • Affiche ComplianceReport::getDisclaimer() dans chaque rendu d’un rapport destiné à l’utilisateur.
  • Les rapports et les constats peuvent porter des données personnelles issues des documents signés et des métadonnées de la piste d’audit (noms des signataires, numéros de série des certificats). L’exploitant est responsable des contrôles de rétention et de minimisation.
  • Les politiques personnalisées implémentent CompliancePolicy ; garde getIdentifier() unique pour toutes les politiques afin d’assurer la sérialisation et la mise en cache.
  • Ce module concerne une fonctionnalité cryptographique ; traite-le comme sensible du point de vue de la sécurité dans ta propre revue.
  • Le détail des mécanismes internes reste dans la documentation interne du dépôt source et sort du périmètre de ce manuel.

Cette page documente uniquement le comportement observable de l’extérieur et la surface d’API publique prise en charge. Les chemins d’espaces de noms internes, les classes utilitaires, les tables de mécanismes, les noms de fichiers de runbook et les préfixes de tickets sont hors périmètre.