Chapter 02Lesson 03~105 minutes

Account Security, Two-Factor Authentication, SSH Keys, Tokens, and Credential Hygiene: Configuration, Design Choices, and Tradeoffs

Choose SSH, HTTPS, fine-grained PATs, classic PATs, GitHub Apps, and credential storage patterns by threat model, scope, lifecycle, platform policy, and operational cost—not by habit.

Least privilegePATsGitHub AppsCredential storage

Learning objectives

  • Choose SSH or HTTPS for Git transport based on identity management, network compatibility, credential storage, rotation, and team policy.
  • Choose among fine-grained PATs, classic PATs, GitHub App installation tokens, and GITHUB_TOKEN based on caller identity and resource scope.
  • Design expiration and rotation policy that minimizes blast radius without creating unmanaged outages.
  • Select credential storage that avoids plaintext/source/history exposure and remains operable across Windows, Linux, and macOS.
  • Recognize SSO/organization policy as an additional authorization layer, not a reason to broaden tokens blindly.
  • Apply a decision framework to developer, CI, integration, and enterprise scenarios while keeping the mandatory path free-compatible.
Availability: SSH keys, HTTPS/GCM, GitHub CLI, and personal fine-grained PAT practice are available on the free learning path. Enterprise SSO policy and some organization governance controls are optional design exercises unless your account already has access.

1. Design principle: minimize reusable authority

Credential design is a blast-radius problem. A credential has a principal, a set of reachable resources, permitted operations, a lifetime, and a storage location. The safest useful design minimizes all five without making the system impossible to operate.

For interactive developer access, the credential should be tied to a specific device or managed credential store. For automation, the stronger pattern is a dedicated machine identity with short-lived credentials—such as a GitHub App installation token—rather than a long-lived PAT copied from a powerful engineer’s account.

2. SSH versus HTTPS for Git transport

Factor SSH HTTPS
Credential Private SSH key; public key registered on GitHub. Credential manager/OAuth or PAT where necessary.
Secret exposure surface Private key file/agent; can be hardware-backed. Credential store/token cache; avoid URLs and shell arguments.
Network compatibility Port 22 may be blocked; GitHub documents alternatives such as SSH over HTTPS in constrained networks. Usually works through standard HTTPS-friendly networks/proxies.
Multiple accounts Explicit SSH host aliases/identity files can separate accounts, but misconfiguration can resolve the wrong identity. Credential managers/gh can manage account state; host-level protocol settings must be understood.
Rotation Register new key, verify, then remove old key. Refresh/revoke OAuth/PAT/GCM credential according to the helper/provider.
Human experience Excellent for key-based developer workflows. Excellent when browser SSO/2FA and OS credential stores are central to policy.

Neither transport is “more authorized.” Both ultimately reach the same GitHub repository service and then face repository/ref policy. Choose the transport that fits your organization’s endpoint management, network controls, credential recovery, and developer experience.

3. HTTPS storage: delegate secret handling to a credential manager

GitHub recommends GitHub CLI or Git Credential Manager for HTTPS credentials. On supported platforms, GCM integrates with the operating system’s secure credential store and browser authentication. This is preferable to teaching each developer to generate a PAT and paste it whenever Git prompts.

If gh auth login cannot find a system credential store, current CLI documentation says it can fall back to a plain-text file. That does not automatically make the setup unusable, but it changes the threat model: file permissions, disk protection, shared-user machines, backups, and malware exposure become more important. Production workstation standards should define the expected credential backend.

4. Fine-grained PAT versus classic PAT

Fine-grained PATs are the default design candidate because you can narrow the resource owner, repositories, and permissions. However, GitHub’s current documentation lists scenarios that still require classic PAT behavior. These gaps are product policy and can change, so endpoint documentation—not a memorized 2026 list—must decide.

