Summary

  • GitHub confirmed that its GitHub.com RSA SSH host private key was briefly exposed in a public repository and that it replaced the RSA host key at about 05:00 UTC on March 24, 2023; GitHub also said the key did not grant access to GitHub infrastructure or customer data and that it had no reason to believe the key was abused. The primary notice is the GitHub security statement at https://github.blog/news-insights/company-news/we-updated-our-rsa-ssh-host-key/.
  • The practical incident was not only a private-key exposure. It was a trust-repair problem imposed on developers, CI systems, release managers, and small businesses that had to decide whether a changed SSH host identity was a legitimate provider rotation or an interception attempt.
  • The contract-control mismatch is that platform terms can limit warranties and liability, while provider operations still exercise real authority over customer build, release, and source-control continuity. GitHub's terms at https://docs.github.com/en/site-policy/github-terms/github-terms-of-service allocate legal risk differently from the way operational control works during a rotation.
  • Accountability follows the controls each actor actually held: GitHub controlled host-key custody, detection, rotation, first-party guidance, and supported action updates; customers controlled trust-store inventory, independent verification, pinned workflow updates, fallback transport, and release interruption discipline.

The contract could not rotate the key; GitHub could

The March 2023 event is easy to understate because it did not become a disclosed theft of customer repositories, customer accounts, or GitHub's production environment. It is also easy to overstate because possession of a server host key is not the same thing as possession of user credentials or a master key for private code. The useful accountability analysis sits between those errors. A single provider-controlled trust entity lost confidentiality, and the provider's repair action became visible to customer systems as the same warning those systems were built to show during a hostile change.

GitHub's notice said the old RSA SSH host private key had been briefly exposed in a public GitHub repository and that the company acted to protect users from possible impersonation or eavesdropping over SSH. It limited the impact to Git operations over SSH using RSA and said HTTPS Git operations, web traffic, ECDSA, and Ed25519 users were not affected in the same way. That scope matters. The event does not support a claim that private repositories were read from GitHub, that customer SSH private keys were disclosed, or that GitHub's internal service was generally breached.

It does support a claim that GitHub had to replace a service identity that many customers had pinned as a prerequisite for accepting code over SSH.

The contract-versus-control question begins with the service relationship. GitHub's current terms define a broad service and include disclaimers that the service is provided as available, with limits on assurances about timeliness, security, uninterrupted access, or error-free operation. Those terms are useful for legal allocation, but they did not give a customer the power to rotate GitHub.com's host key. They did not let a small software firm preserve an old key safely after the private key became public. They did not give a CI runner an independent way to know whether the new key was real.

Legal language and operational authority pointed in different directions.

The mismatch is common in cloud dependency. A provider may reserve broad discretion and limit exposure, while also becoming the only actor able to operate a shared control. Customers can leave the platform in theory, but in the moment of an emergency rotation they need a decision in minutes, not a procurement exercise. Their build systems, deployment tools, submodules, vendor integrations, and internal mirrors often assume that GitHub's SSH endpoint is a stable source of truth. When the source of truth changes itself, the customer must either stop or verify through another channel.

This is not a complaint that GitHub rotated. Rotation was the correct containment step once the private key was plausibly exposed. The accountability test is whether the organization with custody of the trust entity had enough preventive controls to keep it out of a public repository, enough detection to know how exposure happened, enough response control to revoke without creating avoidable confusion, and enough disclosure to let customers recover without weakening the very control that protected them.

What was confirmed and what remains unknown

GitHub's public account confirms five facts. First, the secret involved was the RSA SSH host private key for GitHub.com Git operations over SSH. Second, the company discovered that it had briefly appeared in a public repository. Third, GitHub replaced the key at approximately 05:00 UTC on March 24, 2023, and reported that the new key had been briefly visible during preparations beginning around 02:30 UTC. Fourth, the company said the incident was not caused by compromise of GitHub systems or customer information. Fifth, GitHub said it had no reason to believe the key had been abused.

Those statements define the evidence boundary. They do not identify the repository, person, workflow, scanner, exposure duration, number of views, number of clones, cache behavior, or root cause. They do not disclose the telemetry used to conclude there was no known abuse. They do not say whether the private key was generated or stored in a way that should have made repository publication impossible. They do not state whether the exposure was detected by GitHub's own secret scanning, an employee report, a user report, a researcher, or another control.

That absence matters because GitHub sells and documents controls meant to prevent public secret exposure. In February 2023, GitHub announced free secret-scanning alerts for public repositories at https://github.blog/news-insights/product-news/secret-scanning-alerts-are-now-available-and-free-for-all-public-repositories/. In May 2023, after the host-key event, it announced broader free push protection for public repositories at https://github.blog/news-insights/product-news/push-protection-is-generally-available-and-free-for-all-public-repositories/. Current GitHub documentation lists generic private-key patterns at https://docs.github.com/en/code-security/reference/secret-security/supported-secret-scanning-patterns. Those sources show the control family. They do not prove which control saw, missed, or blocked the specific host key in March 2023.

The root cause should therefore be stated narrowly. The trigger was exposure of the private host key in a public repository. The root accountability issue was not merely that exposure, but the custody system that permitted a production service identity to become publishable and the customer recovery path that then depended on live verification. Contributing conditions include the breadth of GitHub SSH use, old client trust stores pinned to RSA, automation that fails closed without a human nearby, workflows pinned to old action code, and customer runbooks that often treated host-key warnings as local annoyance rather than supply-chain signal.

The public record also separates potential from observed harm. A party with the old RSA host private key could attempt to impersonate GitHub to a client whose traffic it could divert and whose client accepted the old RSA identity. That could expose Git commands, pushed entities, repository content requested through that connection, or enable more elaborate deception depending on the attacker's position. But the key did not itself supply network position, user credentials, GitHub account access, or access to GitHub's stored repositories. The reviewed sources do not establish a successful impersonation incident.

The warning was the control working

SSH host-key warnings are not decorative friction. RFC 4253, at https://datatracker.ietf.org/doc/html/rfc4253, separates server authentication in the transport layer from user authentication. A client that remembers the expected server identity is supposed to stop when a server presents a different key. The OpenSSH client manual at https://man.openbsd.org/ssh_config describes strict host checking as a setting that refuses changed host keys. That refusal is exactly what customers needed if an attacker tried to stand between them and GitHub.

The March rotation created an operational paradox. A legitimate GitHub repair caused the same symptom that a man-in-the-middle attack could cause. A developer saw a changed-key warning. A CI runner saw a failed checkout. A deployment job saw a non-zero exit. The machine could not know whether the change was lawful. It only knew that the host identity no longer matched the local record. That is why the event belongs in a risk and accountability series even without confirmed customer data theft.

GitHub's troubleshooting guidance at https://docs.github.com/en/authentication/troubleshooting-ssh/error-host-key-verification-failed tells users to look for an official explanation and avoid connecting when one is absent. Its fingerprint page at https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/githubs-ssh-key-fingerprints publishes current GitHub SSH fingerprints. Its REST Meta documentation at https://docs.github.com/en/rest/meta/meta says the meta endpoint returns SSH key fingerprints and host keys and can be used without authentication for public resources. Together these channels provided a recovery path, but not a magic one. A customer still had to decide that the HTTPS documentation and API were trustworthy enough for the emergency and had to distribute the corrected trust entry without teaching staff to accept whatever key appeared on the SSH path.

The unsafe shortcut was to remove host checking globally or to populate trusted keys from a live network scan without independent verification. The OpenBSD ssh-keyscan manual at https://man.openbsd.org/OpenBSD-7.2/ssh-keyscan.1 warns that using scan output without verification can leave users open to interception. That warning applies directly. Running a scan against the very name whose identity is in dispute can record an attacker's answer as truth if the path is hostile.

The disciplined sequence is slower but safer: preserve the warning, compare the presented fingerprint against an authenticated provider statement and an internal approval source, update only the affected RSA host entry for the relevant hostname, perform a canary fetch, then roll the update through managed clients and runners. That sequence accepts a brief release delay as the price of not turning a trust failure into a trust bypass.

CI turned trust repair into service continuity

Human developers can read a notice. CI systems cannot. GitHub specifically warned that workflows using actions/checkout with the ssh-key option might fail and that GitHub was updating supported tags such as v2, v3, and main. The action's public repository at https://github.com/actions/checkout documents SSH-key support and strict host checking behavior. The same repair that a moving tag could receive centrally would not automatically reach jobs pinned to a specific commit SHA.

