What is the JSON progress file that ZAP's packaged scans take with -p, and what does it change?
answer
- a second file, and not the same format
- one state value is acted on
- findings split into new and in-progress counts
- only the new counts reach the exit ladder
basics
~20 sIt is a JSON list of issues, each with a rule id, a state and a link. Rules whose state reads inprogress have their findings counted separately, so they are still printed but no longer drive the exit code.
solid answer
~50 s`-p` takes a second, entirely different file from the tab-separated rule file: JSON, shaped as an `issues` array of objects carrying a rule `id`, a `state` and a `link`. Only the state `inprogress` is acted on; any other value is ignored. A finding from a listed rule is printed with an in-progress marker and its link instead of the usual new marker, and is added to a separate in-progress counter. The exit ladder reads only the *new* counters, so those findings stop driving the outcome while staying fully visible in the output. It does not change the rule's verdict -- a rule marked `FAIL` and listed here still prints as failing, just as in progress. One cost worth knowing: supplying `-p` to `zap-baseline.py` makes the run unsupported by its automation-framework path, so it falls back to the older daemon-and-API route.
code
json · 9 lines{
"issues": [
{
"id": "<scan-rule-id>",
"state": "inprogress",
"link": "https://example.com/tracker/open-item"
}
]
}go deeper
Recall that this is a second file and it is JSON, not the tab-separated rule file. It lists rules being worked on so their findings still print but stop driving the exit code.
Explain the split counters: each gating bucket keeps a new count and an in-progress count, and only the new ones reach the exit ladder. Note that the verdict itself is untouched.
Show that you know the trade-off -- supplying it drops a baseline run off the automation-plan route -- and that you would generate the file from whatever tracks the work rather than hand-maintaining it.
Own the question of how long an entry may sit here and who reviews that. The construct is honest by design because every entry carries a link; the discipline it needs is that somebody follows them.
## Two files, two formats, two jobs It is easy to assume the packaged scan scripts read one configuration file. They read two, and confusing them is the usual first mistake. | | the rule file (`-c`, `-u`, `-g`) | the progress file (`-p`) | |---|---|---| | format | tab-separated text | JSON | | keyed on | a rule id per line | a rule id per array entry | | says | which bucket this rule's findings go in | that this rule is being worked on | | effect on the exit code | decides it | removes those findings from it | | effect on the output | changes which count the finding appears under | changes the marker and adds a link | ## The shape of the file A single top-level object with an `issues` array. Each entry carries: - **`id`** -- the scan rule's id, as a string, matched against the rule id on each finding; - **`state`** -- the only value the run acts on is `inprogress`; anything else is read and ignored; - **`link`** -- a URL printed beneath the finding, so the build log points at wherever the work is tracked. Nothing else in the entry is used, and entries for rules that never fire cost nothing. ## What it changes at run time When the run prints its findings, it checks each rule id against the in-progress set: 1. A rule that is **not** listed prints with a **new** marker. 2. A rule that **is** listed prints with an **in-progress** marker, followed by its link on its own line. 3. Counting splits in two: the informational, warning and failing buckets each keep a new count and an in-progress count. 4. The exit ladder reads only the **new** counts. A failing-bucket finding from an in-progress rule does not send the run to exit `1`; a warning-bucket one does not send it to `2`. So the file is a way of saying "we know about this one and it is being handled" without deleting the finding, downgrading the rule, or editing the verdict. The finding stays in the output with a pointer to the work, and the run stops blocking on it. Two details follow from how it is wired: - **It does not override the verdict.** A rule marked `FAIL` in the rule file and listed here prints as failing-in-progress. If you take it out of the progress file tomorrow, it blocks again with no other change. - **Ignored findings are never checked against it.** The run passes an empty in-progress set when it prints the ignored bucket, so the marker never appears there. That is consistent -- an ignored finding was already not gating -- but it means the file is not a way to annotate ignored rules. ## The cost of supplying it `zap-baseline.py` can run two ways: by generating an automation plan and executing it, which is now its default route, or by starting the program and driving it over its control API, which is the older one. Several options are not expressible on the plan route, and `-p` is one of them -- supplying it marks the run unsupported and drops it back to the older route. That matters for two reasons: - the two routes do not behave identically in every corner, so adding `-p` changes more than in-progress counting; - on the plan route the summary step prints both in-progress counters as zero unconditionally, which is a fair signal that the feature belongs to the older path. If you are already pinned to the older route for another reason, `-p` is free. If not, it is a real decision rather than a flag you add casually. ## Where it fits Reach for `-p` when a finding is genuinely being worked on and you want the run to keep reporting it while it is. Reach for an `IGNORE` verdict in the rule file when you have assessed a rule and accepted it indefinitely. The difference is intent, and it shows in the output: an in-progress finding carries a link to the work, an ignored one carries whatever note you wrote in the rule file's fourth column. The failure mode is the same for both, and it is social rather than technical: entries nobody revisits. The progress file makes that visible -- every entry names a link, and a link that has been closed for months is the file asking to be cleaned up. Regenerating it from whatever tracks the work, rather than hand-editing it, is what keeps that honest.
- Does listing a rule here change the verdict it was given in the rule file?No. The verdict still decides which bucket the finding lands in; the progress file only splits that bucket's count into new and in-progress halves. A rule marked `FAIL` and listed here prints as failing-in-progress, and blocks again the moment it leaves the file.
- What happens to an entry whose state is something other than inprogress?It is read and ignored. Only the one value is acted on, so an entry with any other state leaves that rule behaving exactly as if the file had not mentioned it -- its findings print with the new marker and count toward the exit code.
- Why might you avoid -p on a baseline run?Because it is one of the options the automation-plan route cannot express, so supplying it drops the run back to the older route that drives the program over its control API. If you were relying on the plan route, that is a bigger change than the counting behaviour you wanted.
saying these in an interview costs you the question
- Thinks the progress file is the same tab-separated format
- Believes listing a rule there changes its verdict
- Expects any state value to suppress the finding
- Assumes in-progress findings are hidden from the output
- Adds it without noticing it changes the execution route