Skip to content

GitHub Authentication

Csaba Polyak edited this page Sep 28, 2026 · 1 revision

GitHub Authentication

GitHub Mirror Backup uses two separate authentication mechanisms:

Purpose | Authentication -- | -- Repository discovery | GitHub Personal Access Token Git repository transfer | SSH key

This separation is intentional. The Personal Access Token is used only for the GitHub API, while Git itself communicates with GitHub through SSH.

1. Create a GitHub Personal Access Token

The script needs an access token to query the repositories available to the authenticated account.

A GitHub Classic Personal Access Token can be used for this purpose.

The token must be able to read the repositories you want to back up.

For a classic token, the repo scope provides access to private repositories.

Never put the token directly into the backup script.

Store it in a separate file instead.

2. Store the token

Create the configuration directory:

mkdir -p ~/.config/github
chmod 700 ~/.config/github

Create the token file:

nano ~/.config/github/token

Put the token into the file as a single line.

Then restrict the file permissions:

chmod 600 ~/.config/github/token

The resulting layout should look like:

~/.config/github/
└── token

The backup script reads this file automatically.

3. Configure SSH

Git operations use SSH rather than HTTPS.

The machine running the backup therefore needs an SSH key registered with GitHub.

Check whether a key already exists:

ls -la ~/.ssh/

Common key types include:

id_ed25519
id_ed25519.pub

If necessary, create a new Ed25519 key:

ssh-keygen -t ed25519 -C "github-backup"

Do not put the private key into the GitHub repository.

4. Add the public key to GitHub

Display the public key:

cat ~/.ssh/id_ed25519.pub

Copy the entire line and add it to the SSH keys section of your GitHub account.

The public key can safely be registered with GitHub.

The private key must remain on the backup machine.

5. Test SSH authentication

Run:

ssh -T git@github.com

A successful authentication produces a message similar to:

Hi USERNAME! You've successfully authenticated, but GitHub does not provide shell access.

This is expected.

GitHub does not provide an interactive shell through this SSH endpoint. The message confirms that authentication itself succeeded.

6. Test the API token

The backup script performs the API authentication automatically.

You can manually test the token with:

curl -fsSL \
  -H "Authorization: Bearer $(cat ~/.config/github/token)" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/user

A successful response contains the authenticated GitHub account information.

Do not paste the response containing private account information into public issue trackers.

7. Why are both required?

The API and Git transport solve different problems.

API

The API answers:

"Which repositories can this account access?"

The script uses it to discover repositories, including private repositories and repositories accessible through organizations or collaboration.

SSH

SSH answers:

"How do I download the actual Git repository?"

The script uses each repository's SSH URL:

git@github.com:owner/repository.git

This means the Personal Access Token is not used as a Git password.

8. Token security

The token is deliberately not passed as a command-line argument.

Instead, the script supplies the authorization header to curl through standard input.

This avoids exposing the token in the process command line.

The token is also not written into Git remote URLs.

For example, the script does not create remotes like:

https://TOKEN@github.com/owner/repository.git

Instead, the remote remains an SSH URL:

git@github.com:owner/repository.git

9. Recommended permissions

The token file should only be readable by its owner:

chmod 600 ~/.config/github/token

The SSH private key should have similarly restrictive permissions:

chmod 600 ~/.ssh/id_ed25519

The public key can remain readable:

chmod 644 ~/.ssh/id_ed25519.pub

10. Authentication troubleshooting

SSH authentication fails

Run:

ssh -vT git@github.com

Check that:

  • the correct private key exists

  • the corresponding public key is registered with GitHub

  • the SSH agent is available if the key requires one

  • network access to GitHub SSH is available

API authentication fails

Check that the token file exists:

ls -l ~/.config/github/token

Check that it contains exactly one token:

wc -l ~/.config/github/token

Then test the API request again.

SSH account and API account do not match

The script checks both identities.

For example:

API account    csiber
SSH account    another-user

This is reported as a mismatch.

This matters because the API may discover repositories belonging to one account while the SSH key belongs to another account with different repository permissions.

Authentication model

The complete authentication flow is therefore:

             GitHub
                │
       ┌────────┴─────────┐
       │                  │
   REST API              SSH
       │                  │
   PAT token           SSH key
       │                  │
       ▼                  ▼
 Repository          Git repository
 discovery            transfer
       │                  │
       └────────┬─────────┘
                ▼
          Local mirror

Keeping these two authentication paths separate makes the backup process easier to understand and avoids putting long-lived API credentials into Git configuration.