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

> Learn how persist-credentials in actions/checkout manages Git authentication tokens for security and functionality. Control token persistence for authenticated Git operations.

- Repository: [GitHub Actions/checkout](https://github.com/actions/checkout)
- Tags: deep-dive
- Published: 2026-08-29

---

**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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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:

```yaml
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:

```yaml
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:

```yaml
- 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`](https://github.com/actions/checkout/blob/main/src/input-helper.ts) (input parsing), [`src/git-source-provider.ts`](https://github.com/actions/checkout/blob/main/src/git-source-provider.ts) (orchestration logic), and [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/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`](https://github.com/actions/checkout/blob/main/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.