Skip to content

Fix App Doctor secret scanning false positives - #8592

Open
jplhomer wants to merge 4 commits into
mainfrom
joshlarson/app-doctor-secret-false-positives
Open

jplhomer wants to merge 4 commits into
mainfrom
joshlarson/app-doctor-secret-false-positives

Conversation

@jplhomer

Copy link
Copy Markdown
Contributor

WHY are these changes introduced?

Fixes https://github.com/shop/issues-develop/issues/23957

Early-access partners were flooded with COMMITTED_SECRET findings for placeholders, .env.example templates, public client IDs, and Stripe publishable keys. A name match plus a non-empty value was enough to score -50 high, which fails the static-tier bar of provable facts.

WHAT is this pull request doing?

Require two pieces of evidence before scoring an env/secret file: a known credential format, or a secret-named assignment whose value is not a placeholder. Template env files (.env.example, .sample, .template, .dist) only fire on a known token format. Drop SHOPIFY_API_KEY / api_key and Stripe pk_ from secret detection. Keep fail-closed for real secrets when git status is unknown, but stop rendering that case as confirmed-tracked.

How to manually test your changes?

From an app with a committed .env.example of placeholders and a tracked .env that contains a real shpss_ / shpat_ token:

pnpm shopify app doctor --path /path/to/app --skip-instructions

Confirm the template is not reported and the real token still is.

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

Require a known credential format or a non-placeholder value before
scoring COMMITTED_SECRET, skip template env files and public client IDs,
and stop rendering unverified git status as confirmed-tracked.

Co-authored-by: AI (Pi/Grok 4.6) <noreply@pi.dev>
@jplhomer
jplhomer requested a review from a team as a code owner September 18, 2026 15:50
Copilot AI lite review requested due to automatic review settings September 18, 2026 15:50
@github-actions github-actions Bot added the Area: @shopify/app @shopify/app package issues label Sep 18, 2026

Copilot AI 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.

🟡 Changes recommended

Two moderate detection gaps and contradictory template guidance remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Fixes App Doctor secret-scanning false positives while preserving detection of valid credentials.

Changes:

  • Requires stronger evidence for committed-secret findings.
  • Adds template, placeholder, public-key, and git-status handling.
  • Updates guidance, tests, rule version, and patch changeset.
File summaries
File Summary
packages/app/src/cli/services/app-doctor-engine/tests/secret-safety.test.ts Adds regression coverage for refined secret detection.
packages/app/src/cli/services/app-doctor-engine/tests/deterministic-rules.test.ts Verifies deterministic rule versioning.
packages/app/src/cli/services/app-doctor-engine/scanners/index.ts Bumps the deterministic rule version.
packages/app/src/cli/services/app-doctor-engine/rules/secret-rules.ts Implements evidence-based classification; moderate issues remain for multi-suffix templates and quoted JSON keys.
packages/app/src/cli/services/app-doctor-engine/checks/embedded.ts Updates embedded guidance; template guidance needs correction.
packages/app/src/cli/services/app-doctor-engine/checks/COMMITTED_SECRET.md Updates check documentation; template guidance needs correction.
.changeset/app-doctor-secret-false-positives.md Documents the patch release.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/app/src/cli/services/app-doctor-engine/rules/secret-rules.ts Outdated
Comment thread packages/app/src/cli/services/app-doctor-engine/rules/secret-rules.ts Outdated
Comment thread packages/app/src/cli/services/app-doctor-engine/checks/COMMITTED_SECRET.md Outdated
Comment thread packages/app/src/cli/services/app-doctor-engine/checks/embedded.ts Outdated
Match multi-suffix env templates, extract quoted JSON secret keys, and
clarify that template files still report known credential formats.

Co-authored-by: AI (Pi/Grok 4.6) <noreply@pi.dev>
Avoid ReDoS on (?:\.[^/]+)* when suffixes contain extra dots.

Co-authored-by: AI (Pi/Grok 4.6) <noreply@pi.dev>
@jplhomer
jplhomer requested review from dmerand and jek September 18, 2026 16:25
Comment on lines +130 to +133
// `SHOPIFY_API_KEY` / `api_key` are client IDs and public; they are not secret names.
// Optional quotes cover JSON/YAML keys (`"password": "…"`) as well as env assignments.
const SECRET_ASSIGNMENT_PATTERN =
/(?:api[_-]?key|api[_-]?secret|access[_-]?token|secret[_-]?key|private[_-]?key|password|SHOPIFY_API_KEY|SHOPIFY_API_SECRET)\s*[:=]\s*(?:"[^"\r\n]+"|'[^'\r\n]+'|[^\s#'"\r\n][^#\r\n]*)/i
/["']?(?:api[_-]?secret|access[_-]?token|secret[_-]?key|private[_-]?key|password|SHOPIFY_API_SECRET)["']?\s*[:=]\s*(?:"([^"\r\n]*)"|'([^'\r\n]*)'|([^\s#'"\r\n][^#\r\n]*))/gi

@lopez-mar lopez-mar Sep 18, 2026

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.

when it comes to leaked credentials, do we care about shopify credentials specifically? or any credentials? because i think we can look for the token prefix patterns maybe? (like shpat, shpss, etc.)

question: ae we aiming to detect leaked Shopify credentials specifically, or credentials more broadly that could compromise the app and merchant data?

because i'm wondering if the deterministic check should focus on recognized secret formats, like how we use prefixes for our secrets (e.g., shpat_, shpss sort of thing). that wouldn't account for legacy secrets that don't have prefixes admittedly, though i'm not sure how common that is. wrt non-shopify secrets, we could also search for things with well known formats like stripe secret keys (e.g., sk_live_ but not sk_test_), github tokens (e.g., ghp_, github_pat_) , etc.

i think this change reduces the false positives which is good, but i think it's worth being explicit about whether we care about non-shopify api keys being detected. i'm not sure but maybe there are things we could flag for agentic review to be verified? just spitballing

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.

when it comes to leaked credentials, do we care about shopify credentials specifically? or any credentials?

I think our product aim is to try to catch common versioned secrets, even non-Shopify. I'll double-check this assumption!

wrt non-shopify secrets, we could also search for things with well known formats like stripe secret keys (e.g., sk_live_ but not sk_test_), github tokens (e.g., ghp_, github_pat_) , etc.

We support some of these common ones (Google, Stripe, AWS, Slack) today - see test cases in packages/app/src/cli/services/app-doctor-engine/tests/secret-safety.test.ts.

Comment thread packages/app/src/cli/services/app-doctor-engine/rules/secret-rules.ts Outdated
Unquoted 32-hex Shopify secrets now match the quoted form. Assignment
scans no longer consume the next line or treat HAS_PASSWORD as a secret.

Co-authored-by: AI (Pi/Grok 4.6) <noreply@pi.dev>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: @shopify/app @shopify/app package issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants