Configure ssh-known-hosts for Private GitHub Enterprise Instances with actions/checkout

To securely connect actions/checkout to a private GitHub Enterprise Server (GHES) instance over SSH, generate your host fingerprints using ssh-keyscan, store them in a GitHub secret, and supply them via the ssh-known-hosts input while setting github-server-url to your GHES endpoint.

The actions/checkout action supports SSH authentication to private GitHub Enterprise Server instances through dedicated inputs that customize SSH security policies. When you provide custom host keys through the ssh-known-hosts parameter, the action automatically constructs a temporary known-hosts file and configures Git to use it for all subsequent operations.

How the ssh-known-hosts Input Works

When you supply the ssh-known-hosts input, the action implements a multi-step authentication flow defined in the source code:

  1. Collects fingerprints – The action accepts a multiline string containing SSH host key entries, typically generated with ssh-keyscan.

  2. Creates a temporary known-hosts file – In src/git-auth-helper.ts (lines 297-304), the action creates a temporary file in the runner's $RUNNER_TEMP directory and stores the path in the sshKnownHostsPath variable.

  3. Writes host entries – The file contains the default github.com host key plus your user-provided GHES entries written via fs.promises.writeFile.

  4. Persists state – The temporary file path is saved in the action state via state-helper.ts (lines 45-46) to ensure proper cleanup.

  5. Configures SSH command – The action builds a custom SSH command in src/git-auth-helper.ts (lines 306-313) that forces Git to use the temporary file via the UserKnownHostsFile option. By default, this command includes StrictHostKeyChecking=yes and CheckHostIP=no.

  6. Applies Git configuration – The command is stored in sshCommand and applied globally using git config core.sshCommand, ensuring all fetch and clone operations use your specified host keys.

Configuring Your GitHub Enterprise Workflow

Generate Host Fingerprints

Before configuring the workflow, generate the SSH host key fingerprints for your GHES instance:

ssh-keyscan -t rsa,ecdsa,ed25519 my-ghes.example.com

Store the output in a GitHub secret (e.g., GHES_KNOWN_HOSTS) through the repository settings or CLI:

gh secret set GHES_KNOWN_HOSTS --repo=my-org/my-repo < known_hosts.txt

Configure Workflow Inputs

Set the following inputs in your workflow step:

  • github-server-url – Point to your GHES instance (declared in action.yml lines 98-100)
  • ssh-key – Your deploy key stored as a secret
  • ssh-known-hosts – The secret containing your generated fingerprints (declared in action.yml lines 37-46)
  • ssh-strict – Optional boolean to disable strict host checking

Source Code Implementation Details

The SSH authentication flow spans several key files in the repository:

  • action.yml – Defines the ssh-known-hosts, ssh-strict, and github-server-url inputs with their types and descriptions.

  • src/input-helper.ts – Reads the ssh-known-hosts value using core.getInput('ssh-known-hosts') and passes it to the authentication helper.

  • src/git-auth-helper.ts – Contains the configureSsh() method that creates the temporary known-hosts file and constructs the SSH command with the UserKnownHostsFile parameter.

  • src/state-helper.ts – Persists the sshKnownHostsPath to the action state, allowing the post-job cleanup to remove sensitive temporary files.

  • src/git-command-manager.ts – Executes Git commands using the overridden SSH configuration set by the authentication helper.

Managing Strict Host Key Checking

By default, the action enforces strict host key checking when ssh-known-hosts is provided. When ssh-strict remains true (the default), the generated SSH command includes StrictHostKeyChecking=yes.

If your GHES instance uses self-signed certificates or frequently changing host keys, set ssh-strict: false. This omits the strict checking options from the SSH command while still utilizing your custom known-hosts file to prevent man-in-the-middle attacks on the initial connection.

Complete Workflow Example


# .github/workflows/checkout-ghes.yml

name: Checkout private GHES repo

on:
  push:

jobs:
  checkout:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          # Point to the GHES instance

          github-server-url: https://my-ghes.example.com
          # Use an SSH deploy key stored in a secret

          ssh-key: ${{ secrets.GHES_SSH_KEY }}
          # Provide the known-hosts entries for the GHES host

          ssh-known-hosts: ${{ secrets.GHES_KNOWN_HOSTS }}
          # Optional: disable strict checking for self-signed certs

          # ssh-strict: false

Summary

  • Store your GHES host fingerprints in a secret using ssh-keyscan output before configuring the workflow.
  • The ssh-known-hosts input creates a temporary file at runtime in $RUNNER_TEMP via src/git-auth-helper.ts to avoid modifying the runner's global SSH configuration.
  • Set github-server-url to ensure the action targets your private GHES instance rather than GitHub.com.
  • The action constructs a custom SSH command with UserKnownHostsFile pointing to the temporary file, applied through git config core.sshCommand.
  • Use ssh-strict: false only when necessary for self-signed certificates, as this removes StrictHostKeyChecking=yes from the SSH options.

Frequently Asked Questions

How do I generate the SSH known hosts entry for my GHES server?

Run ssh-keyscan -t rsa,ecdsa,ed25519 <your-ghes-host> from a trusted network location to capture the current host keys. Store the complete output, including the host algorithm and base64-encoded key, as a repository or organization secret, then reference it in the ssh-known-hosts input.

What happens if I don't provide ssh-known-hosts for my GHES instance?

Without the ssh-known-hosts input, the SSH client may prompt to accept the host key during the workflow run, causing the job to hang indefinitely or fail with a host key verification error. You must provide the expected host keys to enable non-interactive SSH authentication to private GHES instances.

Can I use ssh-known-hosts with GitHub.com instead of GHES?

Yes, the ssh-known-hosts input works with any SSH Git remote. The action automatically includes the default github.com host key in the temporary known-hosts file, but you can provide additional entries for mirrors, proxies, or other SSH hosts accessed during checkout.

Where does the action store the temporary known-hosts file?

The action creates the file in the runner's temporary directory ($RUNNER_TEMP) using a path generated at runtime and stored in the action state via state-helper.ts. The file is automatically cleaned up after the job completes, ensuring sensitive host key configurations do not persist on the runner between workflows.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →