Salta ai contenuti
getnextpdf.com

Enterprise edizione

Compliance — Riferimento approfondito

Il modulo Compliance instrada un PDF finito verso un sidecar di convalida esterno e restituisce un unico risultato normalizzato. ComplianceGateway risolve il sidecar responsabile a partire da un ComplianceProfile, applica una politica di disponibilità fail-closed e incapsula ogni verdetto degli strumenti in un ExternalValidationResult. Sono forniti bridge per veraPDF (PDF/A, PDF/UA, PDF 2.0 Arlington), EU DSS (livelli PAdES), il sidecar combinato Mustang/KoSIT (ZUGFeRD, Factur-X, EN 16931) e un daemon KoSIT autonomo. Il modulo fornisce inoltre la stampigliatura di readiness AiReadyCertifier e un runner per la suite di test ufficiale KoSIT XRechnung.

Questa capability è inclusa in NextPDF Enterprise (nextpdf/enterprise) e si attiva con un envelope di licenza di tier Enterprise. Un deployment privo di tale entitlement non carica le classi della capability. Confronta le edizioni e ottieni una licenza.

La superficie Compliance/Evidence è concessa in licenza dalla capability enterprise.compliance.evidence. Un entitlement mancante o scaduto nega la funzionalità; non ne degrada silenziosamente il comportamento.

TierSuperficie Compliance
CoreControlli di byte-stream e di grammatica in-process; nessuna delega a sidecar esterni.
ProConvalida EN 16931 / Factur-X / ZUGFeRD in-process; nessun sidecar esterno.
EnterpriseGateway di validatori esterni (questo modulo) con un risultato unificato e una politica fail-closed.

Il validatore di fatture elettroniche in-process di Pro e il sidecar ZUGFeRD esterno di Enterprise sono superfici distinte. Il gateway di validatori esterni è incluso esclusivamente nel pacchetto nextpdf/enterprise.

