Git & CI/CD Intermediate

Fixing GitHub Actions `checkout` Authentication Failure on CentOS Stream / Rocky Linux

Resolve `checkout` action authentication failures in GitHub Actions self-hosted runners on CentOS Stream and Rocky Linux. Learn to fix common credential, SSH, and SELinux issues.

👨‍💻
Senior Systems Architect • Verified in Staging Labs

Resolve `checkout` action authentication failures in GitHub Actions self-hosted runners on CentOS Stream and Rocky Linux. Learn to fix common credential, SSH, and SELinux issues.

Introduction

Encountering an "authentication failed" error during the actions/checkout step in your GitHub Actions workflow on a CentOS Stream or Rocky Linux self-hosted runner can be a frustrating roadblock. This issue typically prevents your workflow from cloning the repository, halting your CI/CD pipeline. While the error message is straightforward, the underlying causes can range from incorrect GitHub permissions and misconfigured Git credentials to system-level security policies like SELinux.

This guide provides a comprehensive, step-by-step troubleshooting approach, leveraging our 16 years of web hosting and DevOps experience, to diagnose and resolve repository authentication failures specifically within the CentOS/Rocky Linux environment for GitHub Actions self-hosted runners.

Symptom & Error Signature

When the actions/checkout action fails due to authentication issues, your GitHub Actions workflow will typically display an error similar to one of the following:

Run actions/checkout@v4
  with:
    repository: org/repo
    token: ***
    clean: true
    fetch-depth: 1
    lfs: false
    submodules: false
    set-safe-directory: true
  env:
    GH_TOKEN: ***
    ACTIONS_RUNTIME_URL: ...
    ACTIONS_RUNTIME_TOKEN: ***
    ACTIONS_CACHE_URL: ...
    ACTIONS_CACHE_TOKEN: ***
Cloning into '/home/actions-runner/_work/my-repo/my-repo'...
remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.
remote: Please see https://github.blog/2020-07-30-token-authentication-requirements-for-git-operations/ for more information.
fatal: Authentication failed for 'https://github.com/org/repo.git/'
Error: The process '/usr/bin/git' failed with exit code 128

Or, if using SSH and there's a host key or permission problem:

Run actions/checkout@v4
  with:
    repository: [email protected]:org/repo.git
    token: ***
    clean: true
    fetch-depth: 1
    lfs: false
    submodules: false
    set-safe-directory: true
  env:
    GH_TOKEN: ***
    ACTIONS_RUNTIME_URL: ...
    ACTIONS_RUNTIME_TOKEN: ***
    ACTIONS_CACHE_URL: ...
    ACTIONS_CACHE_TOKEN: ***
Cloning into '/home/actions-runner/_work/my-repo/my-repo'...
Host key verification failed.
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
Error: The process '/usr/bin/git' failed with exit code 128

Sometimes, a credential helper might also cause issues:

fatal: credential-cache cannot be used without a GPG key

Root Cause Analysis

The "authentication failed" error indicates that the Git client on your self-hosted runner was unable to successfully negotiate access to the GitHub repository. Common root causes include:

  1. Insufficient GITHUB_TOKEN Permissions: By default, GitHub Actions provides a GITHUB_TOKEN with limited permissions. If your workflow attempts to access a private repository from a different organization, a private repository that the token doesn't have read access to, or requires elevated permissions (e.g., to interact with GitHub Packages), the default token will fail.
  2. Incorrect Git Credentials (PAT/SSH) on Self-Hosted Runner:
    • Personal Access Token (PAT): If you're explicitly using a PAT, it might be expired, revoked, or lack the necessary scopes (e.g., repo scope for private repositories).
    • SSH Key Configuration: If your workflow is configured to use SSH, the runner's user (actions-runner by default) might not have the correct SSH key configured, the key might not be loaded into ssh-agent, or github.com might not be in the known_hosts file.
    • Credential Helper Issues: Git's credential helpers might be misconfigured or encountering issues, preventing credentials from being supplied correctly.
  3. SELinux Interference: On CentOS Stream and Rocky Linux, SELinux (Security-Enhanced Linux) is enabled by default. It can restrict the actions-runner process from accessing critical files (like SSH keys or Git configuration) or network resources, leading to "permission denied" errors that manifest as authentication failures.
  4. Outdated Git Client or Runner Software: Although less common, an outdated Git version might have bugs or compatibility issues. Similarly, an outdated runner application could exhibit unexpected behavior.
  5. Network or Firewall Restrictions: The self-hosted runner might be unable to reach github.com due to local firewall rules, network ACLs, or misconfigured proxy settings, causing connection timeouts or immediate failures.
  6. Runner User Environment Issues: The environment variables (HOME, PATH) for the user running the actions-runner service might not be correctly set, leading Git to look for configuration files or SSH keys in the wrong locations.

