Thuta Learning
AdvancedDevOps & Toolsintermediate

GitHub Security Basics

What you'll walk away with

  • Explain the core ideas behind GitHub Security Basics
  • Read the diagram and trace how state or data flows through the Git/GitHub workflow
  • Decide how this applies to your own project or team

Build the mental model

A GitHub account is a more attractive target than most, because it often controls the source code, deployment pipelines, and secrets of everything a person or company has built. Losing control of it can mean a lot more than losing personal data.

Two-factor authentication matters more here than on an average account for exactly that reason: a stolen password alone should never be enough to push code, merge a pull request, or read a private repository. Enabling 2FA everywhere closes the single most common account-takeover path.

SSH keys replace password authentication with a cryptographic key pair: a private key that never leaves your machine, and a public key you register with GitHub. When you push or pull over SSH, GitHub verifies you hold the matching private key without a password ever crossing the network.

Personal access tokens serve a similar purpose for HTTPS-based Git operations and the API, replacing your password with a scoped, expiring credential. A good token grants only the specific permissions a task needs, expires automatically, and can be revoked instantly without touching your password or any other token.

Never share a private key or an unexpired token

Treat both exactly like a password: never commit them to a repository, paste them in chat, or send them by email. If one is ever exposed, revoke or regenerate it immediately — assume it is already compromised.

text
SSH KEY PAIR: LOCAL PRIVATE KEY, REMOTE PUBLIC KEY
--------------------------------------------------
YOUR COMPUTER                        GITHUB.COM

id_ed25519       (private key)
   stays here, never shared
                                      id_ed25519.pub
id_ed25519.pub  ----- upload ------->   (public key)
   (safe to share)                    stored on your account

git push  ---- SSH handshake proves you hold ---->  accepted
              the matching private key

Connect it to a real scenario

The command shown here, ssh-keygen -t ed25519 -C "you@example.com", was actually run in a throwaway directory to produce the real output below; the generated key pair was deleted immediately afterward and was never registered anywhere.

It generates a modern Ed25519 key pair, a private key file and a matching .pub public key file, and prints a fingerprint plus a randomart image derived from the key. Every real run produces a different fingerprint and randomart, since the key itself is freshly random each time — don't expect your own output to match this example exactly, only its shape.

Register the public key

Copy the .pub file's contents, paste it into Settings > SSH and GPG keys > New SSH key on GitHub's website; GitHub stores only the public half.

Create a personal access token

Settings > Developer settings, choose a token type, select an expiration date and the minimum scopes the task needs, then generate it.

Store it once

GitHub shows the token exactly once; treat it like a password and store it in a secret manager, not in a text file or a script.

Never share a private key or an unexpired token

Treat both exactly like a password: never commit them to a repository, paste them in chat, or send them by email. If one is ever exposed, revoke or regenerate it immediately — assume it is already compromised.

GitHub Account Security Checklist

Try the working example

bash
# Run in a throwaway directory only, never your real ~/.ssh
mkdir -p /tmp/ssh-demo && cd /tmp/ssh-demo
ssh-keygen -t ed25519 -C "you@example.com" -f ./id_ed25519 -N ""

ls -la
cat id_ed25519.pub

# cleanup -- this demo key is never registered anywhere
rm -f id_ed25519 id_ed25519.pub
You should see
ssh-keygen printed:

Generating public/private ed25519 key pair.
Your identification has been saved in ./id_ed25519
Your public key has been saved in ./id_ed25519.pub
The key fingerprint is:
SHA256:1pxNKgx8T7W/2wwRxANs0iSaWsp2srYYIPyhR7GA1uM you@example.com
The key's randomart image is:
+--[ED25519 256]--+
|          .++o.  |
|. .  .   o.o+oo  |
|.o +  o = .oo .. |
|o o +. B = = . . |
|...E  * S * . o  |
| .+... = .     o |
| . o. o       o  |
|  .  + .       = |
|    . .       . o|
+----[SHA256]-----+

The .pub file's contents:

ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGuo8yCutlQdHAWl6oARWtZ+xYlJ2jxBhpXpgAE0Ekv0 you@example.com

The fingerprint, randomart, and key string above are real output from one actual run and will be different every time this command runs, since the key is freshly random. Everything past this point -- pasting the public key into GitHub, creating a token -- happens on GitHub's website and has no terminal output to capture.

5-minute try-it

Generate a real SSH key pair in a throwaway directory with ssh-keygen -t ed25519 -C "your-email@example.com" -f ./test_key, inspect both files, then delete them. Separately, on your actual GitHub account, enable 2FA if it isn't already on, and create one personal access token scoped to only what a single task needs with a 7-day expiration, then revoke it once you're done.

One important caution

Pasting a private key or a raw token into a chat message, ticket, or committed file — even in a private repo — should be treated as an immediate compromise requiring revocation.

Creating a single token with broad, permanent access out of convenience instead of a short-lived, narrowly scoped one for each task defeats the entire point of tokens over passwords.

GitHub Docs - Managing your personal access tokensGit & GitHub

Easy traps

  • Pasting a private key or a raw token into a chat message, ticket, or committed file — even in a private repo — should be treated as an immediate compromise requiring revocation.
  • Creating a single token with broad, permanent access out of convenience instead of a short-lived, narrowly scoped one for each task defeats the entire point of tokens over passwords.
  • Always run `git status` before any destructive or history-rewriting command, to know exactly what state you're in.

Exercise

Generate a real SSH key pair in a throwaway directory with ssh-keygen -t ed25519 -C "your-email@example.com" -f ./test_key, inspect both files, then delete them. Separately, on your actual GitHub account, enable 2FA if it isn't already on, and create one personal access token scoped to only what a single task needs with a 7-day expiration, then revoke it once you're done.

You'll know it worked when: ssh-keygen printed: Generating public/private ed25519 key pair. Your identification has been saved in ./id_ed25519 Your public key has been saved in ./id_ed25519.pub The key fingerprint is: SHA256:1pxNKgx8T7W/2wwRxANs0iSaWsp2srYYIPyhR7GA1uM you@example.com The key's randomart image is: +--[ED25519 256]--+ | .++o. | |. . . o.o+oo | |.o + o = .oo .. | |o o +. B = = . . | |...E * S * . o | | .+... = . o | | . o. o o | | . + . = | | . . . o| +----[SHA256]-----+ The .pub file's contents: ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGuo8yCutlQdHAWl6oARWtZ+xYlJ2jxBhpXpgAE0Ekv0 you@example.com The fingerprint, randomart, and key string above are real output from one actual run and will be different every time this command runs, since the key is freshly random. Everything past this point -- pasting the public key into GitHub, creating a token -- happens on GitHub's website and has no terminal output to capture.

GitHub Security Basics | Thuta Learning