انتقل إلى المحتوى
أمين أبوزيد
منشورBEG-047-L02

المصادقة مع GitHub (مفاتيح SSH أو tokens)

  • الدرس 2 من 5
  • 12 دقيقة قراءة
  • مبتدئ
في هذا الدرس 11 موضوعات

هذا الدرس متاح حاليًا باللغة الإنجليزية فقط، ولم تُنشر نسخته العربية بعد.

Lesson Overview

In the last lesson you connected a local repository to a remote and pushed commits. That worked only because the remote knew you were allowed to write to it. Anyone can read a public repository, but only you (and people you invite) may change yours. So before GitHub accepts a push, it asks: who are you?

This lesson covers the two common safe ways to answer. One is a personal access token, a long random string that you use in place of a password. The other is an SSH key pair, two matching files where you give GitHub one and keep the other secret. You will also learn the one rule that matters most: never commit a token or a private key. Think of the shared bookshelf again: authentication is the key to the library door, and you do not tape your key to the shelf.

GitHub changes its settings pages from time to time, so menu names below are the ones documented when this lesson was written. If your screen differs, search GitHub's documentation for the topic named in each step.

Learning Objectives

By the end of this lesson you will be able to:

  • Explain why GitHub does not accept your account password for Git over HTTPS.
  • Describe a personal access token and how to treat it.
  • Generate an SSH key pair with ssh-keygen, and say which file is public and which is private.
  • Add a public key to GitHub, switch a remote to its SSH URL, and test the connection.
  • Choose between the HTTPS-plus-token route and the SSH route for a given situation.
  • Explain what to do if a secret is committed or pushed by accident.

Written Explanation

Authentication is not authorization

Two words are often mixed up. Authentication proves who you are. Authorization decides what that person may do. GitHub first authenticates you (token or key), then checks whether your account may push to that repository. A repository you do not own will reject your push even if you are authenticated perfectly.

Why not a password?

When you clone, fetch, pull, or push over HTTPS to a private repository, Git asks for a username and password. GitHub's documentation states that account passwords are no longer accepted for Git operations; you supply a personal access token (PAT) where the password goes, or use a tool that obtains credentials for you. This protects you: a token can be limited and revoked without changing your account password.

Route 1: HTTPS with a token

A personal access token is a string you create in your GitHub account settings (under Developer settings, then Personal access tokens). GitHub offers two kinds. Fine-grained tokens can be limited to specific repositories and specific permissions; classic tokens use broad scopes and reach every repository you can access. GitHub recommends fine-grained tokens whenever they can do the job, setting an expiry date, and choosing the minimum permissions needed. Treat a token exactly like a password.

You rarely type a token by hand every time. GitHub recommends letting a helper remember credentials: Git Credential Manager (it ships with current Git for Windows) or the GitHub CLI (gh auth login). On the first HTTPS operation that needs authentication, such a tool can open a browser login, and afterwards the credentials are kept in your system's secure store and reused. Where a manual token is needed, you paste it when Git asks for the password. The username is your GitHub username.

Route 2: SSH keys

An SSH key pair is two files made together:

  • The private key stays on your computer. It is your proof of identity. Never share it, never copy it into a project, never commit it.
  • The public key is a lock that matches it. It is safe to share, and you upload it to GitHub.

When you connect, GitHub challenges your computer to prove it holds the private key matching a public key on your account. The private key itself is never sent. That is why uploading the public half is safe.

To create a pair, GitHub documents the Ed25519 type:

bash
ssh-keygen -t ed25519 -C "you@example.com"

The -C value is only a label (a comment) stored in the public key. Run in a scratch folder with a fixed file name and an empty passphrase (for demonstration only), it printed:

text
Generating public/private ed25519 key pair.
Your identification has been saved in ./testkey
Your public key has been saved in ./testkey.pub
The key fingerprint is:
SHA256:2LKnZAZduWPYJw7QkS5Jbjml5zNFtoAVhJ9a5GTANnw you@example.com

With default settings, the files are id_ed25519 (private) and id_ed25519.pub (public) in the .ssh folder of your home directory. The .pub ending is your clue: it is the one you upload. When ssh-keygen asks for a passphrase, set one: it encrypts the private key file so a stolen file is not enough. An SSH agent can hold the unlocked key for the session so you do not retype the passphrase on every push; the setup differs by operating system, so follow GitHub's documented steps for yours.

To register the key, copy the full text of the .pub file and paste it into your account settings under SSH and GPG keys, using New SSH key, a descriptive title such as "Home laptop", and the key type "authentication". Then test:

bash
ssh -T git@github.com

On the very first connection, SSH may ask you to confirm the server's fingerprint; GitHub tells you to compare it with the fingerprints GitHub publishes, and only then type yes. On success the message says you have successfully authenticated but that GitHub does not provide shell access. The command then exits with a non-zero code: that is normal, because GitHub intentionally offers no shell.

Finally, point your remote at the SSH URL (the git@github.com:you/repo.git form):

bash
git remote set-url origin git@github.com:you/bank-accounts.git
git remote -v

Which route should you choose?

HTTPS + token / credential managerSSH key
URL formhttps://github.com/you/repo.gitgit@github.com:you/repo.git
Secret you protectThe tokenThe private key (and its passphrase)
Works behind strict firewallsUsually yesPort 22 may be blocked (alternatives exist)
SetupCredential manager handles itGenerate, upload, test once
Revoke accessDelete the tokenDelete the key on GitHub

Neither is "more correct". Either is fine for this course.

Secrets do not belong in the repository

Tokens, private keys, passwords, and API keys must never be committed. A repository's history is permanent and everyone who clones gets all of it. Deleting the file in a later commit does not remove it from earlier ones. GitHub scans public repositories for known kinds of secrets, and its advice if one leaks is to revoke or rotate the credential immediately: once revoked, it is worthless, and rewriting history becomes much less urgent. In the previous module you wrote a .gitignore that excludes secrets; that is your first line of defense. Keep tokens and keys in your credential manager, ~/.ssh, or an environment variable, outside any project folder.

Examples

Example 1: generate and inspect a key pair (simple)

bash
ssh-keygen -t ed25519 -C "you@example.com"

Press Enter to accept the default location, and choose a passphrase when asked. Now look at the public file:

bash
cat ~/.ssh/id_ed25519.pub

The output is one line starting with ssh-ed25519, then a long string, then your label. Copy it. Never cat and paste the file without .pub: the private one starts with a line -----BEGIN OPENSSH PRIVATE KEY----- and must not leave your machine. (Terminal and folder conventions differ by operating system; Git Bash on Windows accepts these commands.)

Example 2: switch an existing remote to SSH (practical)

Your Bank Accounts repository was pushed over HTTPS last lesson. You uploaded your public key and ssh -T git@github.com greeted you by name. Now switch the remote:

bash
git remote -v
git remote set-url origin git@github.com:you/bank-accounts.git
git remote -v
text
origin	git@github.com:you/bank-accounts.git (fetch)
origin	git@github.com:you/bank-accounts.git (push)

The output shows the address Git will use from now on. History, branches, and commits are untouched: only the address changed. A git push now authenticates with your key, and it should not ask for your account password. If your key has a passphrase and no agent holds it, Git may ask for the passphrase; that is the key's own protection, not GitHub's.

Example 3: a token almost gets committed (realistic)

You write a small Java tool that calls an API and put the token in a file config.properties next to the code. You run git status:

text
Untracked files:
  config.properties

Stop before git add .. The safe sequence is:

  1. Add config.properties to .gitignore and commit the .gitignore.
  2. Keep the real file locally, and commit a harmless config.example.properties with a placeholder like token=put-your-token-here.
  3. Read git status and git diff --staged before every commit.

Now the unlucky version: you did commit and push the token. Order matters: first, in GitHub's token settings, delete the token (revoke it). Second, create a replacement and store it outside the repository. Third, remove the file from future commits. Revoking comes first because anything pushed to a public repository must be treated as already seen.

Backend Insight

Backend code touches secrets constantly: database passwords, API keys for payment or email services, signing keys. The habit from this lesson, secrets live outside the repository, is the same habit professionals use: configuration read from the environment or a secret store at run time, with the repository holding only placeholders. Many teams also give automated systems (such as a build server) their own narrow credentials rather than a person's, and GitHub's own guidance prefers minimum permissions and expiring tokens for the same reason: if a credential leaks, the damage should be small and short-lived.

You will also meet authentication as an error: Permission denied (publickey) means GitHub could not match you to an account. Read it as an identity problem, not a Git problem.

Common Mistakes

Mistake 1: Uploading the private key

  • Incorrect: pasting the contents of id_ed25519 into GitHub.
  • Correct: paste the contents of id_ed25519.pub. GitHub is designed to receive only the public half.

Mistake 2: Using the account password over HTTPS

When Git asks for a password and your account password fails, that is expected: use a token or a credential manager.

Mistake 3: Putting a token in the code, README, or a commit message

Anything in the repository is in the history forever. Keep secrets outside the project and revoke any that leaked.

Mistake 4: Leaving the remote on HTTPS after setting up SSH

You uploaded a key but git remote -v still shows an https:// address, so Git keeps asking for a token. Switch with git remote set-url.

Exercises

Never paste real tokens or private keys into chat tools, screenshots, or exercise answers.

Level A: Foundation

A1. Say whether each belongs on GitHub, or must stay on your machine: private key file, public key file, personal access token, key fingerprint line.

أظهر الحل A1

A1. Public key file: may be uploaded. Private key file: stays on your machine. Personal access token: stays secret (used at login, stored by a credential manager, never in a repo). Fingerprint line: a short summary of the public key, safe to share and used to verify keys.

A2. Why does GitHub's HTTPS Git access not accept your account password?

أظهر الحل A2

A2. GitHub removed password-based authentication for Git because tokens (and keys) can be limited in what they can do, can expire, and can be revoked without changing your account password.

A3. Which URL is the SSH one: https://github.com/you/app.git or git@github.com:you/app.git?

أظهر الحل A3

A3. git@github.com:you/app.git is the SSH URL.

Level B: Application

B1. Write the command that creates an Ed25519 key with the label dev@laptop. Then name the two files it creates (default names) and which one you upload.

أظهر الحل B1

B1. ssh-keygen -t ed25519 -C "dev@laptop". It creates id_ed25519 (private) and id_ed25519.pub (public) in your .ssh folder if you accept the defaults. You upload the .pub file.

B2. Your remote uses HTTPS but you now want SSH. Write the commands to change it and verify the change.

أظهر الحل B2

B2.

bash
git remote set-url origin git@github.com:you/app.git
git remote -v

-v should now show git@github.com: addresses for fetch and push.

B3. git push prints Permission denied (publickey). List three things to check, in an order that goes from quick to slow.

أظهر الحل B3

B3. (1) Run git remote -v: is the URL SSH and the right repository? (2) Did you add the public key to the GitHub account that owns or can write to the repository? (3) Run ssh -T git@github.com to see whether authentication works at all; if not, check that the key is loaded in the agent and that you uploaded the matching .pub. If everything above is fine, check that your account has write access to the repository.

Level C: Challenge

C1. A friend committed .env containing a database password and pushed it to a public repository. Write the steps in the right order, with one sentence on why that order. Include what to do about future commits.

أظهر الحل C1

C1. (1) Revoke or change the password in the database (and any other secrets in the file) right away. (2) Create a new password, stored outside the repository. (3) Add .env to .gitignore and stop tracking it (git rm --cached .env, then commit). (4) Optionally clean the history later. The order is important because the secret was public the moment it was pushed: only changing it makes it harmless, and history cleanup is slow and does not undo copies others may have.

C2. Compare tokens and SSH keys for three situations: (a) a laptop at a school with strict network rules, (b) a personal laptop you use daily, (c) a script that only needs to read one repository. Pick one for each and justify it briefly.

أظهر الحل C2

C2. (a) HTTPS with a credential manager or token is a safer bet if the network might block SSH's usual port, since HTTPS is more likely to pass through firewalls. (b) SSH is a good choice: set up once, nothing to type afterward. HTTPS with a credential manager is also fine. (c) A fine-grained token limited to that one repository with read-only access and an expiry date fits the minimum-permission advice.

Mini Challenge

Set up authentication for your own machine, whichever route you prefer, and prove it works.

  1. SSH route: generate a key with a passphrase, upload the .pub file, run ssh -T git@github.com, and switch your remote to the SSH URL. Token route: install or enable a credential manager, or create a fine-grained token limited to one repository, with an expiry date.
  2. Run git push to a repository you own and confirm it does not ask for your account password.
  3. Write two sentences in your notes: where your private key or token lives, and what you would do first if it leaked.

Check your work: nothing secret is inside any project folder, git remote -v matches your chosen route, and git push succeeds.

Summary & Next Lesson

Key takeaways

  • Authentication proves who you are; authorization decides what you may do.
  • GitHub does not accept your account password for Git over HTTPS. Use a personal access token or a credential manager.
  • An SSH key pair has a private half that never leaves your machine and a public half (.pub) that you upload to GitHub.
  • ssh -T git@github.com tests the SSH setup, and git remote set-url switches a remote between HTTPS and SSH.
  • Never commit tokens or keys. If one leaks, revoke it first.

Next lesson

Now that you can push safely, you will use that power in a team-friendly way. The next lesson, "Pull requests and reviews", shows how to propose a change on a branch, get it reviewed, and merge it, instead of pushing straight to main.

Self-check

  1. Which half of an SSH key do you upload to GitHub?
  2. What should you use in place of a password when Git asks for one over HTTPS?
  3. What command tests an SSH connection to GitHub?
  4. You pushed a token to a public repository. What is the first action?
  5. Where should secrets be stored?
أظهر الإجابات
  1. The public key (the .pub file).
  2. A personal access token, or a credential manager that supplies credentials for you.
  3. ssh -T git@github.com.
  4. Revoke the token, because it must be treated as already exposed.
  5. Outside the repository: in a credential manager, the .ssh folder, or environment or secret configuration, with only placeholders committed.

References

التطبيق

طبّق هذا الدرس بمختبر الوحدة وتمارينها واختبارها.

المختبر والتمارين الاختبار

تعليم الدرس كمكتمل اختياري ويمكنك التراجع عنه في أي وقت. يبقى تقدمك محفوظًا في هذا المتصفح.

اكتب للبحث في المستويات والمراحل والوحدات والدروس.