Understanding the `persist-credentials` Input in actions/checkout: Security and Functionality Explained

The persist-credentials input controls whether authentication tokens remain in the Git configuration after actions/checkout completes, enabling subsequent authenticated Git operations when set to true while minimizing security exposure when set to false.

The actions/checkout step is essential for cloning repositories in GitHub Actions workflows. The persist-credentials input determines whether the authentication token used for the initial clone remains available for later steps, directly impacting both workflow functionality and security posture according to the actions/checkout source code.

How persist-credentials Controls Credential Lifecycle

The input accepts a boolean value that dictates the retention strategy for HTTPS tokens or SSH credentials provided to the action.

Enabling Credential Persistence (persist-credentials: true)

When set to true, the authentication token is written to the local Git configuration file (.git/config) and stored in a temporary file under $RUNNER_TEMP. This configuration allows any subsequent Git commands—such as pushing tags, pulling submodules, or making commits—to authenticate automatically without requiring additional tokens.

According to src/input-helper.ts (lines 166-168), this setting is parsed and assigned to result.persistCredentials within the IGitSourceSettings object. The credentials persist until the job completes, at which point the post-job cleanup removes them from the environment.

Disabling Credential Persistence (persist-credentials: false)

By default, persist-credentials is set to false. In this mode, the authentication token is used only for the initial repository checkout and optional submodule fetch. Immediately after these operations complete, the cleanup logic in src/git-source-provider.ts (lines 19-24) invokes authHelper.removeAuth() to strip credentials from the Git configuration. This approach minimizes the risk of accidental credential exposure in later workflow steps that do not require authenticated Git access.

Source Code Implementation Details

The behavior of persist-credentials is implemented across three key files in the repository:

  • src/input-helper.ts: Parses the persist-credentials input value and assigns it to result.persistCredentials, making the setting available throughout the checkout process (lines 166-168).

  • src/git-source-provider.ts: Orchestrates the decision to retain or remove credentials. The logic checks if (!settings.persistCredentials) to determine whether to immediately remove authentication after checkout (lines 19-24).

  • src/git-auth-helper.ts: Implements the actual credential injection and removal logic, manipulating the Git configuration files directly.

Submodule Authentication Implications

The persist-credentials setting directly affects how submodules are authenticated during the checkout process. When persistence is enabled, the action calls gitAuthHelper.configureSubmoduleAuth() to ensure submodule credentials remain available for subsequent Git operations within the same job, as implemented in src/git-source-provider.ts (lines 91-96). If disabled, submodule authentication is temporary and removed immediately after the initial fetch, preventing authenticated access to private submodules in later workflow steps.

Security Considerations and Best Practices

According to the actions/checkout README, storing credentials in $RUNNER_TEMP rather than directly in .git/config provides isolation from the working directory. However, setting persist-credentials: false remains the recommended security posture for workflows that do not perform subsequent authenticated Git operations.

Use persist-credentials: true when subsequent steps need to:

  • Push commits or tags to the repository
  • Fetch additional private submodules
  • Perform authenticated Git operations against the origin

Use persist-credentials: false (default) when:

  • The workflow only needs to read the repository code
  • Subsequent steps do not require Git authentication
  • Minimizing credential exposure is a priority

Configuration Examples

The following workflow demonstrates enabling persistence to push a new tag:

name: Release Workflow
on:
  push:
    branches: [main]

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout with persistent credentials
        uses: actions/checkout@v4
        with:
          persist-credentials: true
      
      - name: Create and push tag
        run: |
          git tag "v$(date +%Y%m%d%H%M%S)"
          git push origin --tags

For workflows that only require read access, explicitly disable persistence:

name: Secure Build
on: [pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout without credential persistence
        uses: actions/checkout@v4
        with:
          persist-credentials: false
      
      - name: Build application
        run: npm ci && npm run build

When using SSH authentication with immediate credential cleanup:

- name: Checkout via SSH
  uses: actions/checkout@v4
  with:
    ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
    persist-credentials: false

Summary

  • The persist-credentials input in actions/checkout determines whether authentication tokens remain available after the initial clone operation.
  • When set to true, credentials are stored in .git/config and $RUNNER_TEMP, enabling subsequent authenticated Git commands until job completion.
  • The default value of false removes credentials immediately after checkout, reducing the attack surface for workflows that do not require further authentication.
  • Implementation resides primarily in src/input-helper.ts (input parsing), src/git-source-provider.ts (orchestration logic), and src/git-auth-helper.ts (credential manipulation).
  • Submodule authentication behavior is controlled by the same flag, determining whether configureSubmoduleAuth() maintains credentials for nested repositories.

Frequently Asked Questions

What is the default value of persist-credentials in actions/checkout?

The default value is false. When you do not explicitly set the persist-credentials input, the action automatically removes authentication tokens from the Git configuration immediately after completing the checkout and submodule fetch operations, as handled by the cleanup logic in src/git-source-provider.ts.

When should I set persist-credentials to true?

Set persist-credentials: true when subsequent workflow steps need to perform authenticated Git operations such as pushing commits or tags, fetching additional private submodules, or interacting with the remote repository. When enabled, credentials remain available in $RUNNER_TEMP and .git/config until the job completes and post-job cleanup runs.

Does persist-credentials affect SSH key authentication?

Yes, the persist-credentials input controls the persistence of both HTTPS tokens and SSH keys configured via the ssh-key input. Setting it to false ensures SSH keys are removed from the Git configuration immediately after checkout, while true maintains them for the duration of the job according to the authentication helper implementation.

Is it safe to use persist-credentials: true?

Using persist-credentials: true is safe when you need authenticated Git access in subsequent steps, as credentials are stored in $RUNNER_TEMP rather than the working directory. However, for workflows that only read code, keeping the default false minimizes exposure risk by ensuring credentials exist only for the minimum necessary duration as recommended in the README documentation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →