Skip to content

Add typed JSON output to app security review - #8966

Merged
jek merged 3 commits into
app-security/support-json-schema-instructionsfrom
app-security/support-json-schema-review
Oct 22, 2026
Merged

jek merged 3 commits into
app-security/support-json-schema-instructionsfrom
app-security/support-json-schema-review

Conversation

@jek

@jek jek commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Related to https://github.com/shop/issues-develop/issues/23885

WHY are these changes introduced?

app security review is the only combined view of the deterministic and agent results: it applies check precedence, suppressions and result ages. Coding agents currently read it from terminal boxes and have to rejoin paths and commands that wrap across lines.

WHAT is this pull request doing?

Adds --json to app security review. The result has:

  • valid and blocking: {level, blockedCheckCount}. valid is false exactly when --blocking fails; the result is still printed, and the command exits 1.
  • resultsFiles.deterministic and resultsFiles.agent, each with its path, generatedAt, engine and scope, or null when the file is missing. scopeDiffers compares the two scopes.
  • detection and coverage from the latest scan.
  • checks, after --check-id. Each check has its metadata, each source's own result (bySource) and every finding, whatever --verbose says. Deterministic findings carry fix; agent findings carry confidence, reasoning and suppression.

How values appear:

  • Paths are absolute and native.
  • Stored enum values are kebab-case, for example not-applicable and structured-config.
  • Times are whole-second UTC instants, or null when they can't be parsed.
  • Optional text that's empty in the results files is null.
  • Lines and columns are one-based, as the results files record them. json-output.md asks for zero-based positions, so this is still open: before the stack lands, either the guidance changes or the codec converts them, in one place.

New error codes:

  • results-file-invalid, with details.files: [{path, errors}];
  • unknown-check-id, with details.checkIds listing the unknown IDs.

Commits:

  1. securityReview returns the reviewed results, and a presenter in security-review/result.ts renders them and sets the exit code. No behaviour change.
  2. Add --json. The scope, scan directory and blocking definitions go in the shared module, for check.
  3. Reject results files with values the CLI never writes, for example line: 0, a docs_url that isn't a URL, or a fractional version. review now reports such a hand-edited file as invalid, in both formats. Before, --json failed as an unexpected error, and the text view showed file:0. This commit has its own patch changeset. The JSON output is covered by Add typed JSON output to app security clean #8963's changeset.

How to manually test your changes?

Build once and run the local CLI directly, so nothing else reaches stdout:

pnpm nx build cli
alias shopify-dev="node $PWD/packages/cli/bin/dev.js"
shopify-dev app security check --path <app> --no-input --skip-instructions
shopify-dev app security review --path <app> --json
shopify-dev app security review --path <app> --json --blocking low; echo "exit $?"   # valid: false, exit 1 when there are findings
shopify-dev app security review --path <app> --json --check-id NOPE                  # unknown-check-id

To see results-file-invalid, set any "line" in .shopify/app-security/<results key>/deterministic-findings.json to 0 and run review again, with and without --json.

Checklist

  • I've considered possible cross-platform impacts (Mac, Linux, Windows)
  • I've considered possible documentation changes
  • I've considered analytics changes to measure impact
  • The change is user-facing — I've identified the correct bump type (patch for bug fixes · minor for new features · major for breaking changes) and added a changeset with pnpm changeset add

@jek
jek added this pull request to stack #8969 October 21, 2026 00:00
@github-actions github-actions Bot added the Area: @shopify/cli @shopify/cli package issues label Oct 21, 2026
@jek jek changed the title app security/support json schema review Add typed JSON output to app security review Oct 21, 2026
@jek
jek force-pushed the app-security/support-json-schema-review branch from b6029d4 to 34b0e76 Compare October 21, 2026 00:46
@jek
jek marked this pull request as ready for review October 21, 2026 13:57
@jek
jek requested review from a team as code owners October 21, 2026 13:57

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just trusting both types.ts and result.ts are correct, will tophat also

* The stored values of each closed enum, mapped to their public values. A new stored value fails to compile until
* it is mapped.
*/
const SEVERITIES: Record<Severity, AppSecurityCheck['severity']> = {high: 'high', medium: 'medium', low: 'low'}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we assign unchanged enum values directly instead of keeping identity maps such as SEVERITIES, PRECEDENCES, DISPOSITIONS, CONFIDENCES and LANGUAGE_SUPPORT?

The typed projections already reject values that don't fit the public schema. We could keep maps for actual conversions, such as not_applicable to not-applicable.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done: SEVERITIES, PRECEDENCES, DISPOSITIONS, CONFIDENCES and LANGUAGE_SUPPORT are gone, and those values are assigned directly. The maps that convert spellings stay.

@jek
jek force-pushed the app-security/support-json-schema-review branch from 34b0e76 to ea4d549 Compare October 22, 2026 15:23
@jek
jek added this pull request to the merge queue Oct 22, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue because a pull request earlier in the stack was removed Oct 22, 2026
@jek
jek added this pull request to the merge queue Oct 22, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue because a pull request earlier in the stack was removed Oct 22, 2026
jek added 3 commits October 22, 2026 19:43
`securityReview` now returns the reviewed results and the commands that
the review suggests, instead of rendering them and setting the exit
code. The command passes them to a presenter in security-review/, which
renders the review and sets exit code 1 when `--blocking` is breached.
The JSON codec will live beside it, as for the other app security
commands. The text output and exit codes don't change.
`--json` prints the combined checks with every finding, whatever
`--verbose`, beside the results files they come from, the latest scan's
detection and coverage, and the app. `valid` and `blocking` report the
`--blocking` policy; a breach still exits 1, after the result is
printed. Paths are absolute, lines and columns are one-based as the
results files record them, and stored enum values are kebab-case.

An invalid results file aborts with the `results-file-invalid` code and
lists each file's path and errors in `details.files`. An unknown
`--check-id` aborts with `unknown-check-id` and lists the unknown IDs in
`details.checkIds`, so callers can branch without parsing the message.

The scope, scan directory and blocking definitions are shared, so that
`check` can reuse them.
The results files' reader accepted any number as a line, column, check
version, scanned file count or skipped file size, and any string as a
check's docs_url. The CLI never writes such values, and `review --json`
couldn't show them: a hand-edited line 0 made it fail with an unexpected
error. The reader now rejects them, so `review` reports the file as
invalid in text and JSON, with the `results-file-invalid` code and the
steps to regenerate it.
@jek
jek force-pushed the app-security/support-json-schema-review branch from ea4d549 to e3d8ebb Compare October 22, 2026 19:43
@jek
jek added this pull request to the merge queue Oct 22, 2026
Merged via the queue into main with commit b590baf Oct 22, 2026
27 of 29 checks passed
@jek
jek deleted the app-security/support-json-schema-review branch October 22, 2026 20:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: @shopify/cli @shopify/cli package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants