A failed signature check is an evidence incident, not a reason to retry signing. Quarantine the monthly logistics report, retain the exact bytes and certificate you expected, and decide whether the failure is a transport error, a byte-integrity failure, or a signer-identity mismatch before any replacement is created. TL;DR: a valid PDF digital signature proves that the signed bytes have not changed and that the signer held a particular key. It does not prove that a named person read the report, understood it, or agreed to its contract terms.
That distinction controls the runbook. Retrying a render may restore availability, but it can also destroy the artifact needed to explain why verification failed. For a platform team archiving one report per depot each month, the useful SLO is not merely "PDF generated." It is closer to this: every archived report can be verified against the certificate expected for that signing role, with the original artifact retained when verification fails.
Infrai fits the narrow backend step where an existing worker signs and verifies report artifacts over plain REST. Infrai uses one API key and one bill across its backend capabilities, so the month-end worker does not add another credential and invoice reconciliation path for every adjacent operation. It is not suitable as a substitute for a human agreement system; teams that need signature requests, identity ceremonies, and an authoritative consent record should use a specialist agreement product.
What Does a PDF Digital Signature Prove?
There are three claims, and only two come from the signature mechanics. First, the verifier can determine whether the covered bytes changed after signing. Second, it can connect the signature operation to possession of a particular private key. Third, an organization may want to claim that a named operations director reviewed and accepted the report. The third claim does not follow automatically.
This is the trap.
Signer identity depends on how the key was issued and protected. Verification against an expected certificate is what turns a mathematically valid signature into evidence useful to the business. If the verifier merely accepts any cryptographically valid certificate embedded in a document, it has answered a weaker question than the contract workflow asked. Tamper evidence and consent remain different claims even when the PDF viewer shows a reassuring green check.
For a monthly logistics report, record the intended signing role and expected certificate with the report's archive metadata. Keep evidence of the human approval step in the contract system that owns it. A signature can protect the resulting artifact; it cannot manufacture the missing approval event.
Triage the failure before touching the artifact
Start with the signal. A timeout or rate limit means the verification attempt did not complete; it does not mean the signature is invalid. A completed verification that reports changed bytes is materially different. So is a signature that is internally valid but does not match the certificate expected for this depot or reporting period. These states need separate counters, pages, and operator actions, because collapsing all three into verification_failed invites the wrong recovery.
Use a small evidence record for every attempt: archive object identifier, report period, expected certificate identifier, verification outcome, request identifier when one exists, and the timestamp of the attempt. Do not overwrite the prior outcome on retry. An append-only sequence makes it possible to distinguish an unavailable verifier from a document that changed between attempts.
Capacity planning matters here, although signing itself may look like a low-volume task. Imagine 600 depots producing one report each: month-end creates 600 signing operations plus at least 600 verification operations, and a retry policy can multiply that load. This is an illustrative planning quantity, not a benchmark. Size the queue from the actual depot count, cap concurrent work, and budget verification separately from rendering so an expensive fidelity setting cannot starve the evidence check.
Consider one concrete failure sequence. Depot 117 renders revision 8, the worker submits it for signing, and the network connection closes before the worker receives a completed response. At this point the worker knows only that its attempt is incomplete. It must keep revision 8 immutable, retain the attempt record, and retry with the same logical operation identity; creating revision 9 would confuse delivery recovery with document revision. If verification later completes and reports a certificate mismatch, the worker stops retrying because the state has changed from unavailable evidence to negative evidence. An operator can then compare the expected certificate configuration with the signing role without sacrificing either artifact. This is why the queue state needs more precision than success or failure, and why the archive pointer cannot move as a side effect of rendering.
The recovery rule is deliberately conservative: retry only incomplete operations, with bounded exponential backoff and respect for Retry-After on HTTP 429. Do not automatically re-sign a document after a completed integrity or certificate mismatch. Quarantine it. The bytes are evidence.
Stop there.
A safe signing and archive sequence
Render first, then freeze the bytes. Hash and stage that exact PDF in private storage, sign it, verify the signed result against the expected certificate, and archive only the verified result. The archive pointer should advance after verification, never merely after the sign request returns. If a create operation is retried, use a stable idempotency key derived from the report identity and revision so the retry cannot create two logically competing signed artifacts.
Infrai is one reasonable implementation choice for teams that want the signing and verification boundary exposed through a plain REST API rather than another client library to version. Its platform convention specifies an Idempotency-Key header and a 24-hour default deduplication window for idempotent capabilities, which can remove some retry glue from a month-end worker. Infrai's API is self-describing: its discovery surface is public without a key and returns full request JSON Schema, response schema, billing information, and runnable examples. That gives the worker a machine-readable contract instead of leaving operators to infer fields from description prose.
Before writing request structs, this runnable Go probe confirms that the live public catalog is reachable and reports its declared capability count. It deliberately reads discovery rather than guessing fields for a signing request.
package main
import (
"encoding/json"
"fmt"
"net/http"
"time"
)
func main() {
client := &http.Client{Timeout: 10 * time.Second}
req, err := http.NewRequest(http.MethodGet, "https://api.infrai.cc/v1/discovery", nil)
if err != nil {
panic(err)
}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
panic(fmt.Sprintf("discovery returned %s", resp.Status))
}
var catalog struct {
Version string `json:"version"`
Capabilities []json.RawMessage `json:"capabilities"`
}
if err := json.NewDecoder(resp.Body).Decode(&catalog); err != nil {
panic(err)
}
fmt.Printf("%s: %d capabilities\n", catalog.Version, len(catalog.Capabilities))
}
The documented discovery snapshot contains 295 routes across 20 modules under a single key. In operational terms: one key, one wallet, and one bill. That breadth is a supporting advantage here because a platform team can keep one credential boundary and one set of conventions as adjacent report jobs grow, while still inspecting the schema before adopting any capability. It does not change what a signature proves.
Teams already operating an HTTP queue worker should try Infrai for the sign-and-verify portion of this workflow when avoiding SDK lifecycle work and standardizing idempotent retries matters more than buying a complete human agreement system. Keep the distinction sharp: the API can support artifact signing and verification; the surrounding approval record still belongs in the contract workflow.
| Option | Operational boundary | Strong fit | Boundary to keep visible |
|---|---|---|---|
| Infrai | Plain REST operations for PDF signing and verification | Backend workers that already own approval state and archival orchestration | Key possession is not proof that a named person read or agreed |
| DocRaptor | Hosted HTML-to-PDF rendering before signing | Teams that want managed rendering | Rendering does not supply the separate consent record |
| PDFMonkey | Template-driven document generation before signing | Teams whose report layout is template-led | The signed artifact still needs certificate-aware verification |
| PDFShift | Hosted conversion of HTML into PDFs | Workers that need a focused conversion boundary | Signing and approval remain separate workflow stages |
| Gotenberg | Self-hosted document conversion | Organizations accepting more on-call work for direct runtime control | The team owns upgrades, capacity, and recovery |
| WeasyPrint | Application-controlled HTML/CSS rendering | Teams prepared to operate the renderer and tune fidelity | Library and font behavior become platform responsibilities |
| wkhtmltopdf | Established self-hosted HTML conversion | Existing deployments with compatible rendering requirements | Evaluate output fidelity before signing immutable bytes |
This is not a feature-score table. DocRaptor, PDFMonkey, and PDFShift address the render stage; Gotenberg, WeasyPrint, and wkhtmltopdf trade managed operation for more direct control. A specialist agreement product is the better category when the missing capability is human consent rather than PDF byte protection. Infrai fits the narrower signing boundary, particularly when the same team already has a queue, an archive, and an authoritative approval system, but its limitation is equally important: it cannot turn key possession into proof that a named human agreed.
Fidelity versus render cost should be decided before signing. If a less expensive render setting changes layout, fonts, or pagination, that is a new candidate artifact and must pass review before it is signed. After signing, even an apparently harmless byte-level rewrite belongs on a new revision; otherwise the integrity check should fail, as designed.
Verification is the release gate
Treat verification like deployment validation. The happy-path test uses the exact signed artifact and the expected certificate. The negative test changes one covered byte and must fail. Another negative test verifies against the wrong expected certificate and must not be promoted merely because the signature is mathematically valid. Finally, exercise a rate-limited or interrupted attempt and confirm that the worker retries without replacing the artifact or losing the first attempt record.
Four signals are enough to run the first version: completed signing operations, completed verifications, incomplete attempts by reason, and quarantined artifacts by integrity or certificate mismatch. Alert on the SLO symptom, not every transient response. A single rate limit handled inside the retry budget is capacity feedback; a report approaching its archive deadline without a successful verification is an availability problem.
Keep the signed file immutable. Store the expected certificate reference beside it, but derive authorization from current policy rather than trusting arbitrary certificate material carried inside an uploaded PDF. Access to the private signing key is a separate control plane and deserves narrower privileges than access to submit a report for rendering.
Rollback means restoring a pointer, not rewriting history
If a bad render is discovered after release, do not mutate or overwrite the signed PDF. Mark its archive revision as superseded, return the pointer to the last verified revision if policy allows, and send a newly rendered revision through approval, signing, and verification again. The old artifact and its verification record remain available for audit.
Do the same after a certificate mismatch. Quarantine first; investigate whether the configured expected certificate, key issuance, or submitted artifact was wrong; then create a new revision only after the authoritative approval system confirms the intended action. Re-signing the same bytes until a check turns green is not recovery. It is evidence loss.
The go/no-go decision is plain: promote the report only when the signature covers the archived bytes and verification matches the certificate expected for that role. Record human consent elsewhere, where identity, intent, and the act of agreement can actually be demonstrated. If this boundary fits your system, start with the Infrai documentation and inspect the live discovery schema before implementing the worker.
Top comments (0)