Module 8: walk through GitHub PAT setup, link SSH as optional (#106)
CI / check (pull_request) Successful in 7s
CI / check (pull_request) Successful in 7s
Add a concrete "Set up GitHub authentication" subsection to the Module 8 lab, before Part A. It walks the PAT/HTTPS path step by step on GitHub as the worked example (fine-grained token, Contents: Read and write scope, copy-once, paste-at-password-prompt), links GitHub's official SSH docs as the optional alternative, and gives a pros/cons table so the learner can choose deliberately. Extend the Verify-before-publish checklist with the GitHub-specific menu path and scope labels, since those drift. Closes #106 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014strzwARMpFSrdSV3wi4Ns
This commit is contained in:
@@ -323,6 +323,88 @@ WSL, or Git Bash on Windows. Continues the `tasks-app` repo from Module 2.
|
||||
*direct the agent* to do the git work (add the remote, push, clone, fetch, pull) and you verify
|
||||
each result yourself. You don't type the git commands by hand.
|
||||
|
||||
### Set up GitHub authentication (do this first)
|
||||
|
||||
This is the one part you do by hand in the web UI, and it's failure mode #1 above: the single most
|
||||
common first-push wall. Set it up *before* Part A so the push just works. You have two paths; do
|
||||
**one**. This lab walks the **PAT / HTTPS** path step by step on GitHub as the worked example,
|
||||
because it's all in the browser and needs no command-line setup. SSH is the optional alternative,
|
||||
linked below.
|
||||
|
||||
> **Other host?** These are GitHub's exact menu paths as the worked example. On GitLab, Bitbucket,
|
||||
> Codeberg, or your own Forgejo/Gitea the *shape* is identical (see the "Getting a credential" callout
|
||||
> in the lesson) but the menu names drift; find your host's "access tokens" or "SSH keys" settings.
|
||||
|
||||
**Path 1: Personal access token (PAT) over HTTPS.** Generate a token in GitHub's web UI, then paste
|
||||
it once when Git asks for a password.
|
||||
|
||||
1. On GitHub, go to your avatar (top right) → **Settings** → **Developer settings** (bottom of the
|
||||
left sidebar) → **Personal access tokens**. GitHub offers two token types:
|
||||
|
||||
- **Fine-grained tokens** (recommended): scoped to a single repository, with explicit permissions.
|
||||
This lab uses fine-grained.
|
||||
- **Tokens (classic)**: older, broader; access is controlled by a coarse `repo` scope that grants
|
||||
all your repos at once.
|
||||
|
||||
Pick **Fine-grained tokens** → **Generate new token**.
|
||||
|
||||
2. Fill in the token:
|
||||
|
||||
- **Token name:** anything memorable, e.g. `tasks-app-push`.
|
||||
- **Expiration:** pick a real expiry (30 to 90 days is fine for the lab). Tokens expire by design;
|
||||
that's a rotation cost you accept for the convenience.
|
||||
- **Repository access:** choose **Only select repositories** and select your `tasks-app` repo. If
|
||||
you haven't created the empty remote yet (Part A step 1), come back and select it after, or
|
||||
create the repo first and then make the token. The token only needs to *reach* a repo that
|
||||
exists.
|
||||
- **Permissions → Repository permissions → Contents:** set it to **Read and write**. This is the
|
||||
write scope, and it is *the* gotcha: a token without it authenticates fine and then `403`s on
|
||||
push (failure mode #1's scope trap). GitHub auto-adds **Metadata: Read** when you do this; leave
|
||||
it.
|
||||
|
||||
3. Click **Generate token** and **copy the value immediately.** GitHub shows it exactly once. If you
|
||||
lose it, you generate a new one rather than recover the old.
|
||||
|
||||
4. At the first push (Part A step 2), Git prompts for a **username** and **password**:
|
||||
|
||||
- **Username:** your GitHub username.
|
||||
- **Password:** paste the **token** (not your GitHub account password; password auth over HTTPS
|
||||
was removed years ago). Most terminals show *nothing* while you paste a secret; that's normal,
|
||||
not a hang. Press Enter.
|
||||
|
||||
A **credential helper** caches it after the first success (`git config --global credential.helper`,
|
||||
set to `osxkeychain` on macOS, `manager` on Windows, or `store`/`cache` on Linux), so you paste the
|
||||
token *once*, not on every push.
|
||||
|
||||
> **Verify-before-publish:** GitHub's menu wording, token-type names, and the **Contents: Read and
|
||||
> write** permission label drift. Re-confirm the path **Settings → Developer settings → Personal
|
||||
> access tokens → Fine-grained tokens** and the Contents scope before relying on these exact names.
|
||||
|
||||
**Path 2: SSH key (optional alternative).** A key you add to your account skips passwords entirely.
|
||||
It's more upfront setup (generate a keypair, load the ssh-agent, paste the *public* key into GitHub),
|
||||
but then there's no token to scope, expire, or cache. Follow GitHub's official docs, in order:
|
||||
|
||||
- [Generating a new SSH key and adding it to the ssh-agent](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)
|
||||
- [Adding a new SSH key to your GitHub account](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)
|
||||
- [Testing your SSH connection](https://docs.github.com/en/authentication/connecting-to-github-with-ssh/testing-your-ssh-connection)
|
||||
|
||||
If you go SSH, use the **SSH** URL (`git@github.com:…`) when you create the remote in Part A, not the
|
||||
HTTPS one.
|
||||
|
||||
**Which should you pick?**
|
||||
|
||||
| | **PAT / HTTPS** | **SSH key** |
|
||||
|---|---|---|
|
||||
| **Setup** | Fast, all in the web UI; nothing to install | More upfront: keygen, ssh-agent, add the public key |
|
||||
| **After setup** | Credential helper caches the token; otherwise re-paste | No prompts ever; nothing to cache |
|
||||
| **Network** | Port 443; sails through corporate proxies/firewalls | Port 22; sometimes blocked on locked-down networks |
|
||||
| **Maintenance** | Expires; needs rotation; the write-scope `403` trap; shown once | No expiry by default; no scope to misconfigure |
|
||||
| **Risk to manage** | A leaked token until it expires/is revoked | A private key + passphrase on your disk |
|
||||
|
||||
Short version: **PAT** is the faster start and the friendlier path behind a corporate firewall;
|
||||
**SSH** is the lower-friction *long-term* setup once you're past the initial keygen. Either one
|
||||
satisfies the lab. If you're unsure, do the PAT.
|
||||
|
||||
### Part A: Create the empty remote and push
|
||||
|
||||
1. On your host's web UI, create a **new, empty** repository named `tasks-app`. Do **not** add a
|
||||
@@ -514,4 +596,9 @@ tables, and update the "as of" date when you do.
|
||||
- [ ] **Credential/token UI**: the "Getting a credential" callout names menu paths and the
|
||||
write-scope label (`repo` / "read and write") generically; confirm the current wording and
|
||||
scope name on the default-example host before publishing.
|
||||
- [ ] **GitHub PAT walkthrough** (lab "Set up GitHub authentication"): confirm the menu path
|
||||
**Settings → Developer settings → Personal access tokens → Fine-grained tokens**, the two token
|
||||
types (**fine-grained** vs **classic**/`repo`), and that the write scope is **Repository
|
||||
permissions → Contents: Read and write** (with **Metadata: Read** auto-added). These are
|
||||
volatile GitHub UI labels; also re-confirm the three linked SSH docs URLs still resolve.
|
||||
- [ ] Update the comparison's **"as of" date** to the build date.
|
||||
|
||||
Reference in New Issue
Block a user