Terminal window
composer require nextpdf/enterprise:^3
SimboloParametriComportamento predefinitoRestituisceSolleva o fallisce conNote
ComplianceGateway::__constructlist<ExternalValidator> $validators, LoggerInterface $logger, bool $optional = falseIndicizza i validatori per nome dello strumentoLa modalità facoltativa riduce il controllo di disponibilità a solo avviso
ComplianceGateway::validatestring $pdfContent, ComplianceProfile $profile, array $options = []Risolve il validatore tramite ComplianceProfile::toolName(), verifica la disponibilità, delega?ExternalValidationResultComplianceSidecarUnavailableException; InvalidArgumentException (nessun validatore registrato per lo strumento)Restituisce null solo in modalità facoltativa con il sidecar non disponibile
ComplianceGateway::validateAllProfilesstring $pdfContent, string $toolNameConvalida ogni profilo mappato sullo strumentolist<ExternalValidationResult>Come validate()Salta i risultati null (modalità facoltativa)
ComplianceGateway::healthCheckSonda l’endpoint di salute di ogni sidecar registratoarray<string, bool>Riporta la raggiungibilità; non convalida alcun documento
ComplianceGateway::buildComplianceMatrix (statico)list<ExternalValidationResult> $results, string $commitShaRiduce i risultati a una matrice con versione di schemaarray<string, mixed>Versione di schema 1.0; registra l’output degli strumenti, non asserisce nulla
ComplianceProfile (enum)15 casi con backing stringMappa ogni profilo su un’etichetta di standard e uno strumentostandardReference(): string, toolName(): string
ExternalValidator (interfaccia)Contratto di bridge dei sidecar su PSR-18validate() solleva ComplianceSidecarUnavailableException in caso di errore di trasportogetToolName(), isAvailable(), validate()
VeraPdfValidator::validateFirma dell’interfacciaPOST multipart al sidecar REST veraPDF; parsing del report JSONExternalValidationResultComplianceSidecarUnavailableException; InvalidArgumentException (profilo non supportato)PDF/A, PDF/UA, Arlington; analizza solo JSON, mai XML
DssValidator::validateFirma dell’interfacciaPOST JSON in Base64 al sidecar REST EU DSSExternalValidationResultComplianceSidecarUnavailableException; InvalidArgumentException (profilo non supportato)PAdES da B-B a B-LTA; il costruttore rifiuta timeout inferiori a un secondo
ZugferdExternalValidator::validateFirma dell’interfacciaPOST multipart al sidecar combinato Mustang/KoSITExternalValidationResultComplianceSidecarUnavailableException (anche con circuit breaker aperto); InvalidArgumentException (profilo non supportato)ZUGFeRD 2.4, Factur-X 1.08, EN 16931; circuit breaker iniettato facoltativo
KoSitValidator::validateFirma dell’interfacciaPOST XML grezzo a un daemon KoSIT autonomoExternalValidationResultComplianceSidecarUnavailableException; InvalidArgumentException (profilo non supportato)Solo EN 16931; analizza il report SVRL Schematron in modalità fail-closed
ExternalValidationResultValue object readonlyVerdetto normalizzato dello strumentopasses(), fails(), nonConformanceCount(), toComplianceMatrix()
NonConformanceValue object readonlySingola rilevazione con id regola, clausola, gravità, posizionetoArray()
ComplianceSidecarUnavailableExceptionstring $toolName, string $endpoint, int $code = 0, ?Throwable $previous = nullSegnale fail-closed di indisponibilità del sidecartoolName e endpoint readonly pubblici
AiReadyCertifier::certifystring $pdfBytesValuta tre criteri di readiness; stampiglia la provenienza XMParray{0: AiReadyCertification, 1: string}InvalidArgumentException (la stampigliatura richiede una tabella di cross-reference classica)Il secondo elemento è uguale all’input quando il livello è not_certified
AiReadyCertificationValue object readonlyValutazione di readiness con livello, numero di criteri, problemi, hash di origineEtichetta di readiness interna, non una certificazione di standard
XRechnungTestSuiteRunner::__constructstring $suitePath, ExternalValidator $validator, bool $useCuratedNegativeFallback = trueRisolve la directory della suite estrattaInvalidArgumentException (la directory non esiste)Mira alla suite di test ufficiale KoSIT XRechnung
XRechnungTestSuiteRunner::runbool $stopOnFirstFailure = falseConvalida ogni istanza della suite tramite il bridgeXRechnungTestSuiteResultXRechnungTestSuiteException (validatore non disponibile; nessun file XML)Anche isAvailable(), getSuitePath(), discoverTestFiles()
XRechnungTestSuiteResultValue object readonlyEsito aggregato della suiteallPassed(), totalCount(), getFailures(), getErrors(), toSummary()
XRechnungTestCaseResultValue object readonlyEsito per singolo casopassed(), hasError(), getFilename()
XRechnungTestSuiteExceptionCostruttori staticiSegnale di errore a runtime della suiteselfvalidatorUnavailable(), noTestFilesFound(string $suitePath)
namespace NextPDF\Enterprise\Compliance;
final class ComplianceGateway
{
/** @param list<ExternalValidator> $validators */
public function __construct(
array $validators,
private readonly LoggerInterface $logger,
private readonly bool $optional = false,
);
/** @param array<string, mixed> $options */
public function validate(
string $pdfContent,
ComplianceProfile $profile,
array $options = [],
): ?ExternalValidationResult;
/** @return list<ExternalValidationResult> */
public function validateAllProfiles(string $pdfContent, string $toolName): array;
/** @return array<string, bool> */
public function healthCheck(): array;
/**
* @param list<ExternalValidationResult> $results
* @return array<string, mixed>
*/
public static function buildComplianceMatrix(array $results, string $commitSha): array;
}
interface ExternalValidator
{
public function getToolName(): string;
public function isAvailable(): bool;
/** @param array<string, mixed> $options */
public function validate(
string $pdfContent,
ComplianceProfile $profile,
array $options = [],
): ExternalValidationResult;
}
enum ComplianceProfile: string
{
case PdfA1b = 'pdfa-1b';
// PdfA2b, PdfA3b, PdfA4, PdfA4f, PdfUa1, PdfUa2, Pdf20Arlington,
// PadesBasic, PadesTimestamp, PadesLongTerm, PadesArchive,
// Zugferd24, FacturX108, En16931
public function standardReference(): string;
public function toolName(): string;
}
final class AiReadyCertifier
{
/** @return array{0: AiReadyCertification, 1: string} Tuple of [certification, stamped PDF bytes] */
public function certify(string $pdfBytes): array;
}

