fix: include private contributor statistics safely - #11
Conversation
WalkthroughThe project statistics workflow now uses pinned actions, Go 1.26, explicit dependency validation, repository write access, and controlled authentication. The Go script includes private-repository filtering and propagates contributor API errors to ChangesProject statistics update
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant main
participant fetchContributors
participant GitHubAPI
main->>fetchContributors: collect contributor statistics
fetchContributors->>GitHubAPI: fetch commits, issues, and pull requests
GitHubAPI-->>fetchContributors: data or API error
fetchContributors-->>main: contributors or error
main->>main: terminate on contributor-fetch error
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 @.github/workflows/update-projects.yml:
- Line 20: Update the actions/checkout step in the update-projects workflow to
set persist-credentials to false, preventing the GitHub token from being stored
in local Git configuration. If the final push step requires authentication,
provide the token directly to that push command rather than relying on checkout
persistence.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: f870d70f-1a38-4c77-9ff4-b24ecb4a34db
📒 Files selected for processing (2)
.github/workflows/update-projects.ymlscripts/update_projects.go
| timeout-minutes: 10 | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4 |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== workflow excerpt =="
cat -n .github/workflows/update-projects.yml | sed -n '1,180p'
echo
echo "== relevant GHA checkout references =="
rg -n "actions/checkout|persist-credentials|github\.token|git push|go test|update_projects" .github/workflows/update-projects.yml
echo
echo "== repository-controlled Go files paths/stat =="
git ls -l -- . | head -20
git ls-files scripts update_projects.go | head -50
echo
echo "== file sizes if relevant scripts exist =="
for f in $(git ls-files scripts/update_projects.go 2>/dev/null | tr '\n' ' ') scripts/update_projects.go; do
[ -f "$f" ] && echo "--- $f" && wc -l "$f"
doneRepository: HappyHackingSpace/.github
Length of output: 2253
🌐 Web query:
actions/checkout persist-credentials default true github.token local git config
💡 Result:
In the actions/checkout GitHub Action, the persist-credentials input determines whether the authentication token (typically the GITHUB_TOKEN or a provided Personal Access Token) is configured for use with Git [1][2]. When persist-credentials is set to true (which is the default value) [1][2], the action configures the provided credentials so that subsequent steps in the workflow can run authenticated Git commands [1][3]. Regarding how these credentials are stored: - In older versions of actions/checkout, the token was persisted directly in the local.git/config file [4][5]. - As of version 6.0.0 and later, the action has been updated to store these credentials in a separate file located under $RUNNER_TEMP, rather than directly in the local git config [4][6]. This change helps improve security by keeping the credentials out of the local Git configuration file [4][5]. The action automatically removes these credentials during the post-job cleanup phase [1][3]. If you prefer to disable this behavior for security reasons, you can set persist-credentials: false in your workflow step [1][7].
Citations:
- 1: https://github.com/actions/checkout
- 2: https://github.com/actions/checkout/blob/34e114876b0b11c390a56381ad16ebd13914f8d5/action.yml
- 3: https://github.com/actions/checkout/tree/v6.0.2?tab=readme-ov-file
- 4: https://github.com/actions/checkout/tree/v6.0.0
- 5: https://github.com/actions/checkout?v=1.1.1
- 6: actions/checkout@v5.0.1...v6.0.0
- 7: Change the default value of persist-credentials to false actions/checkout#1687
🌐 Web query:
actions/checkout v4 persist-credentials default github.token local git config
💡 Result:
In actions/checkout v4, the persist-credentials input defaults to true [1][2][3]. When set to true, the action automatically configures the local git repository's configuration (stored in.git/config) with the authentication token provided to the action [1][4][5]. If you do not specify a custom token, the action defaults to using the GitHub token (typically secrets.GITHUB_TOKEN) [6][7]. By persisting this token into the local git config, the action enables your workflow scripts to run authenticated git commands (such as git push or git pull) directly within the workspace [1][4][5]. To opt-out of this behavior—which is often recommended for security to prevent the token from being accessible to other processes or potentially leaked through artifacts—you must explicitly set persist-credentials to false [1][5][7]: - uses: actions/checkout@v4 with: persist-credentials: false When persist-credentials is set to false, the action does not write the token into the local git configuration [1][5]. Any subsequent git commands that require authentication will need to be configured separately (e.g., using a credential helper or by manually configuring the git url with credentials) [8]. The token used by the action is automatically removed during the post-job cleanup process in either case [1][4][5].
Citations:
- 1: https://github.com/actions/checkout/blob/v4/README.md
- 2: https://github.com/actions/checkout/blob/v4/action.yml
- 3: https://github.com/actions/checkout/blob/v4.1.1/action.yml
- 4: https://github.com/actions/checkout
- 5: https://github.com/actions/checkout/blob/main/README.md
- 6: Remove
persist-credentialsor change the default tofalseactions/checkout#485 - 7: https://yossarian.net/til/post/actions-checkout-can-leak-github-credentials/
- 8: https://stackoverflow.com/questions/67030607/how-to-config-git-to-use-pat-token-in-github-actions-checkout
🌐 Web query:
GitHub Actions GITHUB_TOKEN contents: write permissions git push token permissions contents read
💡 Result:
The GITHUB_TOKEN is a powerful, repository-scoped token automatically provided by GitHub Actions to authenticate on behalf of the GitHub App installed on your repository [1]. By default, it often has only read access to repository contents, meaning workflows attempting to push commits, create branches, or delete files will fail with a "permission denied" error unless permissions are explicitly elevated [2][3]. To allow a workflow to perform write operations like git push, you must grant the contents: write permission in your workflow file [2][4]. How to grant write permissions: You can define permissions at either the workflow level (for all jobs) or the job level (for a specific job) [5][4]. Specifying the permissions key will override the repository's default token permissions [2][4]. Example configuration: jobs: build: runs-on: ubuntu-latest permissions: contents: write steps: - uses: actions/checkout@v4 # Now you can commit and push changes - run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git commit -am "Update via GITHUB_TOKEN" git push Important considerations: 1. Explicit Override: When you define a permissions block, any permissions not explicitly listed are set to none [4]. If your workflow requires other actions (such as reading metadata or interacting with issues), ensure they are included in the permissions block [4]. 2. Scope: The GITHUB_TOKEN is strictly scoped to the repository containing the workflow [1][6]. It cannot be used to push to other repositories, even if those repositories are under the same organization [6][7]. To push to a different repository, you must use a Personal Access Token (PAT) or a GitHub App installation token stored as a secret [1][7]. 3. Security: Always follow the principle of least privilege [5][2]. Only grant contents: write if the workflow genuinely needs to modify the repository [5][2]. 4. Recursive Workflows: When a workflow uses the GITHUB_TOKEN to push code, it generally does not trigger new workflow runs, which prevents infinite loops [1]. Exceptions exist for certain pull_request events, which may create workflow runs in an "approval-required" state [1].
Citations:
- 1: https://docs.github.com/en/actions/concepts/security/github_token
- 2: https://adhdecode.com/articles/github-actions/github-actions-workflow-permissions/
- 3: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/enabling-features-for-your-repository/managing-github-actions-settings-for-a-repository
- 4: https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax
- 5: https://docs.github.com/en/actions/tutorials/authenticate-with-github_token
- 6: https://stackoverflow.com/questions/79471500/github-actions-authentication-failed-for-pushing-to-repository
- 7: https://stackoverflow.com/questions/64374179/how-to-push-to-another-repository-in-github-actions
Disable checked-out token persistence.
actions/checkout@v4 persists github.token in the local Git config by default, and this job runs repository-controlled Go code before git push. Set persist-credentials: false on checkout and pass the token directly to the push command only if the final step needs it.
🧰 Tools
🪛 zizmor (1.28.0)
[warning] 20-20: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false
(artipacked)
🤖 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 @.github/workflows/update-projects.yml at line 20, Update the
actions/checkout step in the update-projects workflow to set persist-credentials
to false, preventing the GitHub token from being stored in local Git
configuration. If the final push step requires authentication, provide the token
directly to that push command rather than relying on checkout persistence.
Source: Linters/SAST tools
|
@dogancanbakir review pls |
Summary
This PR allows the contributor leaderboard to include activity from authorized private repositories without exposing private repository details in the public organization profile.
Changes
ORG_STATS_TOKENwhen configured and falls back to the default GitHub token otherwise.contents: write.Required configuration
An organization administrator must add an
ORG_STATS_TOKENActions secret to the upstream.githubrepository.The token should have read-only access to the selected repositories with only:
No token value or private repository information is included in this PR.
Security
Private repository names, URLs, project statistics, commit messages, and source code are never written to the public README. Only aggregated contributor counts are published.
Summary by CodeRabbit
Bug Fixes
Reliability