Every scan worker should have a wall clock timeout, memory and CPU limits, a disk quota, caps on archive size and file count, and restricted network egress. Scanners open untrusted archives and repositories, so assume some inputs are hostile or just enormous.
Why limits are part of security
A scanner reads other people's content: source trees, container layers, package archives. Some inputs are accidentally huge. Some are crafted. A compressed file can expand to many times its size, and a repository can contain millions of tiny files. Without limits, one input can exhaust a node and delay every other team's scans.
Limits also contain damage. If a parser has a flaw, a locked-down worker limits what the attacker gets.
The limits to set
| Limit | What it prevents | Notes |
|---|---|---|
| Wall clock timeout per job | Hung or looping scans | Base it on a percentile of normal runs, with headroom |
| Memory limit | One job crashing the node | Out of memory kills should be a recorded failure class |
| CPU limit | Noisy neighbours | Use requests and limits in your orchestrator |
| Disk quota for scratch space | Archive expansion filling the disk | Clean the workspace after every job |
| Decompressed size and file count cap | Archive bombs | Check while extracting, not after |
| Path handling rules | Archive entries that write outside the workspace | Reject absolute paths and parent directory traversal |
| Network egress allowlist | Exfiltration and calls to internal services | Allow the database mirror and results endpoint only |
Isolation matters as much as limits
- Run each job in a fresh sandbox, such as a container with no privileges, or a lightweight virtual machine for stronger separation.
- Run as a non-root user, drop capabilities, and use a read-only root file system with a writable scratch directory.
- Never mount host credentials or the container runtime socket.
- Give the worker short-lived, narrowly scoped credentials to fetch only the target it is scanning.
- Do not execute the code under scan. Static analysis and dependency analysis should read files, not run build scripts or install hooks.
- Destroy the sandbox after the job so nothing carries over.
Choosing the numbers
Collect data first. Measure duration, memory peak and disk use per scan type for a few weeks, then set limits above the 99th percentile and review monthly. Too tight and legitimate large repositories fail, which creates support tickets and exceptions. Too loose and the limit never fires.
For jobs that exceed a limit, fail with a clear message that names the limit. "Scan exceeded memory limit of the configured size on this path" helps an owner exclude a vendored directory, whereas a generic error does not.
Large inputs are a product question
Some legitimate targets are just big: monorepos, huge images. Offer a path for them, such as sharding the scan or a larger worker class with approval, rather than raising the default for everyone.
Try it yourself
Click through it at your own pace, or open it full screen. Notice that the scan reads the image contents and reports on them without running the image.
Safeguard runs scanning as a hosted service, so worker isolation is handled on our side. You can try the free scan at https://gold.safeguard.sh/scan.
Quick check
Should scanners run the project's build?
Avoid it where you can. Running build scripts executes untrusted code. Prefer reading manifests and lockfiles.
What timeout should I start with?
Start from measured run times for each scan type and set the limit above the 99th percentile, then adjust.
Last reviewed: 19 October 2026.