ComplianceGateway::validate() risolve l’ExternalValidator registrato il cui getToolName() corrisponde a ComplianceProfile::toolName(), verifica isAvailable(), delega e restituisce un ExternalValidationResult normalizzato. Regole osservabili dall’esterno:

  • Impostazione predefinita fail-closed. Quando il sidecar risolto non è disponibile e la modalità facoltativa è disattivata, la chiamata solleva ComplianceSidecarUnavailableException. Il documento non viene controllato; non viene mai trattato come superato.
  • Modalità facoltativa. Costruire il gateway con optional: true (gli operatori lo collegano dalla variabile d’ambiente NEXTPDF_COMPLIANCE_OPTIONAL) riduce un sidecar non disponibile a un avviso registrato e a un ritorno null. I chiamanti devono trattare null come «non controllato». La modalità facoltativa copre solo la sonda di disponibilità preliminare; un errore di trasporto durante la chiamata di convalida stessa solleva ComplianceSidecarUnavailableException in entrambe le modalità.
  • Profilo sconosciuto. Un profilo privo di validatore registrato solleva InvalidArgumentException; non passa mai silenziosamente.
  • Semantica di superamento. ExternalValidationResult::passes() richiede che conformant sia true e zero non conformità. Ogni risultato riporta il profilo, il nome e la versione dello strumento, il numero di asserzioni, le rilevazioni, lo SHA-256 dei byte convalidati, un timestamp UTC e la durata della chiamata.
  • La matrice è un registro, non un’asserzione. buildComplianceMatrix() è un reducer statico che produce una struttura con versione di schema con le versioni degli strumenti e una commit SHA per la tracciabilità. Registra l’output degli strumenti; non asserisce nulla.
  • Flusso dei dati. L’intero byte stream del PDF viene trasmesso al sidecar configurato tramite un client PSR-18. Ogni convalida viene registrata tramite PSR-3 con profilo, strumento, esito (pass/fail), numero di asserzioni e durata.

Instradamento profilo-strumento, come restituito da ComplianceProfile::standardReference() e ::toolName():

Casi di profiloRiferimento allo standardStrumento
pdfa-1b, pdfa-2b, pdfa-3b, pdfa-4, pdfa-4fISO 19005-1/-2/-3/-4 (Livello B; Livello F per 4f)veraPDF
pdfua-1, pdfua-2ISO 14289-1:2014, ISO 14289-2:2024veraPDF
pdf20-arlingtonISO 32000-2:2020 (modello Arlington)veraPDF
pades-b-b, pades-b-t, pades-b-lt, pades-b-ltaETSI EN 319 142-1 da B-B a B-LTAEU DSS
zugferd-2.4, factur-x-1.08, en-16931ZUGFeRD 2.4 / Factur-X 1.08 / EN 16931-1:2017Mustang/KoSIT

AiReadyCertifier::certify() valuta tre criteri: presenza strutturale della firma, salute LTV e assenza di cifratura. Tre criteri superati producono il livello certified; uno o due producono partial; zero produce not_certified. Con certified o partial, aggiunge un aggiornamento incrementale che trasporta uno stream di provenienza XMP e un override del Catalog; i byte originali non vengono mai mutati. Il livello «certified» è un’etichetta di readiness interna a NextPDF, non una certificazione di standard.

VeraPdfValidator analizza solo risposte JSON del sidecar (nessun XML; XXE-clean per costruzione). KoSitValidator analizza il report SVRL XML del daemon con le dichiarazioni DOCTYPE rifiutate e l’accesso di rete disabilitato, e tratta un report non analizzabile come un fallimento della chiamata.

  • Un timeout del sidecar o un errore di trasporto emerge come ComplianceSidecarUnavailableException dal bridge; si applica l’impostazione predefinita fail-closed.
  • Una risposta non-200 del sidecar produce un risultato di fallimento con una rilevazione specifica dello strumento (ad esempio VERAPDF-HTTP-ERROR); non è mai un superamento di conformità.
  • Un corpo JSON o XML del sidecar malformato è un errore di convalida della chiamata, non un superamento di conformità.
  • I risultati EU DSS senza firme falliscono con DSS-NO-SIGNATURES. Un’indicazione diversa da TOTAL_PASSED fallisce con DSS-SIG-INVALID. Un livello di firma inferiore alla baseline attesa fallisce con DSS-LEVEL-MISMATCH.
  • DssValidator pubblica il proprio budget di timeout per richiesta su ogni richiesta tramite l’header X-NextPDF-Timeout-Seconds; il client PSR-18 dell’integratore deve rispettarlo affinché un sidecar bloccato non possa bloccare il thread chiamante senza limiti.
  • ZugferdExternalValidator instrada facoltativamente le chiamate al sidecar attraverso un circuit breaker iniettato; un breaker aperto viene mappato su ComplianceSidecarUnavailableException (fail-fast, comunque fail-closed). L’impostazione predefinita è un breaker no-op.
  • KoSitValidator::isAvailable() accetta HTTP 200 e 405 dalla sonda di salute del daemon; il daemon risponde a GET con 405 quando è in salute.
  • La stampigliatura di AiReadyCertifier fallisce in modalità closed con InvalidArgumentException quando il documento originale è privo di una tabella di cross-reference classica (ad esempio, cross-reference stream).
  • XRechnungTestSuiteRunner::run() rifiuta di eseguire quando il validatore non è disponibile o la suite non contiene file XML; con useCuratedNegativeFallback abilitato sostituisce un corpus negativo curato quando la suite non fornisce istanze non valide.

Questo modulo non esegue alcuna firma né custodia delle chiavi. La politica di algoritmo in modalità FIPS è governata dai moduli Security e Signature. La conformità della firma è delegata a EU DSS, che effettua la propria determinazione.

Il gateway delega il verdetto di conformità a uno strumento esterno; la progettazione riflette il confine stabilito dagli standard stessi, secondo cui la conformità è determinata rispetto ai requisiti e non asserita da un produttore.

ComportamentoRiferimento
Obbligo del processore conforme; conformità determinata rispetto allo standardISO 19005-4:2020 §5.2
Requisiti del file PDF/A-4 vs. autodichiarazione del produttoreISO 19005-4:2020 §6.6.4
La conformità PDF/UA-2 è una proprietà del fileISO 14289-2:2024 §6
Livelli di firma baseline PAdESETSI EN 319 142-1 §5.4.3

Lo strumento esterno produce il verdetto. NextPDF non detiene alcuna certificazione e non ne concede alcuna; il supporto di un profilo non equivale alla conformità ad esso. I risultati di convalida sono registri tecnici di controllo strutturale a scopo di riferimento, non pareri legali; consultare il proprio team di conformità per valutare la sufficienza normativa.

  • L’operatore ospita e gestisce i sidecar, ne fissa (pin) le versioni, ne limita la raggiungibilità di rete, ne convalida il TLS e controlla l’ambiente che abilita la modalità facoltativa. Gli endpoint dei sidecar sono un confine di fiducia; i controlli di residenza e conservazione per documenti, risultati e log sono responsabilità dell’operatore.
  • L’output di buildComplianceMatrix() è progettato per la tracciabilità in CI: fissa (pin) la commit SHA e archivia la matrice accanto agli artefatti di build.
  • Il runner XRechnung si aspetta la suite di test ufficiale estratta in una directory locale; il messaggio del suo costruttore indica la fonte di download pubblica.
  • I dettagli sui meccanismi interni restano nella documentazione interna del repository sorgente e sono fuori ambito per questo manuale.

Questa pagina documenta esclusivamente il comportamento osservabile dall’esterno e la superficie API pubblica supportata. I percorsi di namespace interni, le classi helper, le tabelle dei meccanismi, i nomi di file di runbook e i prefissi di ticket sono fuori ambito.