Step-by-Step Resolution

Follow these steps to diagnose and resolve GitHub Actions checkout authentication failures on your CentOS Stream / Rocky Linux self-hosted runner.

1. Verify GITHUB_TOKEN Permissions in Workflow

The GITHUB_TOKEN is automatically generated for each workflow run. It has default permissions, which are often sufficient for cloning the current repository. However, if you're trying to perform actions beyond this, or interact with other repositories, you might need to adjust its permissions.

  • For the current repository: Ensure the contents: read permission is explicitly set in your workflow. While it's often the default, explicit declaration can prevent issues.

    # .github/workflows/your-workflow.yml
    name: My CI Workflow
    on: [push]
    jobs:
      build:
        runs-on: self-hosted
        permissions:
          contents: read # Ensure read access for the current repository
          # Add other permissions as needed, e.g., packages: write, issues: write
        steps:
          - name: Checkout repository
            uses: actions/checkout@v4
            # No 'token' parameter needed if using default GITHUB_TOKEN for current repo
    
  • For accessing other private repositories or elevated permissions: The GITHUB_TOKEN is scoped to the current repository. If you need to clone a different private repository or perform actions requiring broader permissions (e.g., interacting with GitHub's API for releases, packages, etc.), you must use a Personal Access Token (PAT).

    Always store PATs as GitHub Actions secrets, never hardcode them directly in your workflow files.

2. Configure Git Credentials for the Self-Hosted Runner

This step addresses issues when the GITHUB_TOKEN is insufficient, or when using SSH for repository access.

2.1 Using a Personal Access Token (PAT)
  1. Generate a PAT:

    • Go to GitHub.com -> Settings -> Developer settings -> Personal access tokens -> Tokens (classic).
    • Click "Generate new token (classic)".
    • Give it a descriptive name (e.g., "Runner access token").
    • Set an appropriate expiration.
    • Crucially, select the necessary scopes. For cloning private repositories, the repo scope (all sub-scopes) is usually required. Limit scopes to the minimum necessary for security.
    • Copy the generated token immediately.
  2. Add PAT to GitHub Secrets:

    • In your GitHub repository (or organization) -> Settings -> Secrets and variables -> Actions -> Repository secrets (or Organization secrets).
    • Click "New repository secret".
    • Name it (e.g., RUNNER_PAT).
    • Paste the PAT into the "Secret value" field.
  3. Modify Your Workflow to Use the PAT:

    • Pass the secret PAT to the checkout action.
    # .github/workflows/your-workflow.yml
    name: Workflow with PAT
    on: [push]
    jobs:
      build:
        runs-on: self-hosted
        steps:
          - name: Checkout the current repository (using default GITHUB_TOKEN)
            uses: actions/checkout@v4
    
          - name: Checkout another private repository (using PAT)
            uses: actions/checkout@v4
            with:
              repository: your-org/your-other-private-repo # Specify the other private repo
              path: ./other-repo # Path to clone into
              token: ${{ secrets.RUNNER_PAT }} # Use your secret PAT
    

    Personal Access Tokens are powerful. Treat them like passwords. Limit their scope and expiry, and rotate them regularly.

2.2 Using SSH Key Configuration (If using SSH Repository URLs)

If your workflow uses [email protected]:org/repo.git URLs, SSH authentication is required.

  1. Generate SSH Key on Runner:

    • Log in to your CentOS Stream / Rocky Linux runner machine as the root user or a user with sudo privileges.
    • Switch to the actions-runner user's home directory (assuming the runner runs as actions-runner).
    sudo -u actions-runner bash
    cd ~
    
    • Generate a new SSH key pair:
    ssh-keygen -t rsa -b 4096 -C "github-actions-runner-key" -f ~/.ssh/id_rsa_github_actions
    
    • Press Enter to accept the default passphrase (empty) for CI/CD environments, unless you have a robust way to manage passphrases.
    • Set appropriate permissions:
    chmod 600 ~/.ssh/id_rsa_github_actions
    
    • Exit the actions-runner user shell:
    exit
    
  2. Add Public Key to GitHub:

    • Copy the public key:
    sudo cat /home/actions-runner/.ssh/id_rsa_github_actions.pub
    
    • Add this public key to your repository's Deploy Keys (Settings -> Deploy keys -> Add deploy key) or the user's SSH keys on GitHub (Settings -> SSH and GPG keys -> New SSH key). For deploy keys, ensure "Allow write access" if the workflow needs to push changes.
  3. Configure ssh-agent and known_hosts for the Runner:

    • Ensure ssh-agent is running for the actions-runner user. This is often handled by the runner startup script, but explicit configuration helps.
    • The GitHub Actions checkout action often handles ssh-agent and known_hosts if you pass the ssh-key input. However, it's good practice to ensure github.com is in the runner's known_hosts file.
    sudo -u actions-runner bash -c 'ssh-keyscan github.com >> ~/.ssh/known_hosts'
    sudo -u actions-runner chmod 600 /home/actions-runner/.ssh/known_hosts
    
  4. Add Private Key to GitHub Secret:

    • Copy the private key:
    sudo cat /home/actions-runner/.ssh/id_rsa_github_actions
    
    • Add this private key to a GitHub Secret (e.g., RUNNER_SSH_PRIVATE_KEY).
  5. Modify Workflow to Use SSH Key:

    # .github/workflows/your-workflow.yml
    name: Workflow with SSH
    on: [push]
    jobs:
      build:
        runs-on: self-hosted
        steps:
          - name: Checkout repository via SSH
            uses: actions/checkout@v4
            with:
              repository: [email protected]:your-org/your-repo.git # Ensure you use the SSH URL
              ssh-key: ${{ secrets.RUNNER_SSH_PRIVATE_KEY }} # Pass the private key via secret
              # known-hosts: 'github.com ssh-rsa AAAAB3NzaC...' # Optional, can embed known_hosts entry
    

3. Address SELinux Contexts (CentOS/Rocky Specific)

SELinux can prevent the actions-runner process from accessing ~/.ssh or the working directory.

  1. Check for SELinux Denials:

    • After a failed workflow run, check the audit log for AVC messages related to git or actions-runner.
    sudo tail -f /var/log/audit/audit.log | grep AVC
    
    • If you see denials, you might need to create a custom SELinux policy. A quick way to generate a policy is using audit2allow:
    sudo ausearch -c 'git' --raw | audit2allow -M git_policy
    sudo semodule -i git_policy.pp
    
    • Replace 'git' with other relevant processes if the AVC messages indicate a different source (e.g., containerd_t).
  2. Restore File Contexts:

    • Ensure the actions-runner user's home directory and the runner's work directory have the correct SELinux contexts.
    sudo restorecon -Rv /home/actions-runner
    sudo restorecon -Rv /var/lib/actions-runner/_work # Or wherever your _work directory is located
    
  3. Temporarily Disable SELinux (for testing ONLY):

    • If you suspect SELinux, you can temporarily disable it for testing.
    sudo setenforce 0
    
    • Rerun the workflow. If it succeeds, SELinux was the culprit.

    Disabling SELinux severely compromises system security. Do not run with SELinux disabled in production. Re-enable it (sudo setenforce 1) immediately after testing and implement proper SELinux policies.

4. Update Git and Runner Software

Ensure your Git client and the GitHub Actions runner are up-to-date.

  1. Update Git:

    sudo dnf update git -y
    
  2. Update Runner Application:

    • Navigate to your runner installation directory:
    cd /home/actions-runner/actions-runner # Adjust path if different
    
    • Stop the runner service:
    sudo ./svc.sh stop
    
    • Update dependencies and the runner itself:
    ./bin/installdependencies.sh # Installs required packages
    ./bin/vsslib/Update.sh # Updates the runner application
    
    • Start the runner service:
    sudo ./svc.sh start
    

5. Check Network Connectivity and Proxy Settings

Verify that your runner can reach github.com.

  1. Test Connectivity:

    • Ping GitHub:
    ping github.com
    
    • Use curl to simulate a Git connection:
    curl -v https://github.com
    
    • Look for successful HTTP 200 responses or clear error messages.
  2. Configure Proxy Settings (if applicable):

    • If your runner is behind a proxy, you need to configure http_proxy and https_proxy environment variables for the actions-runner service.
    • Edit the systemd service file for your runner (e.g., /etc/systemd/system/actions.runner.your-org.your-runner.service).
    • Add Environment directives under the [Service] section:
    [Service]
    Environment="HTTP_PROXY=http://proxy.example.com:8080"
    Environment="HTTPS_PROXY=http://proxy.example.com:8080"
    Environment="NO_PROXY=localhost,127.0.0.1,.example.com" # Adjust no_proxy for internal networks
    
    • Reload systemd and restart the runner:
    sudo systemctl daemon-reload
    sudo systemctl restart actions.runner.your-org.your-runner.service
    

6. Inspect Runner User Environment

Ensure the actions-runner user has a proper environment for Git operations.

  1. Echo Environment in Workflow:

    • Add a temporary step to your workflow to print environment variables:
    - name: Debug Environment
      run: |
        echo "HOME: $HOME"
        echo "PATH: $PATH"
        echo "whoami: $(whoami)"
        env
    
    • Check the workflow logs for output. Ensure HOME points to /home/actions-runner and that /usr/bin (where git typically resides) is in PATH.
  2. Verify Git Configuration:

    • As the actions-runner user, check global Git configuration:
    sudo -u actions-runner git config --global -l
    
    • Look for any credential.helper or other settings that might interfere.

7. Clear Git Credential Cache (If using a credential helper)

If you're using a Git credential helper (e.g., cache, store), it might be holding stale or incorrect credentials.

  • As the actions-runner user, clear any cached credentials:
    sudo -u actions-runner git credential-cache exit
    # Or to unset the helper entirely for testing:
    # sudo -u actions-runner git config --global --unset credential.helper
    

By systematically working through these troubleshooting steps, you should be able to identify and resolve the root cause of GitHub Actions checkout authentication failures on your CentOS Stream or Rocky Linux self-hosted runner.

👨‍💻

Johnathon Wheeler

Senior Systems Architect & DevOps Engineer • Austin, TX

Connect on LinkedIn

Johnathon has over 16 years of hands-on experience designing, debugging, and scaling Linux web hosting stacks, container clusters, and high-availability database architectures. Every guide on ButItWorkedLocal is independently tested against Debian 12, Ubuntu 24.04/22.04 LTS, Rocky Linux, and Docker environments to guarantee reproducibility in production.

🛡️

Our Production Verification Guarantee

Encountering a bug not covered here or running a non-standard kernel configuration? Our solutions are continually refined against real production incidents. Submit an environment trace for our editorial team to replicate.