# How actions/checkout Uses includeIf.gitdir for Secure Credential Isolation

> Learn how actions/checkout uses includeIf.gitdir to securely isolate authentication credentials. Discover how this feature protects tokens for specific repositories and worktrees.

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

---

**The actions/checkout action isolates authentication credentials by writing tokens to a temporary UUID-named config file under `RUNNER_TEMP` and selectively including it via `includeIf.gitdir` directives, ensuring credentials are only visible to the specific repository, worktrees, and submodules during job execution.**

The `actions/checkout` action handles repository cloning and authentication for millions of GitHub Actions workflows daily. To prevent personal access tokens from persisting in global Git configuration or leaking across repository boundaries on shared runners, the action implements a strict **credential isolation** mechanism using Git's `includeIf.gitdir` configuration directive.

## The Architecture of Credential Isolation

The isolation strategy centers on keeping authentication material outside the standard Git configuration hierarchy. Instead of storing tokens in `~/.gitconfig` or the repository's local `.git/config`, the action uses a temporary credential file that is selectively loaded only when Git operates within specific directories.

### Temporary Credentials File Creation

In [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts), the `GitAuthHelper.getCredentialsConfigPath()` method generates a unique file path for each workflow run. The function constructs a filename pattern `git-credentials-<uuid>.config` inside the `RUNNER_TEMP` directory (lines 25-30). 

This file initially receives a placeholder header (`AUTHORIZATION: basic ***`) to prevent the real token from appearing in process argument lists during initial Git configuration commands. The `configureToken()` method then rewrites the file with the actual base64-encoded token after the configuration structure is established (lines 33-40).

### Wiring Credentials with includeIf.gitdir

The action creates conditional Git configuration entries that link specific Git directories to the temporary credentials file. According to the source code in [`src/git-auth-helper.ts`](https://github.com/actions/checkout/blob/main/src/git-auth-helper.ts), the helper constructs configuration keys using the pattern:

```typescript
const hostIncludeKey = `includeIf.gitdir:${gitDir}.path`;

```

This directive tells Git to include the temporary credentials file **only** when the repository's Git directory matches the specified path. The action adds multiple variants to handle edge cases:

- **Host repository**: The primary repository at `${gitDir}.path` (lines 73-81)
- **Worktrees**: Additional entries for `.../worktrees/*.path` patterns to support Git worktree operations
- **Container environments**: When running inside Docker, separate entries map `/github/workspace` to a container-visible copy of the credentials file at `/github/runner_temp/` (lines 84-92)

### Submodule and Nested Repository Support

For repositories with submodules, `configureSubmoduleAuth()` iterates through each submodule's `.git` directory and repeats the `includeIf.gitdir` wiring (lines 77-89). This ensures that submodule fetch operations use the same isolated credential context without exposing tokens to the parent repository's configuration or sibling submodules.

## Security Guarantees and Cleanup

The `includeIf.gitdir` approach provides path-based isolation because Git evaluates these conditional includes based on the current working directory's repository root. Other repositories on the same runner cannot trigger the inclusion of the temporary credentials file because their Git directories do not match the scoped paths.

### Automated Cleanup

After job completion, `removeToken()` and `removeIncludeIfCredentials()` execute to scrub all traces from the runner:

1. Locate all `includeIf.gitdir` entries referencing `git-credentials-*.config` files
2. Remove these configuration keys from Git's config
3. Delete the temporary file from `RUNNER_TEMP`

This ensures that even if the runner is reused for subsequent jobs, no authentication material persists in Git configuration or disk.

## Implementation Example

The following TypeScript excerpt illustrates how the action configures this isolation internally:

```typescript
import {createAuthHelper} from './git-auth-helper.js'
import {GitCommandManager} from './git-command-manager.js'

const git = new GitCommandManager()
const authHelper = createAuthHelper(git, {
  authToken: process.env.GITHUB_TOKEN,
  persistCredentials: true,
  nestedSubmodules: true
})

// Configure isolated credential includes for host and submodules
await authHelper.configureAuth()          
await authHelper.configureSubmoduleAuth() 

```

For manual verification or debugging in a running workflow, you can inspect the generated conditional includes:

```bash

# List all includeIf.gitdir configurations

git config --local --get-regexp 'includeIf.gitdir'

# Output will show entries like:

# includeIf.gitdir:/__w/repo/repo/.git.path /home/runner/work/_temp/git-credentials-abc123.config

```

## Summary

- **Temporary file isolation**: Credentials are stored in UUID-named files under `RUNNER_TEMP`, never in global or repository-persistent configuration.
- **Path-scoped includes**: The `includeIf.gitdir:${path}.path` directive ensures credentials are only loaded for specific repository directories, worktrees, and submodules.
- **Container awareness**: Separate configuration entries handle the translation between host runner paths and container-internal paths (`/github/workspace`).
- **Automatic cleanup**: The `removeIncludeIfCredentials()` function scrubs all references and temporary files after job execution, preventing cross-job contamination.

## Frequently Asked Questions

### What is includeIf.gitdir in Git?

`includeIf.gitdir` is a Git configuration directive that conditionally includes additional configuration files based on whether the current Git repository's directory matches a specified path pattern. When the pattern matches, Git loads the referenced config file; otherwise, it ignores those settings entirely. The `actions/checkout` action leverages this to create scoped "firewalls" between repositories on shared self-hosted runners.

### How does actions/checkout prevent token leakage between jobs?

The action prevents leakage by never writing credentials to `~/.gitconfig` or the repository's `.git/config`. Instead, it uses `includeIf.gitdir` to point to a temporary file that is deleted after the job completes. Because the include directive is scoped to a specific Git directory path, other repositories or subsequent jobs cannot access the token even if they run on the same physical runner.

### Why does the action use a placeholder token initially?

The placeholder mechanism (`AUTHORIZATION: basic ***`) exists to prevent the real token from appearing in process argument lists. When `configureToken()` executes `git config` commands, the real token could be visible to other processes via `/proc` or system monitoring tools. Using a placeholder during the initial `git config` call, then rewriting the file directly with the actual token, minimizes the window where sensitive data appears in command-line arguments or shell history.

### Are Docker container workflows protected by this mechanism?

Yes. The action detects containerized environments and creates additional `includeIf.gitdir` entries that map the container-internal repository path (`/github/workspace/.git`) to a container-accessible copy of the credentials file (`/github/runner_temp/...`). This ensures that Git commands running inside Docker containers can authenticate while maintaining the same isolation guarantees as host-runner operations.