feat(materials): add OVERSECURED_JSON material type
Closes #3369
Adds a first-class material type for Oversecured mobile (Android/iOS) scan reports. Until now the only way to attest one was the generic EVIDENCE kind with a hand-written wrapper, which pushed the wrapping onto every caller and skipped validation at craft time. Oversecured has no SARIF output, so the report cannot be routed through the existing SARIF kind either.
The accepted input is the whole-scan JSON export (oversecured report <scanId> --app <appId> --format json). The crafter validates the export envelope โ a scan id, an app platform, and a findings array that may be empty or null for a clean scan โ and then uploads the report unchanged. Validation stops at the envelope: the findings carry decompiled sources and DAST heap snapshots that make up nearly all of a multi-MB export, and nothing in them identifies the tool better than the header does.
The kind is deliberately kept out of auto-detection, so it must be referenced with an explicit --kind OVERSECURED_JSON or from a workflow contract. The vendor does not publish the export envelope, so pinning it into the detection order would bet every other JSON kind on a shape inferred from a sample. The exclusions in that list are now consolidated into one comment block and pinned by a test.
The material carries the chainloop.material.tool.name annotation only. The export omits the per-finding hasSast/hasDast flags that exist on the API's findings-list and single-finding responses, and states nothing about which engines ran, so no chainloop.material.scan.types value can be derived from it honestly; there is no scanner version in the envelope either (header.scan.version is the app version).
Evaluating these reports with the sast policy family needs a matching rego execution path, which lives in the policies repository and is not part of this change. Worth noting for whoever writes it: the export has no sink, so a finding's location has to come from code[] and its is_matched lines, and false positives are marked rather than filtered out.
AI assistance
This change was produced with AI assistance (Claude Code). Every commit carries an Assisted-by: Claude Code trailer.
๐ค Posted by Maximus bot (Claude Code) on behalf of @migmartri