Skip to content

ci: harden GitHub Actions token and input handling - #2008

Merged
merill merged 10 commits into
maester365:mainfrom
thetechgy:security/github-actions-hardening
Aug 1, 2026
Merged

ci: harden GitHub Actions token and input handling#2008
merill merged 10 commits into
maester365:mainfrom
thetechgy:security/github-actions-hardening

Conversation

@thetechgy

@thetechgy thetechgy commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

📑 Description

Hardens GitHub Actions token and input handling while preserving active automation behavior:

  • Reduces the automatic GITHUB_TOKEN in update-public-suffix-list to contents: read.
  • Uses the read-only automatic token for checkout in Maester Bot automation, then mints App tokens immediately before pull request creation with only contents: write and pull-requests: write.
  • Passes module version, website version, and release-tag values to shell steps through step-local environment variables instead of direct expression interpolation.
  • Disables persisted checkout credentials in read-only jobs, while retaining checkout authentication in release/versioning jobs that later push through it.
  • Removes the obsolete update-tag-documentation workflow and its sole-purpose build/Update-TagsDocumentation.ps1 generator. GitHub records 116 runs from January 19 through July 25, including 73 on non-main branches. Those runs performed checkout with contents: write, installed Pester, discovered tests, and wrote website/docs/tests/tags/readme.md; however, after the generator moved to that path, the commit step continued checking website/docs/tags.md, logged No changes to commit, and discarded the generated change. Repository history contains no matching chore: update tags documentation bot commit. Since May, website/scripts/generate-test-docs.mjs has owned the current linked tag index and is enforced by the website checks and prebuild. The current generator now also preserves the legacy tag-usage guidance and groups the inventory into CIS, CISA, EIDSCA, ORCA, Maester, and Ungrouped sections. Removing the legacy workflow and script therefore eliminates nonfunctional automation without removing its useful documentation behavior.

The persisted checkout credentials in publish jobs remain an accepted residual because stefanzweifel/git-auto-commit-action requires them for its later push. Existing active triggers, jobs, matrices, artifacts, branches, tags, inputs, and release fallback behavior remain unchanged. The regenerated tag index is the only intended generated-output change.

Supporting guidance:

✅ Checks

  • My pull request adheres to the code style of this project.
  • My code requires changes to the documentation. The repository-restructure proposal referenced the removed legacy script.
  • I have updated the documentation as required. The stale proposal reference was removed, and the generated tag index was updated for feature parity.
  • The build and unit tests pass after running /powershell/tests/pester.ps1 locally.

Local validation completed:

  • Every remaining workflow file parsed successfully as YAML.
  • Structural comparisons confirmed that only the intended token boundaries, environment-variable handling, checkout settings, action pins, obsolete workflow and script removals, and associated proposal cleanup changed.
  • A repository-wide reference check confirmed that no Update-TagsDocumentation references remain.
  • npm --prefix website run generate-test-docs generated 408 test-documentation pages, including website/docs/tests/tags/readme.md, and npm --prefix website run build completed successfully. A subsequent generated-doc comparison reports only the unrelated, time-sensitive contributor snapshot as stale; the tag page is current.
  • git diff --check upstream/main passed.
  • The Pester wrapper was attempted. After installing the same project dependencies used by CI and isolating the run to the CI-pinned Pester 5.7.1, it completed the general-test phase and then stopped producing output in Common.Tests.ps1 for more than 15 minutes. The local run was stopped and is not reported as passing; the required Ubuntu, Windows, and macOS build-validation jobs are the authoritative full-suite result.

Earlier PR checks for commit e951cbc3 (before the tag-index parity update):

  • Passed: CodeQL Actions and JavaScript/TypeScript analysis, PowerShell analysis, PSScriptAnalyzer, Codacy, command-reference generation, and command-reference drift detection.
  • The website build reached npm run check-test-docs and failed only because the pre-existing generated contributor snapshot website/src/data/contributors.json is stale.
  • The required Ubuntu, Windows, and macOS build-validation jobs each ran 10,224 tests and reported the same nine failures: the Global Secure Access functions added in Add 9 Global Secure Access checks (MT.1187–MT.1195) [Preview] #1992 do not satisfy the repository-wide Write-Verbose policy test. This PR does not change those functions, and an unrelated PR run immediately before this one failed on the same checks, so no unrelated GSA implementation was added to this focused workflow-hardening change.
  • The PR remains draft until the upstream validation failures are resolved and all required checks pass.

ℹ️ Additional Information

No repository variables, secrets, environments, generated command documentation, module output, or runtime dependencies are added or changed. The generated tag index is the only generated test documentation changed. No prior issue is required for this focused maintenance change.

Summary by CodeRabbit

  • Security

    • Improved workflow credential handling by preventing checkout credentials from persisting.
    • Reduced default permissions and requested elevated access only when required.
    • Pinned a checkout action revision for improved consistency.
  • Maintenance

    • Improved version and release value handling across publishing workflows.
  • Documentation

    • Reorganized tag documentation into suite-based sections with clearer usage guidance and grouped tag tables.
  • Removed

    • Removed automated tag documentation generation and its supporting script.

