Source archives
KeyHog recognizes archive and compressed formats while scanning a file or directory. You do not need a separate archive flag.
keyhog scan incoming/ --format json-envelope -o keyhog-archives.json
ZIP-family containers include ZIP, JAR, WAR, APK, IPA, CRX, Python and NuGet packages, and common office formats. KeyHog also reads tar, 7z, RAR, and tar or single streams compressed with gzip, zstd, LZ4, Snappy, bzip2, or xz. Supported archives nested inside those formats are scanned within bounded depth and byte budgets.
Each eligible readable regular member enters the normal detector pipeline.
Binary members use printable-string extraction. Finding paths retain every
container and member, such as submission.tar//paper/main.tex.
Scan untrusted archives
Keep the envelope report when the input may be corrupt or hostile:
rc=0
keyhog scan incoming/ --format json-envelope -o keyhog-archives.json || rc=$?
jq '{scan_status, coverage_gap_summary, findings: (.findings | length)}' \
keyhog-archives.json
printf 'keyhog exit=%s\n' "$rc"
KeyHog does not extract members into the filesystem or execute their contents. It rejects archive paths that are absolute, contain traversal, use ambiguous encoding, or name a special file. It also refuses a top-level archive reached through a symbolic link. Decoded bytes per member, nested depth, and aggregate output are bounded. Formats with compression-ratio metadata also apply a ratio guard.
Rejected, encrypted, corrupt, unreadable, oversized, or budget-truncated input
is not treated as clean. KeyHog reports the uncovered member or archive on
stderr and records a coverage gap in the envelope. With no findings, incomplete
coverage exits 13. If the covered portion has findings, exit 1, or exit 10
for a confirmed live credential, takes precedence. The coverage warning and
scan_status = "partial" remain in the report.
Do not raise --max-file-size merely to make exit 13 disappear. Raise it only
when you trust the input and the runner has enough memory. Otherwise isolate the
failed archive, repair or unpack it with a trusted tool, and scan the recovered
files as a new input.
Suppress one reviewed archive fixture
Use the full member path in .keyhogignore.toml. Include the detector and hash
so another credential in the same member still reports:
[[suppress]]
detector = "aws-access-key"
path_eq = "vendor-bundle.zip//examples/demo.env"
credential_hash = "5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8"
The rule does not match the same member in a differently named container. It
also does not match a different value in demo.env. Inline directives are not
loaded from archive member text. See Suppressions for rule
precedence and failure behavior.
TeX source packages
Scan a TeX source package like any other archive:
keyhog scan submission.tar
TeX packages receive an additional bounded dependency pass. It recognizes
input, include, subfile, includegraphics, bibliography, and
addbibresource commands. Paths are resolved relative to the referring member.
Absolute paths and references that escape the archive root do not enter the
dependency graph. After an exact member-name lookup, unresolved references try
the command’s standard .tex, .bib, or graphics extensions.
Archive chunks use these source labels:
filesystem/archive/tex-rootfor document rootsfilesystem/archive/tex-referencedfor members reachable from a rootfilesystem/archive/tex-orphanedfor inventory members not reachable from a rootfilesystem/archive/tex-comment/<role>for exact unescaped TeX comment spans
Binary members with printable strings use the corresponding
filesystem/archive-binary/tex-<role> label.
Comments are scanned with their original member path and byte offset. The full member is also scanned unchanged. Expansion cycles terminate through a visited member set. Malformed commands do not stop ordinary member scanning.
The dependency pass caps member count, per-source bytes, total source bytes, references per member, and group nesting. If the analysis exceeds a cap, role annotations are unavailable and every readable member still takes the ordinary archive path. The scan reports the incomplete semantic expansion as a coverage gap rather than claiming complete TeX analysis.
Android packages
keyhog scan app-release.apk --format json-envelope -o app-release.keyhog.json
APK scans decode resources.arsc value tables and compiled Android XML before
running the normal detector pipeline. Resource findings preserve package, type,
entry name, resource ID, and configuration qualifier. XML findings preserve the
element path, attribute name, framework resource ID, and inline or referenced
value.
Decoded chunks use filesystem/archive/android-resource or
filesystem/archive/android-xml. KeyHog also scans each original member through
the ordinary archive path. It does not execute Dalvik code or resolve runtime
resource selection.
Input bytes, chunk count, string pools, resource entries, XML depth, emitted
items, and emitted bytes are bounded. A malformed compiled resource records an
inaccessible coverage gap. A cap records a truncated coverage gap. Semantic
decoding is incomplete in either case, while the original member scan
continues.