# How to Push Commits Back Using the Built-In GITHUB_TOKEN with actions/checkout

> Learn how to push commits back using the built-in GITHUB_TOKEN with actions/checkout. Authenticate git push commands seamlessly without extra secrets.

- Repository: [GitHub Actions/checkout](https://github.com/actions/checkout)
- Tags: how-to-guide
- Published: 2026-07-18

---

**The `actions/checkout` action automatically persists the built-in `GITHUB_TOKEN` to the local Git configuration, enabling authenticated `git push` commands in subsequent steps without requiring additional secrets.**

 When using the `actions/checkout` action in GitHub Actions workflows, you can push commits back to the repository using the built-in `GITHUB_TOKEN` without manually configuring authentication headers or passing the token to individual commands. The action handles credential persistence automatically by storing the token provided by `${{ github.token }}` in a temporary Git configuration file during the checkout process.

 ## How Credential Persistence Works

 By default, `actions/checkout` sets the `persist-credentials` input to `true`. According to the logic implemented in [`action.yml`](https://github.com/actions/checkout/blob/main/action.yml) and the compiled [`dist/index.js`](https://github.com/actions/checkout/blob/main/dist/index.js) (lines 42190–42200), this setting instructs the action to write the authentication token to the local Git configuration under `$RUNNER_TEMP`. This credential helper setup allows any Git command executed later in the same job to use the token transparently. The token is removed automatically during the post-job cleanup step to prevent credential leakage between jobs or workflow runs.

 ## Required Workflow Permissions

 To push commits using the built-in token, you must explicitly grant write permissions to the workflow job. By default, the `GITHUB_TOKEN` restricts repository contents to read-only access. As documented in the [`README.md`](https://github.com/actions/checkout/blob/main/README.md) (lines 77–84), you must add the `permissions` block to your workflow:

 ```yaml
 permissions:
   contents: write
 ```

 Without `contents: write`, any attempt to run `git push` will fail with a 403 Forbidden error because the token lacks sufficient scope.

 ## Configuring the Commit Author

 Since the `GITHUB_TOKEN` does not carry a real user identity, you must manually configure Git with a bot account before committing. The standard practice, as shown in the [`README.md`](https://github.com/actions/checkout/blob/main/README.md) examples (lines 32–49), uses the `github-actions[bot]` identity:

 ```bash
 git config user.name "github-actions[bot]"
 git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
 ```

 This ensures commits appear as authored by the GitHub Actions bot rather than displaying generic or empty metadata in the repository history.

 ## Handling Detached HEAD in Pull Requests

 When running on `pull_request` events, the checkout action defaults to checking out the merge commit, placing the repository in detached HEAD mode. To push back to the pull request branch, you must explicitly checkout the head reference using `github.head_ref`, as documented in [`README.md`](https://github.com/actions/checkout/blob/main/README.md) (lines 54–65):

 ```yaml
 - uses: actions/checkout@v4
   with:
     ref: ${{ github.head_ref }}
 ```

 Omitting this configuration causes push operations to fail because HEAD is not attached to a branch reference.

 ## Complete Working Examples

 ### Push to Default Branch

 The following workflow generates a timestamp file and pushes it back to the current branch using the built-in token:

 ```yaml
 on: push
 jobs:
   update:
     runs-on: ubuntu-latest
     permissions:
       contents: write
     steps:
       - uses: actions/checkout@v4
       - run: |
           date > timestamp.txt
           git config user.name "github-actions[bot]"
           git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
           git add timestamp.txt
           git commit -m "Update timestamp"
           git push
 ```

 ### Push to Pull Request Branch

 For workflows triggered by pull requests, checkout the head ref to enable pushing back to the source branch:

 ```yaml
 on: pull_request
 jobs:
   format:
     runs-on: ubuntu-latest
     permissions:
       contents: write
     steps:
       - uses: actions/checkout@v4
         with:
           ref: ${{ github.head_ref }}
       - run: |
           echo "Formatting changes" >> report.md
           git config user.name "github-actions[bot]"
           git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
           git add report.md
           git commit -m "Add formatting report"
           git push
 ```

 ## Summary

 - The `actions/checkout` action automatically persists the `GITHUB_TOKEN` to Git configuration when `persist-credentials` is `true` (the default), storing credentials in `$RUNNER_TEMP` and cleaning them up post-job.
 - You must grant `contents: write` permissions in your workflow to enable push operations using the built-in token.
 - Configure `user.name` and `user.email` with the GitHub Actions bot identity before committing to ensure proper attribution.
 - For pull request workflows, checkout `github.head_ref` to avoid detached HEAD state and enable pushing back to the PR branch.
 - No additional secrets are required beyond the automatically provided `GITHUB_TOKEN`.

 ## Frequently Asked Questions

 ### Why does git push fail with authentication errors despite using actions/checkout?

 Authentication failures typically occur when the workflow lacks the required `permissions: contents: write` configuration. By default, the built-in `GITHUB_TOKEN` has read-only access to repository contents. Verify your workflow grants write permissions and that `persist-credentials` is not explicitly set to `false`.

 ### Do I need to pass the token explicitly to the checkout action?

 No. The action automatically uses `${{ github.token }}` (the built-in `GITHUB_TOKEN`) when the `token` input is omitted or left as the default. According to [`action.yml`](https://github.com/actions/checkout/blob/main/action.yml), this default value provides seamless authentication for subsequent Git operations without exposing the token in workflow definitions.

 ### How long does the token persist in the runner?

 The token remains available for the duration of the job only. The action writes credentials to a temporary location under `$RUNNER_TEMP` during the checkout step and automatically removes them in the post-job cleanup phase. This ensures the credential does not leak to subsequent jobs or workflow runs.

 ### Can I use the built-in token to push to a different repository?

 No. The built-in `GITHUB_TOKEN` is scoped only to the repository where the workflow runs. To push commits to a different repository, you must use a Personal Access Token (PAT) or GitHub App token with appropriate permissions, passed explicitly via the `token` input or stored as a repository secret.