Decision question Fine-grained PAT Classic PAT
Can I select only the needed repositories? Yes, within the selected resource owner. Generally broad scope follows the user’s accessible repositories.
Can I choose endpoint-specific permissions? Yes; REST docs publish required fine-grained permissions. Uses broader OAuth-style scopes.
Does every legacy/API scenario work? No; verify current limitations. Some scenarios still require classic tokens.
Should I use it for durable org automation? Usually not the best endpoint architecture. No; broad user-bound tokens are especially weak for durable integration. Prefer a GitHub App.
What if organization policy blocks it? Use the approved credential/integration path; do not bypass policy. Same: policy is an authorization boundary, not an invitation to find a broader token.
Never “solve” a permission error by switching immediately to a classic PAT with repo scope. First identify the endpoint’s documented permission and the owner/repository/policy boundary.

5. GitHub App installation tokens for automation

A GitHub App has its own registered permissions. An installation grants that App access to selected accounts/repositories, and an installation access token represents the installed App for a short period. Current GitHub documentation states installation access tokens expire after one hour.

This design is operationally useful because the automation identity is not a human, the repository set is explicit, permissions are configured centrally, tokens are short-lived, and app activity is attributable. The App’s private key remains a high-value credential used to mint installation tokens and therefore requires its own secret-storage/rotation controls.

Boundary: this chapter does not ask you to create a GitHub App. Chapter 27 covers Apps and integrations. Here you only need to recognize when the architecture should be an App rather than a PAT.

6. GITHUB_TOKEN: prefer the built-in workflow identity when it is enough

For GitHub Actions, GitHub automatically creates a GITHUB_TOKEN for each job. It is an installation access token for the GitHub App installed for Actions and is limited to the workflow repository. Workflow permissions, repository/org defaults, and event context determine what it can do.

If a workflow only needs to read code, create a release, comment on an issue, or perform another supported operation in its own repository, start by asking whether GITHUB_TOKEN can satisfy the requirement. A personal PAT should not be the default simply because “the workflow needs an API token.”

7. Expiration: security control plus availability dependency

Shorter lifetime reduces the window in which a stolen bearer credential remains useful. But expiration without ownership and rotation creates outages. A production credential record should therefore include owner, purpose, resource scope, expiry, consumer locations, rotation lead time, and a test that proves the replacement works before the old credential is revoked.

Credential Lifecycle pattern
Developer SSH key Device-bound; review periodically; rotate on device loss, personnel/offboarding events, or policy schedule.
Fine-grained PAT Short explicit expiration aligned with task; recreate/rotate intentionally; delete when task ends.
Classic PAT Exceptional compatibility credential; shortest feasible expiration and extra review because scopes can be broad.
GitHub App installation token Mint on demand; currently expires after one hour; do not persist as a long-lived secret.
GITHUB_TOKEN Issued for a workflow job and expires with the job/effective lifetime; permissions should be explicit and minimal.

8. Storage choices: “not in Git” is only the beginning

A credential copied out of source control can still leak through shell history, CI logs, process arguments, screenshots, crash dumps, clipboard history, backup systems, or overly broad environment inspection. The storage control must match how the credential is used.

Use case Preferred storage/handling Avoid
Developer HTTPS Git OS credential manager via GCM/gh. PAT embedded in remote URL or plaintext dotfile.
Developer SSH Private key with restrictive permissions/passphrase, ssh-agent; hardware key when appropriate. Shared private key copied across a team.
Local short script Credential manager or secure prompt/in-memory env for the process; delete/revoke afterward. Literal token in command line or source.
GitHub Actions Built-in GITHUB_TOKEN or encrypted secret only when necessary; do not log. Echoing entire environment/context.
External integration Secret manager for App private key; mint short-lived installation token. Long-lived human PAT in application config.

9. SSO and organization policy change the authorization equation

Enterprise Cloud SAML SSO can require a PAT or user SSH key to be authorized for an organization after the user establishes a linked external identity. Fine-grained PAT selection can also be subject to organization approval and policy. Therefore a credential design document must name both the GitHub credential and the organization/enterprise authorization context.

Do not interpret an SSO denial as “use a more powerful token.” The correct fix is usually to establish/refresh the required SSO session or authorize the credential according to organization policy. If policy blocks PATs entirely, the correct architecture may be a GitHub App or another approved integration identity.

Enterprise-only note: SSO credential authorization described here applies to GitHub Enterprise Cloud. It is not a universal rule for GitHub Enterprise Server. Select the documentation version matching the deployed product.

10. Decision table: choose the smallest durable credential

