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.
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_TOKENbased 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.
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. |
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.
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.
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.
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_TOKENor 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?
The built-in GITHUB_TOKEN with explicit
least-privilege permissions, because it is already a
repository-scoped job identity.
Why is a GitHub App usually stronger than an engineer’s PAT for a long-running organization integration?
The App is a distinct automation identity with install/repository/permission boundaries and short-lived installation tokens, instead of inheriting a human account’s lifecycle and potentially broad access.
Does choosing SSH eliminate the need for repository authorization?
No. SSH authenticates the caller; GitHub still evaluates the account’s access and repository/ref policy.
When is a classic PAT justified?
When the current documented scenario or endpoint requires a capability fine-grained PATs do not support and a GitHub App/other credential is not the appropriate solution; keep scopes/lifetime minimal.
What is the hidden availability risk of very short token expiration?
If ownership, rotation, consumer inventory, and pre-cutover verification are missing, expiration becomes an outage. Short lifetime must be paired with a reliable replacement process.
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.
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.