Safeguard
Security Guides•

Why do deploy keys survive a contractor's offboarding?

Deploy keys belong to a repository, not a person, so removing a contractor leaves them live. Find, rotate and replace them as part of every exit.

Safeguard Security Team
4 min read

Deploy keys survive because they are tied to a repository, not to a user. GitHub documents that if the person who added a key is removed, the key stays active. Anyone holding the private key can still read, or write if allowed, until you delete it from the repository.

What GitHub says about deploy keys

GitHub's documentation lists several properties that matter for offboarding:

  • A deploy key grants access to a single repository.
  • Deploy keys are read only by default, but can be given write access when added.
  • They are usually not protected by a passphrase, so anyone with the file can use it.
  • They are credentials without an expiry date.
  • They are not linked to organization membership. If the user who created the key is removed from the repository, the key remains active, because it belongs to the repository.

The roles documentation repeats the point as a warning: when someone adds a deploy key, any user who has the private key can read or write (depending on settings) even if they are later removed from the organization.

Why contractors create them

Contractors set up build servers, staging hosts and scripts. A deploy key is the quickest way to let a server pull code. It works, nobody reviews it, and months later nobody remembers who owns the private half.

The exit sweep

  1. List the deploy keys on every repository the contractor worked in, under the repository settings, and on any repository where they asked an administrator to add one.
  2. For each key, record the title, the date added, whether it has write access, and the server that uses it.
  3. Identify which keys the contractor generated and which are still needed.
  4. Generate replacement keys on your own infrastructure for anything still needed, deploy them, and then delete the old key.
  5. Delete keys that nothing uses.
  6. Check the audit log for key additions and removals around the engagement dates. GitHub retains audit log events for the last 180 days, so run this review promptly rather than a year later.

Prefer designs that avoid shared long lived keys

ApproachTied to a personExpiryOffboarding effort
Deploy keyNo, tied to a repoNoneManual review each time
Personal access tokenYesPolicy can limit lifetimeRevoked when the account loses access
Short lived credentials issued by your pipelineNoMinutes or hoursLittle to do

Where your platform supports it, short lived credentials issued at run time remove the whole class of problem. If you must keep deploy keys, name them with an owner and an end date, such as the system name plus a review date, and add them to a register you check each quarter.

A note on machine accounts

Some teams create a shared machine user for contractors. GitHub's guidance on managing deploy keys lists machine users as one option, but a shared account hides who did what and its password or token outlives any one person. If you use one, treat every departure as a reason to rotate its credentials.

Keep it from recurring

Safeguard's asset discovery helps you see repositories and pipelines you may have forgotten, and its compliance and evidence automation can record that the review happened. See the free scan.

Quick check

Do deploy keys expire?

No. GitHub documents deploy keys as credentials that do not have an expiry date, so you must remove them yourself.

Does removing a user remove their deploy keys?

No. The key is tied to the repository, so it stays active until someone deletes it from the repository settings.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.