@coderabbitai

coderabbitai Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The pull request hardens GitHub Actions checkout and token handling, passes release values through environment variables, removes tag documentation automation, and groups generated tag documentation by suite.

Changes

Workflow maintenance

Layer / File(s) Summary
Checkout and token flow updates
.github/workflows/build-*.yaml, .github/workflows/*review.yaml, .github/workflows/codeql.yml, .github/workflows/opengrep.yml, .github/workflows/update-*.yaml, .github/workflows/build-website.yaml
Checkout steps disable credential persistence. Selected workflows generate GitHub App tokens after repository updates and request explicit permissions.
Release version environment propagation
.github/workflows/publish-module*.yaml, .github/workflows/publish-tests.yaml, .github/workflows/publish-versioned-docs.yml
Workflows pass module, release-tag, and website-version values through step environment variables to PowerShell and Node commands.

Tag documentation

Layer / File(s) Summary
Grouped tag documentation
website/scripts/tag-groups.mjs, website/scripts/tag-groups.test.mjs, website/scripts/generate-test-docs.mjs, website/docs/tests/tags/readme.md
The generator classifies tags into ordered groups, renders grouped tables, and documents tag categories, usage, counts, and examples. Tests cover group matching.
Tag documentation automation removal
build/Update-TagsDocumentation.ps1, .github/workflows/update-tag-documentation.yml, docs/proposals/repo-restructure.md
The tag documentation script and workflow are removed. The restructuring proposal removes the script reference.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related PRs

Suggested labels: github_actions, automation, documentation

Suggested reviewers: merill

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the primary GitHub Actions security changes to token permissions and input handling.
Description check ✅ Passed The description explains the changes, validation results, documentation updates, and known pre-existing failures in the required sections.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

codacy-production Bot commented Jul 26, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 18 complexity

Metric Results
Complexity 18

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@thetechgy
thetechgy marked this pull request as ready for review July 26, 2026 21:50
@thetechgy
thetechgy requested a review from a team as a code owner July 26, 2026 21:50
Copilot AI review requested due to automatic review settings July 26, 2026 21:50

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.

Pull request overview

This PR hardens GitHub Actions token usage and shell input handling by reducing default GITHUB_TOKEN privileges, limiting credential persistence on checkouts, and deferring higher-privilege GitHub App token minting until just before PR creation. It also removes legacy, nonfunctional tag-documentation automation.

Changes:

  • Reduce default workflow/job token privileges and disable persisted checkout credentials in read-only jobs.
  • Mint GitHub App tokens only immediately before PR creation, with narrowly scoped contents: write / pull-requests: write.
  • Avoid direct ${{ }} interpolation in shell commands by passing values via step-local environment variables; remove obsolete tag doc workflow/script and update action pins.

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
docs/proposals/repo-restructure.md Removes obsolete proposal reference to the deleted tag-doc generator.
build/Update-TagsDocumentation.ps1 Removes legacy tag documentation generator script.
.github/workflows/update-tag-documentation.yml Removes legacy workflow that attempted to generate/commit tag docs.
.github/workflows/update-role-definitions.yaml Uses read-only checkout token; mints App token only for PR creation; disables persisted creds.
.github/workflows/update-public-suffix-list.yaml Reduces default job token to contents: read; mints App token only for PR creation; disables persisted creds.
.github/workflows/update-module-docs.yaml Uses read-only checkout token; mints App token only for PR creation; disables persisted creds.
.github/workflows/build-docs.yaml Uses read-only checkout token; mints App token only for PR creation; disables persisted creds.
.github/workflows/publish-versioned-docs.yml Passes input version to Node via step env var (safer shell argument handling).
.github/workflows/publish-tests.yaml Disables persisted checkout creds; passes release tag via env vars; updates cpina action pin.
.github/workflows/publish-module.yaml Passes module version via env vars into PowerShell/Node steps.
.github/workflows/publish-module-preview.yaml Passes module version via env vars into PowerShell/Node steps.
.github/workflows/publish-module-manualversionupdate.yaml Passes module version via env vars into PowerShell/Node steps.
.github/workflows/opengrep.yml Disables persisted checkout creds in scan job.
.github/workflows/maester-action-smoke-test.yaml Aligns checkout pin to actions/checkout v7.0.1 SHA.
.github/workflows/dependency-review.yaml Disables persisted checkout creds for dependency review job.
.github/workflows/codeql.yml Disables persisted checkout creds (but currently introduces invalid YAML indentation in steps).
.github/workflows/build-website.yaml Disables persisted checkout creds across website build jobs.
.github/workflows/build-maester-report-template.yaml Disables persisted checkout creds in report-template build job.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/codeql.yml
@SamErde

SamErde commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

I love the intent and the goal of this PR! The one thing I want to check: the newer test auto-documentation workflow doesn't completely replace what the tag documentation workflow does (as far as I have seen). Let's see if we can find a way to get feature parity before the tag documentation is removed.

As an aside, I think the last website reorganization resulted in some valuable pages being lost from the navigation structure and I'd like to see some of those recovered as well.

@thetechgy

thetechgy commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

I love the intent and the goal of this PR! The one thing I want to check: the newer test auto-documentation workflow doesn't completely replace what the tag documentation workflow does (as far as I have seen). Let's see if we can find a way to get feature parity before the tag documentation is removed.

As an aside, I think the last website reorganization resulted in some valuable pages being lost from the navigation structure and I'd like to see some of those recovered as well.

I was under the impression that website/scripts/generate-test-docs.mjs replaced the .github/workflows/update-tag-documentation.yml workflow + build/Update-TagsDocumentation.ps1 script. Additionally, looking at the run history, that workflow doesn't appear to have led to a commit in the past year.

I could be wrong on both points, but that's how it seemed to me. It would be good if someone else could verify or disprove :)

@SamErde

SamErde commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Additionally, looking at the run history, that workflow doesn't appear to have led to a commit in the past year.

I didn't think that workflow was even a year old?

@thetechgy

Copy link
Copy Markdown
Contributor Author

Additionally, looking at the run history, that workflow doesn't appear to have led to a commit in the past year.

I didn't think that workflow was even a year old?

You're right - it was introduced in commit d2ddee1 in December 2025.

What I meant was that based on the run history since it was implemented, the workflow doesn't appear to have produced a commit. I phrased that poorly.

@merill

merill commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

I removed the cpina gh action pin change in this commit since I'm removing the third party dependency completely and using the Maester Bot to perform the task. See #2068

@merill
merill requested a review from a team as a code owner August 1, 2026 04:05
@merill

merill commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

@SamErde The tag-documentation feature-parity concern is now addressed in 5284e66.

We kept one source of truth: website/scripts/generate-test-docs.mjs now generates website/docs/tests/tags/readme.md with the legacy tag-usage guidance and the CIS, CISA, EIDSCA, ORCA, Maester, and Ungrouped sections. The generated tables retain test counts and links to example tests.

The obsolete workflow and PowerShell script remain removed, so two generators cannot drift or overwrite the same page.

Validation:

  • generated all 408 test-documentation pages
  • completed the Docusaurus production build successfully
  • the generated-doc comparison reports only the unrelated, time-sensitive contributor snapshot as stale; the tag page is current

The broader navigation-recovery aside is not changed by this focused fix and can be handled separately.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@website/scripts/generate-test-docs.mjs`:
- Around line 514-519: Update the CIS matcher in tagGroups so its L1 and L2
alternatives are anchored to match only standalone tags, preventing values such
as CISA.L1, ORCA.L2, or embedded substrings from being classified as CIS. Add
regression cases covering these overlapping-prefix tags and verify they remain
in their correct sections.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 067499ed-173a-400d-a8ef-8226b1eb60e3

📥 Commits

Reviewing files that changed from the base of the PR and between 5087588 and 5284e66.

📒 Files selected for processing (2)
  • website/docs/tests/tags/readme.md
  • website/scripts/generate-test-docs.mjs

Comment thread website/scripts/generate-test-docs.mjs Outdated

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
website/scripts/tag-groups.test.mjs (1)

5-20: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add regression cases for the MS. and Maester branches.

The test covers the CISA prefix but not the MS. alternative. It does not cover the Maester group at all. Add representative cases so these mappings remain protected.

Suggested cases
     ["CISA.L1", "CISA"],
+    ["MS.Azure.Baseline", "CISA"],
     ["EIDSCA.L1", "EIDSCA"],
     ["ORCA.L2", "ORCA"],
+    ["MT.1001", "Maester"],
+    ["Maester", "Maester"],
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@website/scripts/tag-groups.test.mjs` around lines 5 - 20, Add regression
cases to the cases array in the standalone CIS-level classification test for
representative tags using the MS. branch and the Maester group, asserting each
maps to its expected group through tagGroupFor. Keep the existing overlap and
ungrouped cases unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@website/scripts/tag-groups.test.mjs`:
- Around line 5-20: Add regression cases to the cases array in the standalone
CIS-level classification test for representative tags using the MS. branch and
the Maester group, asserting each maps to its expected group through
tagGroupFor. Keep the existing overlap and ungrouped cases unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 0bdfd14f-7c50-46d1-aaa1-cce591f2ae2b

📥 Commits

Reviewing files that changed from the base of the PR and between 5284e66 and 5de7d2a.

📒 Files selected for processing (3)
  • website/scripts/generate-test-docs.mjs
  • website/scripts/tag-groups.mjs
  • website/scripts/tag-groups.test.mjs
🚧 Files skipped from review as they are similar to previous changes (1)
  • website/scripts/generate-test-docs.mjs

@merill merill 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.

LGTM

@merill
merill merged commit 76efb25 into maester365:main Aug 1, 2026
14 checks passed
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.

4 participants