Scenario Recommended starting point Reason
Developer on managed laptop, routine Git HTTPS + GCM/gh if organization standardizes browser SSO; otherwise SSH key is also valid. Both can be secure; choose the managed lifecycle/network model.
Developer with hardware security key and stable SSH workflow Hardware-backed SSH key. Private key material is harder to export; clear device identity.
One-time script reading one private repository Fine-grained PAT limited to that repo and read permission, short expiry—if gh/browser credential cannot satisfy the task. Small resource and permission scope.
Repository Actions workflow GITHUB_TOKEN with explicit least-privilege permissions. No separate long-lived secret; repository-bounded job identity.
Service integrating across selected org repositories GitHub App installation token. Dedicated app identity, repository installation scope, short-lived access token.
Legacy endpoint documented as unsupported by fine-grained PAT Classic PAT only for the required compatibility case, with minimal scopes and short expiry. Use the exception deliberately and track migration away from it.

11. Worked scenario: Atlas release metadata bot

Atlas needs a bot that reads tags from ten repositories and opens release-tracking issues. A team member proposes a classic PAT from their personal account with broad repository scope and no expiration. It works, but it couples production automation to that person’s employment, permissions, token rotation, 2FA/account recovery, and offboarding.

A stronger target architecture is a GitHub App installed on only the ten repositories, with only the repository permissions required to read metadata and create issues. The service stores the App private key in an approved secret manager, mints installation tokens on demand, and logs installation/repository IDs—not token values. If the integration runs entirely inside one repository’s Actions workflow and needs only that repository, GITHUB_TOKEN may be even simpler.

Design outcome: use human credentials for human work. Give durable automation a durable machine identity with ephemeral access credentials.

12. Free-compatible design lab

Create a small credential design worksheet for these four actors: learner-laptop, local-read-script, repo-workflow, and atlas-integration. For each actor, record principal, credential type, resource scope, operations, lifetime, storage, revocation owner, and verification method.

No paid feature or live token is required. For atlas-integration, use a design-only GitHub App row. For the local script, compare “reuse managed gh authentication” against “temporary fine-grained PAT” and state why you would create the PAT only when the gh credential cannot meet the requirement.

13. Verification checklist

  • Your transport choice separates network/credential-management concerns from repository authorization.
  • Any PAT design names its resource owner, repositories, permissions/scopes, expiration, storage, and revocation owner.
  • Classic PAT use has a documented compatibility reason rather than convenience.
  • Automation designs prefer GITHUB_TOKEN or GitHub App installation tokens when those identities fit.
  • Credential storage plans address shell history/logs/URLs—not only source control.
  • Enterprise SSO is labeled as deployment/policy-specific and never treated as a universal GitHub rule.

Knowledge check

A CI job in one repository needs to comment on issues in that same repository. Which credential should you evaluate first?

Why is a GitHub App usually stronger than an engineer’s PAT for a long-running organization integration?

Does choosing SSH eliminate the need for repository authorization?

When is a classic PAT justified?

What is the hidden availability risk of very short token expiration?

14. Summary

Credential selection is architecture. SSH and HTTPS solve Git transport with different device/network/storage tradeoffs. Fine-grained PATs are the preferred user-token candidate when supported; classic PATs are compatibility exceptions; GitHub Apps provide dedicated automation identity; GITHUB_TOKEN is the first choice for many repository-local Actions operations.

Least privilege includes resource scope, operation, lifetime, storage, revocation, and organizational policy. A credential is not “secure” because it has a strong algorithm; it is secure when its complete lifecycle and blast radius are controlled.

Next lesson

Diagnose failures without broadening access

Lesson 04 uses status codes, SSH identity inspection, credential-helper evidence, SSO fixtures, and incident-response ordering to distinguish invalid credentials from insufficient authorization and policy denials.

Authoritative references

 Caching GitHub credentials in Git
 Managing personal access tokens
 Permissions required for fine-grained PATs
 Authenticating with a GitHub App
 Choosing permissions for a GitHub App
 GITHUB_TOKEN
 About authentication with single sign-on
 Authorizing a PAT for SSO
 Authorizing an SSH key for SSO
 gh auth login
 GitHub CLI environment variables

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.