That tension is not a defect in pinning. GitHub's own action-hardening guidance at https://docs.github.com/en/code-security/tutorials/secure-your-organization/protect-against-threats recommends pinning actions to immutable commits for supply-chain integrity. In March 2023, immutable review created a continuity tradeoff. A customer that pinned old action code was protected from silent action changes, but also had to review and adopt a new commit to receive the embedded trust update. A customer using a moving tag could receive the provider's fix faster, but at the cost of executing code that may move without the customer's own review.

That is the developer-tool economics of the event. GitHub centralizes repository hosting, collaboration, issue tracking, package workflows, and CI integration because centralization reduces cost and friction. The same centralization means a provider key rotation can interrupt many customers at once. Each customer may experience a local build failure, but the cause is a shared platform control. Each customer may own its own known-hosts files, but the value inside them is a provider-owned assertion.

Small and medium-sized teams face the hardest version. A large enterprise may have endpoint management, CI platform owners, security engineering, and vendor contacts. A five-person software business may have one person who sees a failed deployment, checks a social feed, searches a support page, and has to decide whether to ship. CISA's small-business ICT supply-chain guidance at https://www.cisa.gov/resources-tools/resources/reducing-ict-supply-chain-risk-small-and-medium-sized-businesses-fact-sheet recognizes that smaller firms depend heavily on external technology providers while lacking dedicated risk staff. The March event is a compact example of that dependence.

An SME does not need a perfect alternate forge to be accountable. It does need a lightweight plan: a second Git transport already tested, a repository mirror or bundle for essential code, two people subscribed to provider notices, an internal page listing approved host fingerprints and source URLs, and a rule that host-key warnings are security events until verified. GitHub's remote URL documentation at https://docs.github.com/en/get-started/git-basics/managing-remote-repositories?changing-a-remote-repositorys-url=&platform=linux shows that switching between SSH and HTTPS is technically simple. Operationally, it requires credentials, permissions, and logging that do not create a new secret problem.

Backups are similarly bounded. GitHub's repository backup guidance at https://docs.github.com/en/enterprise-cloud%40latest/repositories/archiving-a-github-repository/backing-up-a-repository and Git's bundle documentation at https://git-scm.com/docs/git-bundle.html can preserve Git history, but they do not automatically preserve issues, pull requests, workflow secrets, package registries, access reviews, or release approvals. A backup plan that protects source code but loses the release state may still leave a business unable to recover cleanly.

Contract terms explain exposure, not control

The current GitHub Terms of Service are relevant because they show the legal surface around a service many organizations treat as critical infrastructure. The terms define the service broadly, treat private repository content as confidential subject to stated access purposes, provide for electronic communications, state no phone support for ordinary terms communication, and disclaim broad warranties. Those clauses can be commercially rational. They also show why contract language is not a substitute for operational accountability.

GitHub's private-repository terms at https://docs.github.com/en/site-policy/github-terms/github-terms-of-service say GitHub treats private repository content as confidential and may access it for specified purposes such as security, support, integrity, legal obligations, or consent. That language acknowledges provider authority over service integrity. A host-key rotation exercises similar authority at the connection layer. Customers may own their content and configure access, but they do not own the platform identity that authenticates GitHub.com over SSH.

The issue is not whether GitHub had a contractual right to rotate. It almost certainly needed one. The issue is whether contractual risk allocation matched practical control. Customers bore the downstream cost of updating trust stores, rerunning builds, explaining failures, and preventing unsafe workarounds. GitHub controlled the facts necessary to do that safely: the new fingerprint, affected key type, reason for rotation, exposure boundary, supported action update status, and confidence about abuse. When one party controls the evidence and the other party bears the recovery labor, disclosure quality becomes a control, not public relations.

GitHub Status at https://www.githubstatus.com/ can communicate operational incidents and component health, but a host-key event also needs authenticated security guidance. A general green status page cannot tell a CI job whether a new SSH fingerprint is lawful. A provider notice, fingerprint page, API endpoint, support response, and status component need to be internally consistent. If one says the key is replaced and another remains silent or stale, customers may pause longer or make unsafe decisions.

