For a server that only needs to read one repository, a deploy key is usually the tighter fit. GitHub describes it as an SSH key that grants access to a single repository and is read-only by default. A personal access token acts as you and can reach more than the server needs.
What GitHub says about deploy keys
GitHub's guide on managing deploy keys describes ways to handle SSH keys on servers when you automate deployment scripts: SSH agent forwarding, HTTPS with OAuth tokens, deploy keys, or machine users. A deploy key is an SSH key that grants access to a single repository. The public part is attached to the repository instead of a personal account, and the private part stays on your server.
Deploy keys are read-only by default. You can give one write access when you add it to a repository.
The trade-offs in GitHub's own words
GitHub lists these pros: anyone with access to the repository and server can deploy, people do not have to change their local SSH settings, and keys are read-only by default.
It lists these cons: a deploy key grants access to a single repository, so a project that pulls many repositories to one server needs more keys. Deploy keys are usually not protected by a passphrase, which makes the key easy to take if the server is compromised. They are credentials with no expiry date. And they are not linked to organization membership, so if the person who created the key is removed from the repository, the key stays active.
GitHub also warns that a deploy key with write access can perform the same actions as an organization member with admin access, or a collaborator on a personal repository.
That last point is the one to remember. Read-only is the safe default. Add write only when a job really has to push, and think hard about what a leaked key could do.
Comparison table
| Option | Scope | Tied to a person | Notes |
|---|---|---|---|
| Deploy key | One repository | No | Read-only unless you grant write, no expiry |
| Personal access token | Whatever its scopes allow across your repos | Yes | Stops working if your account loses access |
| SSH agent forwarding | Any repo your key reaches | Yes | Needs trust in the remote host |
| Machine user | Repos you grant it | No, but it is an account | Another account to manage and secure |
Fine-grained tokens narrow the scope of a personal token, but they are still issued under a person's account.
A simple decision path
- One server, one repository, read only: use a deploy key.
- One server, several repositories: consider a dedicated machine identity per server, or a short-lived token issued by your platform, rather than one broad personal token.
- A job that must push: prefer a scoped token from your CI system, and keep write access out of long-lived keys on servers.
- Anyone's personal token on a server: replace it, because it breaks when that person leaves and it carries their whole reach.
Whatever you pick, record who owns the key, which server holds it, and when you will review it.
Housekeeping
Because GitHub notes these keys have no expiry date, set your own review date. Give each server its own key, so you can revoke one without touching the rest. Name keys after the host and purpose, store the private half with tight file permissions, and delete the key from the repository when you decommission the server.
Where Safeguard fits
Safeguard works on the dependency and code side of your software: SBOM and dependency scanning, reachability analysis and policy gates. It does not store or manage credentials, so keep using your password manager, secrets manager or cloud identity for that. You can run a free scan of a project at gold.safeguard.sh/scan.
Quick check
Can two repositories share one deploy key?
GitHub's guide says a deploy key grants access to a single repository, so each repository needs its own.
Are deploy keys read-only?
By default yes. GitHub lets you grant write access when you add the key.
Why not use my personal token on a server?
It carries your reach and it is tied to your account, so it fails or becomes a risk when your access changes.
Sources
Last reviewed: 19 October 2026.