
A Signed Webhook Is Not Permission to Run the AI Workflow Again
Separate signature checks, durable receipt and permission to act. A practical webhook admission design keeps repeated deliveries from becoming fresh AI workflow requests.
Read MoreUpload size does not bound parsing work. Set shared limits for expanded bytes, images and attachments, and keep partial extraction from becoming a supposedly complete AI answer.

A user uploads a small attachment for summarization. The service accepts it, then runs out of memory while opening images and embedded files. Other requests wait. No text has reached the language model yet. If extraction stops halfway, a second failure becomes possible: the assistant summarizes the first few pages as though it read the whole document.
This is a constructed operating scenario, not an incident reported by ZharfAI. For document-assistant developers and operations owners, the decision is which inputs belong in the ordinary processing lane, which need separately approved capacity, and when to say extraction is incomplete. A model's token limit cannot recover resources already consumed upstream.
Bytes received over the network measure transport, not the work of interpreting a document. A compact input can produce large images, numerous attachments or much more text. Output volume is not a complete proxy either: a parser can spend substantial time on a complicated structure while emitting little.
The OWASP File Upload Cheat Sheet recommends allowlisting needed formats and considering size after decompression. Client-supplied content types are untrusted, and file signatures are insufficient on their own. Recognizing an allowed format does not authorize unlimited processing.
Start with the product's actual needs. A receipt assistant does not automatically need to unpack arbitrary, recursively nested archives. Refusing an unnecessary format is a product decision; exposing every feature of the extraction library is not a requirement. If archives are supported, define what support means for attachments, animated images and encrypted documents.
ZharfAI's recommendation is to make the input contract describe both allowed representations and permitted work. A valid file is not necessarily a cheap file. A legitimate document may exceed the ordinary lane's capacity, while a resource-limit event alone does not establish malicious intent. Explain the limit without accusing the sender or promising that passing it proves safety.
An unusual expansion ratio can be a useful signal, but it cannot replace an absolute cap. A modest ratio applied to a large input still creates substantial output. For each limit, record what is counted, where enforcement happens and what disposition follows a breach. The following is our design framework, not a library's guaranteed configuration.
| Boundary | Measurement | Enforcement point |
|---|---|---|
| Initial upload | Bytes received | Before accepting the complete input |
| Expanded content | Cumulative bytes | During each read and write |
| Decoded images | Per-image and aggregate pixels | Before large allocation and during decoding |
| Document breadth | Component count and nesting depth | As components are discovered and entered |
| Text and metadata | Output size and value count | Before appending to the result |
| Runtime consumption | Memory, CPU, disk and elapsed time | Supervisor outside the parser |
Checking only after output has been produced may be too late. Header inspection helps reject obviously excessive work early, but declared sizes are not proof of eventual resource use. Check counters during execution as well, including error paths. Enforce limits before unbounded buffering, not merely before returning the completed response.
A text-output cap does not constrain an image buffer or temporary-file count. For each supported file family, map the limits supplied by the library against those enforced by the runtime. Any uncovered dimension remains an engineering task; calling the pipeline “secure parsing” does not fill the gap.
Consider a document containing three attachments, each containing further files. Reinitializing the allowance at every nested document defeats the original request's ceiling. All descendants must consume one shared allowance. Local component limits remain useful, but they do not replace the aggregate boundary.
Suppose the illustrative policy allows 24 MiB of expanded output per attachment and 48 MiB for the complete job. Three attachments produce 16, 18 and 20 MiB. Each is individually acceptable, but together they produce 54 MiB. After the first two, only 14 MiB remains; the third must not finish expanding. These are invented policy values, not recommended production defaults.
Parallel children need coordinated reservation and accounting. Two workers must not both treat the same remaining allowance as their own. Distinguish cumulative work from instantaneous occupancy: releasing an image buffer may reduce current memory, but it must not reset the count of pixels processed or bytes expanded. Nesting depth measures the path being entered, rather than the number of files already seen.
A 10,000-by-8,000 image contains 80 million pixels. One three-channel buffer at one byte per channel needs 240 million bytes, approximately 229 MiB. That calculation predicts neither the compressed file size nor peak parser memory; intermediate copies and other structures are additional. Doubling both dimensions quadruples the pixel count.
Pillow's security guidance describes compressed-image expansion and the limits of pixel-based protection: an image below the pixel ceiling can still consume significant processing time. It recommends treating oversized-image warnings as errors and using runtime resource limits.
An illustrative 20-million-pixel policy would reject our example before full image allocation. That is not a memory guarantee or a threshold validated for your product. Track aggregate image work for multipage documents too: many individually permitted pages can still form an expensive job. Downscaling also requires processing; it is not a cost-free escape from the ingestion boundary.
Run extraction in a separate worker with a job-specific temporary area. The worker should not hold database secrets, direct permission to publish into the search index, or unnecessary network access. An external supervisor must impose runtime limits and own cleanup after normal completion, interruption or worker death. Cleanup inside a process that might fail is not enough.
The Python 3.14 tarfile documentation explicitly warns that even the default data extraction filter does not prevent denial of service. External memory, CPU and disk limits remain necessary. Extraction errors can also leave partial files; removing them is the caller's responsibility.
Path safety and resource consumption are separate controls. Define policies for filenames, name collisions and symbolic links independently. In our proposed architecture, an extracted filename never selects a trusted destination. The publishing component accepts only approved output from temporary storage.
This boundary does not establish content authority. A cheap document can still contain misleading instructions or untrustworthy claims. The knowledge-base admission gate addresses provenance and trust separately. Passing a resource check means processing stayed within a chosen envelope, not that every sentence deserves the assistant's confidence.
A consequential detail appears in Apache Tika 4.0.x's limit documentation: in UNPACK mode, reaching maxUnpackBytes can leave partial output while still reporting success. The truncation warning appears only in the fork's log. Do not generalize that behavior to every Tika mode or version.
The same version's timeout documentation distinguishes a total task budget, including children, from per-parser caps clipped to the remaining time and a no-progress timeout. A PARTIAL_TIMEOUT result can include a usable prefix, not a complete document.
The product implication is to separate technical call status from document coverage. A disconnected client is not evidence that the worker stopped either. The supervisor must establish actual termination; until then, retrying the same input with more resources can compound the load.
If the selected tool mode provides no dependable indication of truncation, do not use that mode as the basis for a complete-extraction claim. Logs support investigation, but answer integrity should not depend on someone eventually noticing a warning string. The application needs an explicit, testable completion contract.
Our proposed job record includes the input identifier and hash, parser version, limit-policy version, discovered components, processed components, termination reason and evidence locations. If discovery stopped before the total became known, preserve “unknown.” Three processed components out of an unknown total are not 100 percent coverage.
Distinguish four outcomes: complete within the supported scope, partial, rejected, and unknown after an execution failure. Permit “complete” only after traversal finishes, omissions are accounted for and no limit truncated the result. Even then, an encrypted attachment or unsupported format must constrain the claim's scope rather than disappear into vague fine print.
Do not feed emerging text chunks directly into the searchable index before that disposition is established. Stage them first. A final record should identify the derivative version eligible for publication. If the product permits partial evidence, attach its coverage limitation to those chunks so that later retrieval cannot silently drop the qualification.
Extraction quality is another independent property. Finishing a job does not prove correct column order or accurate text recognition. The multimodal document-intelligence guide explains grounding findings in document pages and regions. Preserve those locations in bounded output too; discarding them makes the surviving evidence harder to inspect.
| Job outcome | Proposed disposition | User-facing explanation |
|---|---|---|
| Complete within approved scope | Publish eligible output | State the processed scope and sources |
| Resource ceiling reached | Stop the ordinary lane | Identify the limit and review option |
| Partial extraction with located evidence | Restricted display, if the product permits it | Name covered portions and answer limitations |
| Failure with unknown coverage | Do not publish | Completion could not be established |
| Legitimate larger requirement | Separately approved processing lane | State revised scope, cost and waiting time |
The larger lane must not mean repeating the previous attempt with every safeguard disabled. Its owner should accept the reason, available capacity and revised limits. Separate queueing and capacity prevent a large document from holding up ordinary users; increased permission must remain bounded and traceable.
Per-file limits do not replace service-level admission control. Hundreds of individually acceptable files from one tenant can still occupy the fleet. Admission control and fairness under overload addresses that second decision: tenant shares, queue length and when to refuse new work. Both boundaries are necessary, and neither substitutes for the other.
Use small, harmless fixtures with deliberately low test limits. There is no need to create destructive, resource-exhausting payloads. Exercise output exactly at the boundary and just above it, siblings whose combined work exceeds the parent limit, and a worker that stops making progress. Include shared-budget accounting under concurrent execution.
Do not stop at “an error was returned.” Did the worker actually terminate? Was temporary storage left behind? Did any partial output enter retrieval? Can the assistant still claim that every attachment was examined? A success label in an execution log does not answer those questions. This guide's numeric examples are arithmetic exercises; ZharfAI has not subjected these libraries to malicious-load testing for this article.
In operation, compare limit reasons, file families, tenants, resource consumption and the share of complete jobs. A rise in one format's failures after an upgrade may indicate changed parser behavior rather than abusive users. Faster success with falling coverage is not an improvement. Rerun boundary tests when libraries or policies change and retain the policy version in job records.
The durable decision is narrow: permit bounded work, publish output with an explicit scope, and never infer complete extraction merely because some useful text came back. An incomplete result can still help a reader when its limits are visible. Hiding the missing portion turns a resource-control event into an evidence failure.
This is design guidance, not an incident report or safety certification. Tables and illustrative thresholds are ZharfAI analysis. These are living documentation pages; the review date is not their publication date.

Separate signature checks, durable receipt and permission to act. A practical webhook admission design keeps repeated deliveries from becoming fresh AI workflow requests.
Read More
Hashing a phone number does not make an AI upload anonymous. Choose the minimum record linkage, protect keys and mappings, and inspect what the remaining fields reveal.
Read More
A public-looking link can lead an AI tool toward private services. Separate public fetching from authenticated connectors, and authorize the connection at every hop.
Read MoreIf you want the agents and automation in this guide working for your engineering team or business processes, start with a small pilot you can measure.