The public notice did several things well. It named the affected algorithm, gave a precise rotation time, acknowledged the early appearance of the new key, supplied the new fingerprint and full public key, separated HTTPS and other host-key algorithms from RSA SSH, warned Actions users, and explained that the old key did not grant access to GitHub infrastructure or customer data. Those are useful operational facts. The missing facts sit elsewhere: exact exposure duration, detection path, retrieval evidence, telemetry limits, custody changes, and later assurance that the same class of publication had been made less likely.

The accountability lens therefore does not ask GitHub to promise perfect availability or zero error. It asks the platform to provide evidence proportionate to the control it holds. A contract can say risk is limited. It cannot make an exposed private host key unexposed. It cannot make a changed host key self-authenticating. It cannot let customers verify facts GitHub alone has not published.

Detection, response, and recovery failures by practical control

The trigger was the exposure of the RSA host private key. The root issue was key custody and emergency trust repair. Contributing conditions included a shared platform identity, uneven customer use of RSA rather than newer host keys, hidden trust stores in automation, pinning tradeoffs in Actions, and customer runbooks that often lacked a verified rotation path.

Detection failure cannot be assigned in detail from the public record because GitHub did not disclose the detector. The event may have been found by a control working correctly. It may have been found by a person. It may have been found after a delay. The right public conclusion is not that detection failed, but that detection evidence is unverifiable from outside. For a provider whose product includes secret detection, that evidence gap is material because customers could learn from the path only if the path is described.

Response was partly strong. The exposed key was retired quickly after public notice. The replacement was scoped to RSA, and unchanged ECDSA and Ed25519 keys reduced blast radius. GitHub supplied an authoritative fingerprint and update directions. It also updated supported actions/checkout tags. The response weakness was the unavoidable confusion created by a new key briefly appearing around 02:30 UTC before the stated 05:00 UTC replacement. That may have been harmless preparation, but to a customer it looked like a changed identity before the final cutover. GitHub acknowledged it; the public record does not explain the mechanism.

Recovery was distributed to customers. Workstations, runners, containers, base images, appliances, build services, and deployment systems all had to update local trust. GitHub could update its own supported action tags, but customers with pinned commits or external CI had to act. That is not unfair by itself. It is the shared responsibility boundary in operation. It becomes unfair only if the provider's guidance is incomplete, if the customer has no practical way to receive it, or if customer contracts imply autonomy that does not exist during a platform identity event.

The most revealing metric would be time to verified recovery, not time to provider rotation. How long did it take major customer categories to restore strict SSH trust without disabling checks? How many support tickets involved unsafe workarounds? How many failed Actions runs involved pinned code? How many customers used the old RSA key after the notice? The public record reviewed for this article does not provide those measures. Their absence limits the ability to say whether recovery was merely completed or measurably improved.

A typography note about records and readability

Forensics is not only a pile of facts; it is also a presentation problem. Customers need warnings, fingerprints, dates, and caveats arranged so that the safe action is clear under pressure. The following typography note belongs in that public body of evidence because the form of a notice can change whether readers preserve or erase the signal.

Typography is the art and technique of arranging type to make written language legible, readable, and visually appealing. It involves selecting typefaces, point sizes, line lengths, line-spacing, and letter-spacing.

  • Typography originated with the invention of movable type by Johannes Gutenberg in the 15th century.
  • Key elements include font selection, kerning, tracking, and leading.
  • Good typography enhances readability and conveys mood or tone in design.

Applied to a host-key rotation, the practical point is simple: the fingerprint, affected algorithm, time window, and safe command path must be visually distinct from context and reassurance. A notice that buries the key material inside marketing layout or vague status prose raises the chance that customers paste the wrong entry or skip verification. The same discipline applies to internal runbooks. A developer under release pressure should see the stop condition, approved source, exact fingerprint, and reviewer rule before seeing background narrative.

Accountability by control, not by slogan

GitHub had the largest preventive control share. It controlled generation, storage, use, and retirement of the host private key. It controlled the repository service on which the key appeared. It controlled product security features that could detect or block private keys, even if the public record does not show which one applied. It controlled the rotation plan, authoritative announcement, fingerprint page, API data, support guidance, and first-party action updates. It also controlled how much detail to publish after containment.

GitHub also had a justified emergency discretion. Leaving a potentially copied private host key in service to avoid customer friction would have preserved an impersonation path. The right critique is not that the platform moved too aggressively. It is that emergency authority should be paired with readiness evidence: rehearsed rotation, verified publication controls, consistent messaging, and a post-incident account of durable change.

Customers controlled their own trust consumption. They decided whether to use SSH or HTTPS, whether to pin RSA host keys, whether to learn alternate host-key algorithms, whether to manage known-hosts centrally, whether to bake keys into images, whether to pin action commits, whether to maintain a mirror, and whether developers were allowed to bypass strict checking. These choices do not excuse provider key exposure. They determine how much a provider-side event turns into customer downtime or unsafe recovery.

CI maintainers and integration vendors controlled embedded trust material and update channels. A tool that hides host keys for convenience should expose a safe way to update them. A tool that relies on live scanning should warn users about verification. A tool that pins dependencies for integrity should make emergency review fast enough that secure pinning does not become stale pinning.

Procurement and legal teams controlled a quieter boundary. They often accepted platform terms without mapping which controls the vendor alone could exercise. A better contract-review question is not simply whether damages are capped. It is which operational facts the provider will disclose during a trust event, how customers will authenticate emergency notices, whether support paths are available for security-critical rotations, and what evidence will be delivered after repair.

Attackers, if any used the key, would be accountable for impersonation or interception. The public record does not establish such use. Network operators, DNS providers, and other trust-channel entities may matter in hypothetical exploitation, but the reviewed facts do not show their failure in this event.

What verifiable repair would look like

The mature control record after this event would not be a promise that no host key will ever be exposed. It would be evidence that the class of failure became harder to repeat and easier to recover from safely.

For custody, GitHub should be able to show that production host private keys cannot enter ordinary repositories, developer workstations, logs, test fixtures, or build artifacts except through a documented break-glass path. That evidence might include key-generation controls, access logs, export restrictions, scanning coverage, and automatic revocation triggers. Outsiders do not need every sensitive detail. They do need enough assurance to know that the fix was not limited to replacing one key.

For detection, GitHub should be able to show time from publication to alert, alert to containment, containment to rotation decision, and rotation decision to customer notice. It should also be able to state what kinds of retrieval evidence were reviewed and what visibility limits remained. "No reason to believe abuse" is a meaningful company statement, but it is not the same thing as a published detection basis.

For response, GitHub should test host-key rotation as a normal exercise. OpenSSH supports mechanisms such as UpdateHostKeys after authentication with an already trusted key, documented at https://man.openbsd.org/ssh_config, but emergency exposure limits overlap time. A provider can still rehearse customer notice, API updates, status messaging, first-party integrations, and support scripts. A clean drill would measure whether customers can update without disabling checking.

For customers, verifiable repair means keeping an inventory of all GitHub trust material and all workflows that use SSH. It means knowing which jobs use actions/checkout with SSH, which are pinned, which base images contain known-hosts files, and which release paths can switch to HTTPS. It means logging host-key failures as security events, not simply build noise. It means preserving evidence before editing trust files.

For SMEs, repair should stay simple. A short runbook, a tested HTTPS remote, a mirror for critical repositories, a second reviewer for host-key changes, and subscribed security notices may be enough for many firms. The central point is not to remove dependence on GitHub. It is to make the dependence visible enough that a provider trust repair does not force improvisation.

The small-customer failure chain

The small-customer version of this event is often the least visible because it produces few public filings and no consolidated incident count. A developer arrives to a failed pipeline. The error mentions a changed host key. A release is already late. A security notice may be available, but the person reading it has to compare fingerprints, update a trust file, rerun a job, and explain the delay to a customer or manager. If the organization has no runbook, the safe path competes with a one-line workaround copied from an old forum answer.

That is where developer tool economics become accountability evidence. GitHub reduces operating cost for small teams by hosting repositories, collaboration workflows, pull requests, issues, packages, and hosted automation in one place. A small firm may save years of infrastructure work by relying on that platform. The cost of the saving is that provider trust changes arrive as local operational events. The firm does not negotiate a host-key rotation schedule. It reacts to one.

The first control for such a firm is pre-decision clarity. A host-key warning should not be assigned to the person with the strongest desire to make the release pass. It should be assigned to a preselected security or release owner, even if that owner is one of only two engineers. The organization should keep the exact provider fingerprint source, the internal approval rule, and the rollback plan in a short record. The point is not ceremony. It is removing the need to invent judgment under pressure.

The second control is split recovery. One person verifies the provider notice and fingerprint through an HTTPS channel. Another person applies the change through configuration management or a reviewed commit. If the team is too small for two people on call, the fallback is delayed release until a second reviewer is available, except for defined emergency patches. This is not because two people are always more accurate. It is because the act of separating verification from application catches the most common unsafe shortcut: trusting the key presented by the disputed SSH path.

The third control is transport discipline. HTTPS fallback can preserve delivery when SSH host trust is being repaired, but it must already be configured with scoped credentials. A rushed switch that uses a broad personal token or exposes a credential in a build log trades one incident for another. The fallback should be tested before a provider event, with enough permissions to fetch or push the specific repository and no more.

The fourth control is evidence retention. Failed CI logs, host-key warnings, and timestamps should be preserved before edits. If a customer later suspects interception or needs to prove that a failed deployment was caused by a provider rotation, erased local evidence will make the answer weaker. GitHub may have server-side records of successful Git activity, but a refused SSH handshake may never reach the service as a Git event. Client logs are part of the record.

These controls are modest. They do not require an enterprise security operations center. They require recognizing that a host identity is production configuration. Once that recognition exists, the cost of a key rotation can be managed as a small change rather than a crisis in which security controls are disabled to make work green.

Procurement should ask for rotation evidence

Procurement often asks cloud and developer-tool vendors for uptime numbers, data processing terms, security certifications, and incident notification clauses. The March 2023 event suggests a more specific evidence request for software supply-chain platforms: show how customer trust entities are rotated and how customers authenticate the replacement.

The request should not demand secret internal designs. It should ask whether production private keys are export-restricted, whether emergency rotation is rehearsed, which customer channels are used for authenticated key material, which first-party integrations embed host identities, how status and security notices are kept consistent, and whether customers receive a post-incident account of changed controls. These are not exotic questions. They are the operational interface between vendor authority and customer dependence.

Contract language can also name customer duties without pretending the customer controls the platform key. A balanced clause can say that the provider will publish authenticated replacement material and affected service scope promptly, while the customer will maintain a process for updating its own trust stores and preserving strict checking. That does not eliminate liability disputes. It gives both sides a practiced path.

The same evidence belongs in internal risk registers. A company that says GitHub is not critical because its code can be cloned elsewhere should test that claim. Can it restore repositories, protected branch rules, release artifacts, workflow definitions, deployment keys, issue history, package references, and team permissions elsewhere fast enough for its business? If not, GitHub is critical enough to warrant trust-rotation planning even if the contract disclaims broad availability guarantees.

The test should include the notice channel itself. If the only people who can approve a host-key change are reachable through a chat system, single sign-on flow, or deployment dashboard that depends on the same platform event, the recovery plan is circular. Emergency trust changes need an authenticated source, an offline-readable runbook, and a reviewer path that still exists when developer tooling is degraded.

Final assessment

The confirmed event was medium impact and high confidence. The private RSA host key exposure created a credible impersonation risk for SSH clients that still trusted that key and whose network path could be diverted. GitHub's rotation was prudent, scoped, and publicly documented. The reviewed record does not show customer repository theft, GitHub infrastructure compromise, user private-key exposure, or confirmed abuse of the old host key.

The accountability finding is sharper than the incident size. GitHub's operating control over a shared host identity exceeded the practical protection customers could buy in ordinary terms. Customers could read the contract, but they could not inspect the key custody path. They could accept disclaimers, but they still had to stop builds when a host identity changed. They could own their repositories, but a provider-side key event could determine whether their release system trusted the source.

That is the contract-control mismatch: the legal documents describe a service relationship; the incident revealed an operational dependency. Accountability therefore belongs at the point of practical control. GitHub owed custody, fast rotation, accurate notice, and repair evidence. Customers owed strict verification, trust inventory, and continuity planning. The difference between those duties is not abstract. At 05:00 UTC on March 24, 2023, it was the difference between a secure pause and an unsafe paste.

Typography

Typography is the art and technique of arranging type to make written language legible, readable, and visually appealing. It involves selecting typefaces, point sizes, line lengths, line-spacing, and letter-spacing.

  • Typography originated with the invention of movable type by Johannes Gutenberg in the 15th century.
  • Key elements include font selection, kerning, tracking, and leading.
  • Good typography enhances readability and conveys mood or tone in design.