# How actions/checkout Handles Credential Persistence and Security from v6 Onwards

> Discover how actions/checkout v6 enhances security by isolating authentication tokens and SSH keys in temporary files, preventing them from appearing in audit logs.

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

---

**Starting with version 6.0.0, `actions/checkout` isolates all authentication tokens and SSH keys in temporary, runner-specific files instead of storing them directly in the repository's `.git/config`, using a placeholder technique to prevent credentials from appearing in audit logs.**

The official GitHub `actions/checkout` action introduced a fundamental security redesign in version 6.0.0 to harden credential handling during repository clones. This article breaks down how the action now leverages temporary credential files, scoped Git configurations, and automatic cleanup routines to prevent secret leakage, based on the implementation in [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts) and related source files.

## Temporary Credential Isolation

The core security improvement in version 6 involves moving authentication material out of the permanent Git configuration and into ephemeral files with restricted lifetimes.

### The Unique Credentials File Structure

According to the source code in [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts) (lines 24-28), the action generates a unique `git-credentials-*.config` file directly under the `RUNNER_TEMP` directory. This file contains the Base-64 encoded token required for HTTPS authentication. By storing credentials in a dedicated temporary file rather than the repository's local `.git/config`, the action ensures that sensitive data never persists in the working directory beyond the job's execution.

### Audit Log Protection via Placeholders

To prevent the token from appearing in process-creation audit events, the helper implements a two-stage write process (lines 30-38). First, it writes a placeholder string `AUTHORIZATION: basic ***` to the temporary credentials file. Then, it immediately replaces this placeholder with the actual Base-64 encoded token. This technique ensures that command-line logging or process monitoring systems capture only the masked placeholder rather than the real secret.

## Scoped Git Configuration with includeIf

Rather than modifying the global Git configuration permanently, the action uses conditional includes to scope authentication to specific repository paths.

### Repository-Scoped Authentication

As implemented in [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts) (lines 73-84), the helper adds `includeIf.gitdir:<repo>.path` and work-tree equivalent entries to the Git configuration. These entries point to the temporary credentials file, instructing Git to load the authentication data only when operating within the checked-out repository's directory structure. This provides **least-privilege exposure** by ensuring the token is not available to arbitrary Git operations outside the intended scope.

### Cross-Environment Support

The implementation accounts for both host runner and containerized environments by creating separate `includeIf` entries. One entry targets the standard host path (`/github/workspace/...`), while another points to the container environment (`/github/runner_temp/...`). This dual-entry approach ensures consistent credential access regardless of whether the workflow executes directly on the runner or inside a Docker container.

## Global Git Configuration and Temporary HOME

When `persist-credentials` is set to `true` (the default), the action must handle global Git configuration without polluting the runner's actual `HOME` directory.

As detailed in [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts) (lines 85-95), the helper creates a **temporary HOME** directory for the duration of the job. It copies any existing global `.gitconfig` into this temporary location, then appends the `includeIf` entries to the temporary global config. The `HOME` environment variable is updated to point to this ephemeral directory, ensuring all Git processes read from the isolated configuration. The temporary HOME and its contents are removed after the checkout step completes.

## SSH Key Isolation and Management

For repositories using SSH authentication, the action applies similar isolation principles to private keys and `known_hosts` files.

Based on [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts) (lines 50-70), when an SSH key is supplied via the `ssh-key` input, the helper writes both the key and a custom `known_hosts` file to `RUNNER_TEMP`. It then constructs a `GIT_SSH_COMMAND` environment variable that explicitly references these temporary files. When credential persistence is enabled, this SSH command configuration is also written to the local or temporary global Git config, ensuring subsequent Git operations can authenticate without exposing the key material in process listings.

## Automatic Credential Cleanup

Regardless of the persistence setting, the action implements strict cleanup procedures to ensure no secrets survive the job.

The `removeAuth` method (lines 72-78) orchestrates the removal of all temporary artifacts. It invokes `removeToken` to delete the `git-credentials-*.config` file and `removeSsh` to remove the SSH key and `known_hosts` files. Additionally, it strips all injected `includeIf` entries from the Git configuration. This guarantees that credentials exist only for the minimum necessary duration and are irrevocably destroyed after the checkout step finishes, even if the job subsequently fails or is canceled.

## Configuring Credential Persistence in Workflows

The `persist-credentials` input in [`action.yml`](https://github.com/actions/checkout/blob/main/action.yml) controls whether these security mechanisms are active for subsequent steps.

By default, `persist-credentials: true` maintains the temporary credential file and Git configuration entries so later steps in the job can execute authenticated Git commands (such as `git push`). To disable this behavior and remove credentials immediately after the initial clone, set the input to `false`:

```yaml
- uses: actions/checkout@v6
  with:
    persist-credentials: false

```

Even when set to `false`, the action still uses the token or SSH key for the initial checkout operation; however, it skips writing the temporary credentials file and `includeIf` entries, leaving subsequent Git commands unauthenticated.

For SSH-based authentication, specify the key explicitly:

```yaml
- uses: actions/checkout@v6
  with:
    ssh-key: ${{ secrets.SSH_PRIVATE_KEY }}
    persist-credentials: true

```

## Summary

- **Temporary File Isolation**: Credentials are stored in `git-credentials-*.config` under `RUNNER_TEMP`, never in the permanent `.git/config`.
- **Placeholder Technique**: The action writes a masked placeholder before substituting the real token to avoid audit log exposure in process creation events.
- **Scoped Authentication**: `includeIf.gitdir` directives restrict credential usage to the specific repository path and environment (host or container).
- **Ephemeral HOME Directory**: Global Git configs are isolated in a temporary HOME directory when persistence is enabled, preventing cross-job contamination.
- **Automatic Cleanup**: The `removeAuth` routine deletes all temporary files and configuration entries after the checkout step completes.

## Frequently Asked Questions

### What is the primary security improvement in actions/checkout v6?

The primary improvement is the isolation of authentication tokens and SSH keys into temporary files under `RUNNER_TEMP`, referenced via `includeIf` directives, rather than storing them directly in the repository's `.git/config`. This prevents secrets from persisting in the working directory and reduces their visibility in system audit logs.

### Where does actions/checkout store the GitHub token during workflow execution?

According to [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts), the token is stored in a uniquely named `git-credentials-*.config` file located in the `RUNNER_TEMP` directory. Git accesses this file through conditional `includeIf.gitdir` entries injected into the configuration, rather than reading the token from the standard credential helper or config file.

### How does the action prevent credentials from appearing in process audit logs?

The helper uses a placeholder substitution technique (lines 30-38): it first writes `AUTHORIZATION: basic ***` to the temporary credentials file, then immediately replaces the asterisks with the actual Base-64 token. This ensures process-creation event monitors log only the placeholder value.

### Does setting persist-credentials: false disable authentication entirely?

No. When `persist-credentials: false` is set, the action still uses the provided token or SSH key to perform the initial repository clone. However, it does not create the temporary credentials file or inject `includeIf` entries into the Git config, meaning subsequent steps cannot perform authenticated Git operations unless they provide their own credentials.