Skip to content

fix(security): CI hardening — permissions, npm ci, Dependabot, CODEOWNERS (SDK-6067/6069/6071)#83

Open
AakashHotchandani wants to merge 2 commits into
masterfrom
security/nightwatch-ci-hardening
Open

fix(security): CI hardening — permissions, npm ci, Dependabot, CODEOWNERS (SDK-6067/6069/6071)#83
AakashHotchandani wants to merge 2 commits into
masterfrom
security/nightwatch-ci-hardening

Conversation

@AakashHotchandani
Copy link
Copy Markdown
Collaborator

@AakashHotchandani AakashHotchandani commented May 27, 2026

Summary

Batched, mechanical CI/config hardening for three tickets (same repo, same type).

Ticket CWE Change
SDK-6067 732 Add least-privilege top-level permissions: to reviewing_changes.yml
SDK-6069 1357 Add .github/dependabot.yml + switch npm installnpm ci
SDK-6071 284 Widen CODEOWNERS .github/*.github/**

Details

SDK-6067 — workflow token scopes. The workflow had no permissions: block, so it inherited broad default GITHUB_TOKEN scopes. The job only checks out the repo and creates check runs via actions/github-script, so it's scoped to exactly:

permissions:
  contents: read
  checks: write

SDK-6069 — dependency drift. Adds .github/dependabot.yml with weekly npm and github-actions update schedules (the latter also helps the unpinned-actions risks tracked elsewhere in this audit), and switches the install step to npm ci for reproducible, lockfile-pinned installs.

SDK-6071 — CODEOWNERS gap. .github/* is a single-level glob that does not match .github/workflows/*, leaving workflow files without required Code Owner review. Widened to .github/**.

Verification

  • Both YAML files parse (js-yaml); workflow permissions resolves to {contents: read, checks: write}.
  • npm ci succeeds against the committed lockfile — the npm installnpm ci switch will not break CI.
  • Diff scoped to .github/ only (CODEOWNERS, reviewing_changes.yml, new dependabot.yml).

Note: permissions and npm ci only take effect once merged to the default branch and the workflow is next dispatched.

Jira: SDK-6067, SDK-6069, SDK-6071

🤖 Generated with Claude Code

…NERS (SDK-6067, SDK-6069, SDK-6071)

Batched mechanical CI/config hardening for the nightwatch sample repo:

- SDK-6067 (CWE-732): add a least-privilege top-level `permissions:` block to
  reviewing_changes.yml (`contents: read`, `checks: write`). The job only reads
  the repo for checkout and writes check runs via github-script; previously it
  inherited broad default GITHUB_TOKEN scopes.
- SDK-6069 (CWE-1357): add .github/dependabot.yml (weekly npm + github-actions
  updates) so transitive CVEs are surfaced automatically, and switch
  `npm install` -> `npm ci` for reproducible, lockfile-pinned CI installs.
- SDK-6071 (CWE-284): widen CODEOWNERS `.github/*` -> `.github/**` so the
  recursive glob actually covers `.github/workflows/` (single-level `*` left
  workflow files without required Code Owner review).

Verified: both YAML files parse (js-yaml); workflow `permissions` resolves to
{contents: read, checks: write}; `npm ci` succeeds against the committed
lockfile (so the install-command switch will not break CI).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AakashHotchandani AakashHotchandani requested a review from a team as a code owner May 27, 2026 10:43
…rget-branch/grouping

pr-review on #83 flagged that CODEOWNERS uses last-match-wins, so the trailing
catch-all '*' rule still won for .github/ files and SDK-6071's bypass was not
actually closed by the glob widening alone. Reorder so '*' precedes '.github/**',
making the .github/** rule the last (winning) match for workflow/config files.

Also applied the two review nits: explicit target-branch: master on both
Dependabot ecosystems, and a groups: block to batch github-actions bumps.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@AakashHotchandani
Copy link
Copy Markdown
Collaborator Author

🤖 Automated review (pr-review agent) — final (re-reviewed after fix)

Verdict: ✅ Approve — Risk: Low · 0 critical · 0 warnings · 0 suggestions (head 5bdebcf).

Initial review found one blocking issue, now fixed: CODEOWNERS uses last-match-wins, so the original .github/*.github/** glob widening alone did not close SDK-6071's bypass — the trailing catch-all * rule still won for .github/ files. The follow-up commit reorders so * @automate-public-repos comes first and .github/** @asi-devs is last → asi-devs is now the effective owner for .github/workflows/*. This matters concretely: the workflow injects live BROWSERSTACK_USERNAME/ACCESS_KEY (lines 30-31), so the owner gate on workflow edits is the real control.

Per-ticket:

  • SDK-6067 — permissions: {contents: read, checks: write} exactly matches job usage (checkout + checks.create via SHA-pinned github-script). No over-grant, no job-level override re-broadening scope. ✅
  • SDK-6069 — single npm ci invocation; safe with the lockfileVersion-1 lockfile (all entries carry integrity) across the node 14/16/18 matrix. dependabot.yml valid; target-branch: master + github-actions groups: nits applied. ✅
  • SDK-6071 — bypass fully closed by the rule reorder. ✅

Per-file confidence: all three files → 🟢 All Clear.

⚠️ One repo-setting follow-up (outside this PR): CODEOWNERS only enforces if branch protection on master has "Require review from Code Owners" enabled — please confirm post-merge. SDK-6071 itself flagged this as unverified.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant