Skip to content

App Security: store results per results key - #8737

Merged
jek merged 1 commit into
app-security/selectionfrom
app-security/results-key
Oct 5, 2026
Merged

jek merged 1 commit into
app-security/selectionfrom
app-security/results-key

Conversation

@jek

@jek jek commented Oct 2, 2026 •

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Results were stored per app directory, so TOMLs in the same directory (or a scan without app configuration) overwrote each other, and instructions, record, review and clean couldn't target a specific configuration.

WHAT is this pull request doing?

Store results in .shopify/app-security/<results key>/, where the key is --client-id if passed, otherwise the selected TOML's file name. All five commands take the same selection flags and find the results the same way. clean removes only the selected results; clean --all removes every results directory. Unsafe --client-id values are refused as a key. The commit and uncommitted-changes state is removed.

How to manually test your changes?

shopify app security check --config production
shopify app security review --config production
shopify app security clean --config production
shopify app security clean --all

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 #8741 October 2, 2026 12:59
@github-actions github-actions Bot added the no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users. label Oct 2, 2026
@jek jek changed the title Store App Security results per results key App Security: store results per results key Oct 2, 2026
@github-actions

github-actions Bot commented Oct 2, 2026

Copy link
Copy Markdown
Contributor

Differences in type declarations

We detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:

  • Some seemingly private modules might be re-exported through public modules.
  • If the branch is behind main you might see odd diffs, rebase main into this branch.

New type declarations

We found no new type declarations in this PR

Existing type declarations

packages/cli-kit/dist/public/node/cli.d.ts
@@ -35,7 +35,6 @@ export declare function runCreateCLI(options: RunCLIOptions, launchCLI?: (option
 export declare const globalFlags: {
     'no-color': import("@oclif/core/interfaces").BooleanFlag<boolean>;
     verbose: import("@oclif/core/interfaces").BooleanFlag<boolean>;
-    'no-input': import("@oclif/core/interfaces").BooleanFlag<boolean>;
 };
 export declare const jsonFlag: {
     json: import("@oclif/core/interfaces").BooleanFlag<boolean>;

@jek
jek force-pushed the app-security/results-key branch from 3ec57c7 to 4d32756 Compare October 2, 2026 13:35
@jek
jek force-pushed the app-security/results-key branch from 4d32756 to a915406 Compare October 2, 2026 14:02
@jek
jek marked this pull request as ready for review October 2, 2026 18:35
@jek
jek requested review from a team as code owners October 2, 2026 18:35
@jek
jek requested a review from jplhomer October 2, 2026 18:38
@jek
jek force-pushed the app-security/results-key branch from a915406 to f7c6892 Compare October 2, 2026 21:07
Each results key (--client-id, or else the selected TOML's name) gets its own
results directory, and check, instructions, record, review and clean find it
the same way. Remove the commit and uncommitted-changes state.
@jek
jek force-pushed the app-security/results-key branch from f7c6892 to c9c3704 Compare October 5, 2026 13:46

@dmerand dmerand left a comment

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.

Agent had a couple of questions. The change overall LGTM + is much more consistent, thanks!

assertWithinRoot(realRoot, realDirectory)

// Adds `.shopify/.gitignore`, which keeps the results out of version control.
await getOrCreateHiddenShopifyFolder(appDirectory)

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.

Perhaps we should make .shopify/.gitignore creation refuse symbolic links, or use a shared helper that does.

The directory checks above do not cover this file. If .shopify/.gitignore is a dangling link to an absent file outside the app, getOrCreateHiddenShopifyFolder sees it as missing. Its writeFile follows the link and creates the outside file. The keyed artifact write then succeeds.

I confirmed this with the pinned artifact writer and hidden-folder helper on a real filesystem. This was a focused writer probe, not a full CLI smoke test.

Please add a regression test that keeps the outside target absent and preserves existing results when refusing the link.

withoutAppConfig: flags['without-app-config'],
allowPrompts: false,
})
await requireResultsDirectory(selection)

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.

Perhaps we should let standalone instructions run before the first check by removing this existing-results requirement.

A new app with valid configuration has no results directory, so this aborts instead of printing the workflow. The workflow itself starts with check. In #8740, it asks the agent to choose scope with --list-files before that scan; --list-files does not create the required directory either.

Instruction generation does not read stored results. Keep shared selection and app-config validation, but let the agent get its workflow before the first scan. Please add a fresh-app test that expects instructions without an earlier check run.

This is based on the source and the existing refusal test, not a command smoke test.

@jek
jek added this pull request to the merge queue Oct 5, 2026
Merged via the queue into main with commit cb47a4c Oct 5, 2026
33 of 57 checks passed
@jek
jek deleted the app-security/results-key branch October 5, 2026 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changelog This PR doesn't include a changeset entry. Is an internal only change not relevant to end users.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants