When would you use a GitHub deploy key instead of a token for a CI job's repository access?
answer
- Scoped to exactly one repository
- SSH-based, not API-based
- Read by default, write is opt-in
- Belongs to no user account
- Cannot be reused on a second repository
basics
~20 sUse a GitHub deploy key when a machine needs Git access to exactly one repository and nothing else. It is an SSH key attached to that repository, read-only unless you enable write, tied to no user account, and carrying no API access.
solid answer
~50 sA **deploy key** is an SSH public key registered on a single GitHub repository. It authorises Git transport operations against that one repository — clone and fetch, plus push if you tick write access — and nothing more: no API calls, no other repositories, no organization surface. Because it is not attached to a person, it survives that person leaving. That narrowness is the reason to choose it, and also its limits. GitHub will not accept the same key on a second repository, so multi-repo CI needs a different mechanism. A deploy key has no expiry and only two privilege levels, and audit entries point at the key rather than at an identity. When you need several repositories, finer scopes, or short-lived credentials, a fine-grained personal access token or a GitHub App installation token is the better fit; inside GitHub Actions the workflow's own `GITHUB_TOKEN` already covers its own repository.
code
json · 5 lines{
"title": "ci-build-runner",
"key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... [email protected]",
"read_only": true
}go deeper
Know that a deploy key is an SSH key attached to one repository, that it is read-only unless write is enabled, and that it is the credential CI uses to clone rather than someone's personal login.
Explain the scope precisely: Git transport on a single repository, no API surface, no reuse across repositories. Then name a concrete case where that limit forces you to a different credential.
Show the operational side — rotation, inventory across repositories rather than users, defaulting to read-only, and why a departing engineer's personal token as CI infrastructure is an outage waiting to happen.
Own the org-wide credential strategy: which automation gets Apps, where deploy keys remain acceptable, how expiry and rotation are enforced, and how you keep an inventory that a repository-scoped credential does not naturally produce.
## What a deploy key actually is A deploy key is an SSH public key stored on a **single repository**. Whoever holds the matching private key can authenticate to GitHub over SSH for that repository and perform Git operations on it. By default the key is **read-only**; adding it with write access enabled lets it push. There is nothing in between. The key point candidates miss: a deploy key grants **Git access only**. It cannot call the REST or GraphQL API, cannot open a pull request, cannot read issues, and cannot touch any other repository — even one owned by the same account. Its blast radius is one repository and one protocol. ## When it is the right tool The classic fit is a deployment or build machine that must clone one repository. A read-only deploy key on that repository gives it exactly that and nothing else, and it survives staff changes because it is not tied to anyone's account. Compare that with the common anti-pattern of pasting an engineer's personal access token into a CI system: that token reaches every repository that person can reach, and it dies the day they leave — usually at 3 a.m., in production. ## Where it runs out **One repository only.** GitHub rejects a key that is already registered as a deploy key elsewhere, so a build that clones a service plus two shared libraries cannot be served by one deploy key. Teams that fight this end up creating a "machine user" account and granting it read on several repositories — which works but consumes a seat and reintroduces a user-shaped credential. **Two privilege levels.** Read or read-write. There is no "push to this branch only" and no "read Actions but not code". Branch-level restriction is a repository rule, not a property of the key. **No expiry, manual rotation.** A deploy key lives until someone deletes it. Rotation is a deliberate act, and the private key is a file somewhere that must itself be protected. **Weak attribution.** Pushes and audit records identify the key, not a human. That is fine for a robot, and unhelpful when you are trying to reconstruct who triggered something. ## The alternatives, and what each buys A **fine-grained personal access token** can be scoped to selected repositories with per-permission granularity and a mandatory expiry, so it fits the multi-repository case that deploy keys cannot. A **GitHub App installation token** is the strongest option for automation: it is issued per installation, scoped to chosen repositories and permissions, and is short-lived, so a leak has a bounded lifetime. Inside GitHub Actions, the workflow run is already handed a `GITHUB_TOKEN` scoped to the workflow's own repository and valid only for that run — reaching for a deploy key to clone the repository the workflow already lives in is redundant, while cloning a *different* private repository from a workflow is exactly where a deploy key or an App token earns its place. ## The decision, compressed One repository, Git operations only, no API, credential must outlive individuals → deploy key, read-only unless you can justify write. Multiple repositories, or any API access, or a hard requirement for short-lived credentials → App installation token, or a fine-grained token where an App is overkill. Never a personal token belonging to a named human as long-lived CI infrastructure. ## Operational hygiene Whatever you pick: enumerate what exists. Deploy keys are listed per repository (and readable through the repository keys API), so an access review must walk repositories rather than users — the reason they are so often forgotten. Record who owns each key, why it exists, and where the private half lives, and delete write access wherever read would do. A read-only deploy key that leaks is an exposure; a write-enabled one that leaks is an attacker with commit rights on your default branch.
- Your CI job must clone a service repository and two shared library repositories. Can one deploy key do it?No — GitHub binds a deploy key to a single repository and rejects the same key on another one. Options are a separate deploy key per repository, a GitHub App installation token scoped to all three, or a fine-grained personal access token listing the three repositories. The App token is usually the right answer because it is short-lived and per-permission.
- Why is a write-enabled deploy key riskier than a read-only one, and how do you contain that?A leaked read-only key exposes source; a leaked write key lets an attacker push code that your pipelines will build and deploy. Contain it by defaulting to read-only, by protecting the default branch with rules so no credential can push to it directly, and by scoping any write-capable key to a repository whose contents are not deployment-critical.
- How does a deploy key differ from a GitHub App installation token for automation?A deploy key is a long-lived SSH credential for Git operations on one repository. An installation token is short-lived, can cover several repositories, and carries fine-grained API permissions — so an App can open pull requests, post statuses and read metadata, none of which a deploy key can do. The App also identifies itself as an app in the audit trail.
saying these in an interview costs you the question
- Says a deploy key can call the GitHub API
- Thinks one deploy key covers a whole organization
- Assumes deploy keys expire on their own
- Uses a personal access token as permanent CI credential
- Enables write access by default without justification