Skip to main content
ISSUE-307LowCI/CD Secrets

Checkout persists credentials in .git/config

Control: Checkout must not persist credentialsยท Config key: checkoutMustNotPersistCredentials

๐Ÿ“‹ What is this?

A workflow calls actions/checkout without persist-credentials: false, which leaves the GITHUB_TOKEN bound to .git/config for the rest of the job.

โš ๏ธ Impact

On its own this is latent: the token is discarded when the job ends. It becomes a demonstrable leak when a later actions/upload-artifact step bundles .git into the artifact zip - that escalation is reported separately as ISSUE-310 (high). The other route, a persisted credential harvested by fork-controlled code, is covered by ISSUE-802 and ISSUE-804.

๐Ÿ”ง How to fix

Set persist-credentials: false on every actions/checkout step unless you have a specific reason to keep the credentials configured.

โœ— BeforeThe artifact zip contains the workflow's GITHUB_TOKEN bound to .git/config.
# .github/workflows/build.yml: โŒ Credentials remain in .git/config
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4 # persist-credentials defaults to true
- run: ./build.sh
- uses: actions/upload-artifact@v4
with:
path: . # bundles .git/config including credentials
โœ“ AfterNo credentials in .git/config; artifact scoped to dist/.
# .github/workflows/build.yml: โœ… persist-credentials: false
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- run: ./build.sh
- uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0
with:
path: dist/ # narrow path, no .git

๐Ÿ’ก Tips

  • If a subsequent step needs to push back to the repo, configure git credentials explicitly via git remote set-url origin https://x-access-token:$GH_TOKEN@github.com/....
  • Never upload the entire workspace as an artifact. Always narrow the path.

โš™๏ธ Configuration

This control is configured in .plumber.yaml under the github section:

github:
  controls:
    checkoutMustNotPersistCredentials:
      enabled: true

See the CLI documentation for the full configuration reference.