Skip to content

Security baseline now that the repo is public: CodeQL, dependency review, secret scanning #287

Description

@rowkav09

Goal

The repo is now public, so the checks that were parked in #127 because they needed GitHub Advanced Security on a private repo are free. Turn them on.

Current state (checked 23 Sept)

Scope

  • Enable CodeQL for JavaScript/TypeScript, C# (setup window) and Actions, either default setup or a pinned least-privilege workflow
  • Re-add the Dependency Review PR check from ci: review dependency changes in pull requests #144 with SHA-pinned actions and minimum permissions
  • Enable secret scanning and push protection
  • Run a one-off scan of full git history for leaked secrets from the private period, and rotate anything found

Done when

  • CodeQL results show on PRs and on main
  • Dependency Review runs on every PR and is green on a clean PR
  • Secret scanning and push protection show as enabled in repo settings
  • History scan done, results noted here (no secret values pasted)

Refs #127

Activity

  1. rowkav09 commented on Sep 23, 2026

    @rowkav09
    MemberAuthor

    Status: CodeQL (#302, alert fixes in #311) and Dependency Review (#300) are merged. Still to do: secret scanning and push protection are still disabled in repo settings (checked just now), and the one-off git history secret scan hasn't been done yet.

  2. rowkav09 commented on Sep 23, 2026

    @rowkav09
    MemberAuthor

    Correction: the git history scan is done. gitleaks ran over a full mirror (546 commits, all branches) plus targeted greps. It found no real secrets, only test fixtures, so nothing needs rotating. The only thing left is turning on secret scanning and push protection in repo settings. That's with the repo owner.

  3. moved this from Backlog to In Progress in nowplayingon Sep 24, 2026
  4. rowkav09 commented on Sep 27, 2026

    @rowkav09
    MemberAuthor

    Work split for the security baseline (record, 2026-09-27). Three independent tracks:

    1. Dependency Review workflow - reintroduce as .github/workflows/dependency-review.yml (it was removed in ci: fix actionlint Linux archive name #150 when ci: review dependency changes in pull requests #144 parked): run on PRs to the default branch, fail on moderate+ severity with a visible summary, pinned action SHA, read-only permissions. Lands as a normal reviewed PR.
    2. CodeQL - advanced setup is a workflow file (codeql.yml, javascript-typescript + csharp, default + security-and-quality queries, PR + weekly cron) and can ship the same reviewed-PR path. Default setup is a repo-settings flip instead; only one of the two should be live or they conflict.
    3. Secret scanning + push protection - repo-settings only (Settings > Code security), no code involved.

    Recommended order: track 1 first (fully in-repo), then decide CodeQL advanced-vs-default, then the settings flips. Acceptance for the issue: PRs show dependency-review results, code scanning alerts exist for JS/TS and C#, and a pushed test secret is blocked by push protection.

  5. rowkav09 commented on Sep 27, 2026

    @rowkav09
    MemberAuthor

    #287 closeout audit against main c67c5e7

    Verified 2026-09-27. Tracks 1 and 2 are both live and match the record spec; track 3 is repo settings, with the repo owner.

    Track 1 - Dependency review workflow. Live as .github/workflows/dependency-review.yml (landed c57691d via #300, fail threshold added in a3c1fb8).

    • Runs on every PR (pull_request with no branch filter - a superset of "PRs to the default branch"). Ticked.
    • Fails on moderate+ severity (fail-on-severity: moderate). Ticked. It also denies AGPL/SSPL licenses, which goes beyond the spec.
    • Pinned action SHAs: checkout @11d5960 (v4), dependency-review-action @a1d282b (v5.0.0). Ticked.
    • Read-only: contents: read at workflow and job level, persist-credentials: false. Ticked.
    • Visible on PRs: the dependency-review check ran and passed on docs: complete guide prose for the tested example paths (#142 phase 2) #697. Ticked.

    Track 2 - CodeQL. Live as .github/workflows/codeql.yml (landed eb29504 via #302, queries widened in 53713a2).

    • Languages: javascript-typescript, csharp, plus actions (workflow analysis beyond the spec). Ticked.
    • Queries: security-and-quality, a superset of the default suite. Ticked.
    • Triggers: PR, push to main, weekly cron 17 4 * * 1. Ticked.
    • Pinned SHAs: codeql-action init/analyze @1c5b675 (v4.38.1). Ticked.
    • Permissions: contents: read plus security-events: write (required to upload alerts). Ticked.
    • Green on PR docs: complete guide prose for the tested example paths (#142 phase 2) #697 and on main (latest main CodeQL run 36352890884, success). A failing upload would fail the analyze job, so upload works; the alerts tab contents themselves are not listable with this token (code-scanning API returns 403), so that part is asserted from run health rather than API listing.

    Track 3 - Secret scanning + push protection. Repo settings only (Settings > Code security and analysis) - nothing in-repo to audit, no code involved. Rowan's flip; the pushed-test-secret acceptance check is already queued with him.

    One thing for the settings pass: the record says default CodeQL setup and this advanced workflow must not both be live. Advanced is live; default setup state is not visible with this token, so Rowan should confirm default setup is off when he does track 3.

    Acceptance status. Criteria 1 (PRs show dependency-review results) and 2 (code scanning for JS/TS and C#) are met in-repo. Criterion 3 (a pushed test secret is blocked) stays open until track 3 lands. Keeping the issue open for that.

  6. rowkav09 commented on Sep 29, 2026

    @rowkav09
    MemberAuthor

    Track 3 record (29 Sept, delegated by Rowan this morning):

    • Secret scanning: ENABLED, verified in repo settings via API.
    • Push protection: ENABLED, verified in repo settings via API.
    • Test-secret push result: NOT BLOCKED. Two pushes of a file containing an obviously fake, pattern-valid GitHub token (ghp_ + 36 chars; no access to anything) on a throwaway branch both succeeded with push protection enabled. The branch was deleted immediately after each test; no secret, real or fake, remains on any branch.

    So the "enabled in repo settings" criterion is literally met, but the control does not actually block token-shaped pushes for this pusher. Possible causes (unverified from here): org-level delegated bypass, the patterns being placeholder-filtered, or a gap between the repo toggle and enforcement. Leaving this issue open - the enabling is done, but whether the non-blocking push protection needs investigation is Rowan's call.

  7. rowkav09 commented on Sep 29, 2026

    @rowkav09
    MemberAuthor

    Correction and closeout on track 3 (29 Sept) - my earlier comment on this issue was wrong, and the correction matters.

    What I claimed earlier: push protection is enabled but does not block, based on two pushes of a fake GitHub-token-shaped string going through.

    What is actually true, verified with the same throwaway-branch method after Rowan said "try fix": push protection WORKS. A push carrying a Slack-pattern fixture was declined by GitHub - "push declined due to repository rule violations" with a secret-scanning unblock URL, fixture identified at PUSH-PROTECTION-TEST.txt:5. Enforcement is active.

    Why my earlier probes were misleading: fake strings shaped like GitHub's own tokens (ghp_ + 36 chars) are not treated as secrets by the detector - GitHub can validate its own token formats and does not flag non-functional ones. An AWS-style fixture was also not flagged. So the earlier "control does not block" conclusion was a wrong inference from probes the detector legitimately ignores, not a control failure. Nothing needed fixing in settings; what needed fixing was my test method. All test branches were deleted immediately after each probe and nothing (real or fake) remains on any branch; the alert list is empty.

    Residual honesty: detection is pattern-based, so not every possible secret shape is caught (the AWS-style fixture passed). That is a property of the detector, not of this repo's setup.

    Done-when audit, all ticked:

    Closing as complete.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions