Enforce capture limits while draining both subprocess pipes, kill and reap interrupted validators, and bound report allocation before parsing. Preserve result precedence and add synthetic-process regressions with EN/DE documentation. Refs #2
86 lines
6.3 KiB
Markdown
86 lines
6.3 KiB
Markdown
# Inbound XRechnung validation
|
|
|
|
This module validates an inbound XML invoice through a locally installed, exact KoSIT validator profile. It does not choose the active standard release, download validation artifacts at runtime, approve a payable, or book an invoice.
|
|
|
|
## Pinned profile
|
|
|
|
An administrator records the XRechnung version, validator version, configuration release, absolute Java and JAR paths, JAR SHA-256, configuration root and complete deterministic tree SHA-256, scenario file, and expected minimum validation-step count. Every run rechecks the executable and both artifact digests. Symbolic links and files outside the configuration root are rejected.
|
|
|
|
## Deployment-owned profile allow-list
|
|
|
|
`KoSITProfileRegistry` allows a deployment to approve several exact profiles
|
|
without GovOPlaN choosing a standard version. Each approval binds the verified
|
|
artifact digest, approving actor, decision reference, receive-time window, and
|
|
the state `approved`, `suspended`, or `retired`. A deployment may configure one
|
|
explicit default, or require the invoking workflow to select a profile every
|
|
time. A default is never inferred.
|
|
|
|
Selection uses the invoice receive time, which permits an administrator to
|
|
model an overlap or transition window. Suspended, retired, unknown, expired,
|
|
not-yet-valid, or subsequently modified profiles fail closed. Artifact digests
|
|
are rechecked on selection and again during validation.
|
|
|
|
Administrierende können damit mehrere konkrete Profile zeitlich begrenzt
|
|
freigeben, ohne dass GovOPlaN eine XRechnungs-Version vorgibt. Übergangsfristen
|
|
und ein Standardprofil sind ausdrücklich konfigurierte Entscheidungen. Ohne
|
|
Standard muss jeder aufrufende Prozess ein freigegebenes Profil benennen.
|
|
|
|
The configuration tree must be installed through deployment governance. A newer published release never becomes active automatically. Updating any artifact creates a different profile digest and requires regression evidence with accepted, rejected, malformed, and deliberately broken technical fixtures.
|
|
|
|
## Fail-closed validation
|
|
|
|
Inbound XML is size-bounded and parsed with external entities and DTD processing disabled before Java runs. KoSIT runs without a shell, with an absolute executable, fixed argument vector, bounded time, bounded captured output, and an isolated result directory.
|
|
|
|
The validator's stdout and stderr share a fixed 2 MiB capture limit, including
|
|
the single separator byte used when inspecting their combined output. Both
|
|
streams are drained while the validator runs. If the next byte exceeds that
|
|
limit, GovOPlaN kills and reaps the direct validator process and returns
|
|
`failed` with the reason `KoSIT runner output exceeded the safety limit.`
|
|
Conformance and assessment remain `unknown`, and no handoff is allowed even
|
|
if a valid-looking report was already written. The existing timeout (120 seconds
|
|
by default, configurable from 1 to 600 seconds) also kills and reaps the
|
|
validator; cancellation propagates after the same cleanup. Output is not
|
|
included in these technical-failure reasons. Operators should check the
|
|
approved engine and configuration using synthetic inputs before retrying an
|
|
output-limit failure. The pipe runner uses POSIX process facilities; deployment
|
|
resource limits and descendant-process isolation remain outside this capture
|
|
bound.
|
|
|
|
Report reads are bounded to the existing 16 MiB limit plus one probe byte.
|
|
Reports exactly at the limit remain eligible for normal interpretation;
|
|
oversized reports cannot supply trusted evidence and yield `incomplete` with
|
|
unknown conformance unless an earlier runner failure already determines the
|
|
outcome. An output-limit failure skips reading the report entirely. This read
|
|
bound does not limit how much report data the validator can write to disk.
|
|
|
|
Standardausgabe und Standardfehlerausgabe des Validators teilen eine feste
|
|
Erfassungsgrenze von 2 MiB einschließlich eines Trennbytes. Beide Ausgaben
|
|
werden während des Laufs gelesen. Bei Überschreitung beendet GovOPlaN den
|
|
direkten Validatorprozess und wartet dessen Abschluss ab. Das Ergebnis lautet
|
|
`failed` mit unbekannter Konformität und Bewertung (`unknown`); auch ein
|
|
scheinbar gültiger Bericht erlaubt keine Übergabe. Das bestehende Zeitlimit
|
|
(standardmäßig 120 Sekunden, konfigurierbar von 1 bis 600 Sekunden) beendet den
|
|
Prozess ebenfalls; ein Abbruch wird nach der Prozessbereinigung weitergegeben.
|
|
Diese technischen Fehlergründe enthalten keine Runner-Ausgabe. Betreibende
|
|
sollten das freigegebene Profil vor einem erneuten Versuch mit synthetischen
|
|
Eingaben prüfen. Der Pipe-Runner verwendet POSIX-Prozessfunktionen;
|
|
Ressourcengrenzen der Installation und die Isolation von Kindprozessen bleiben
|
|
außerhalb dieser Erfassungsgrenze.
|
|
|
|
Berichte werden höchstens bis zur bestehenden Grenze von 16 MiB zuzüglich
|
|
eines Prüfbytes gelesen. Berichte genau an der Grenze werden normal
|
|
ausgewertet; übergroße Berichte liefern keinen vertrauenswürdigen Nachweis und
|
|
ergeben `incomplete` mit unbekannter Konformität, sofern nicht bereits ein
|
|
vorrangiger Runner-Fehler das Ergebnis bestimmt. Bei Überschreitung der
|
|
Runner-Ausgabegrenze wird der Bericht gar nicht gelesen. Die Lesegrenze
|
|
begrenzt nicht die Berichtsmenge, die der Validator auf Datenträger schreiben
|
|
kann.
|
|
|
|
GovOPlaN does not trust the report alone. A technically complete result requires a zero process status, no technical error marker in runner output, a bounded well-formed VARL report, a matched scenario, at least the configured number of complete validation steps, and exactly one assessment. Formal validity and the accept/reject recommendation are retained separately because warnings can make them differ. This compensates for the known risk that a partial report can look valid after a transformation failure.
|
|
|
|
Semantic invalidity is different from technical failure. A complete reject report is `invalid`; a timeout, crash, partial report, or inconsistent assessment is `unknown`. Neither result may be handed off as valid.
|
|
|
|
## Governed handoff
|
|
|
|
Only a technically complete, formally `valid`, and explicitly accepted result creates a handoff. The handoff binds tenant, source reference, invoice SHA-256, VARL report SHA-256, profile ID and profile SHA-256, and validation time. Procurement or Payments owns the later payable workflow; Files owns retained invoice bytes; Records may file an exact revision. Revalidation is mandatory after invoice or profile changes.
|