Skip to content
LearnDeploy key

What is a deploy key?

Also known asrepository SSH key
Example. Kiteline is a fictional company.
On this page

A deploy key is an SSH key pair whose public half is attached to a single repository on a Git host, instead of to a user account, so that a server or build system holding the private half can clone, and if allowed push to, that one repository.

How it works on GitHub

GitHub describes a deploy key as "an SSH key that grants access to a single repository"; it "attaches the public part of the key directly to your repository instead of a personal account", and "the private part of the key remains on your server" (GitHub Docs).

Deploy keys are read-only by default. You can grant write access, and that is a bigger step than it sounds: GitHub notes that a key with write access "can perform the same actions as an organization member with admin access" on that repository.

Strengths and weaknesses

The appeal is scope. The key opens one repository, not everything a developer can reach, and the server doesn't need a person's credentials.

GitHub lists the drawbacks plainly:

  • Deploy keys "are usually not protected by a passphrase, making the key easily accessible if the server is compromised."
  • They "are credentials that don't have an expiry date."
  • They "aren't linked directly to organization membership": if the person who created one leaves the repository, "the deploy key will still be active."
  • "You can't reuse a deploy key for multiple repositories", so a server that pulls ten repositories needs ten key pairs.

For better security and finer control, GitHub recommends a GitHub App instead.

Common mistakes

  • Write access by default. A deploy pipeline that only clones needs read-only.
  • Forgetting them at offboarding. A developer who created a deploy key, or could read its private half from a server or a shared folder, still has a working credential after leaving. Rotate keys they could have copied.
  • The same private key on many servers. One stolen copy then works from anywhere.
  • No inventory. Repository settings list deploy keys per repository; few teams look at them across the organization.

Deploy keys and Crunu

Crunu doesn't create or remove deploy keys on GitHub, GitLab or Bitbucket. It can hold the private half and deliver it to the machine that needs it: store the key file in the server's environment, and the agent delivers it only to machines granted that environment. One detail to know: crunu pull refuses to write into ~/.ssh/ unless you allow that path for a single run with --allow-path, so choose a location your deploy process reads from, or allow it explicitly.

When someone leaves, the reissue checklist lists the values they received that are still in use, which includes a deploy key stored in one of those environments. Replacing it means generating a new pair, adding the new public key to the repository, delivering the new private key, and deleting the old public key at the Git host. For the credentials a pipeline needs beyond the checkout, see CI/CD secrets with OIDC.

Sources

From the blog

  • Teams

    When an admin leaves: the keys that sign everything

    An admin holds the keys and accounts that vouch for everyone else's access. The order that closes them: ownership, vault keys, recovery channels, review.

    Offboarding guide

  • Servers

    Secrets in Docker images: build args, layers and checks

    ARG and ENV values stay in a Docker image, and deleting a file in a later layer doesn't remove it. How to build with secret mounts and check an image.

    Sharing .env files guide

  • Secrets

    source .env can run code: loading env files into a shell

    set -a; source .env runs the file as a shell script, so $(…) and backticks execute. Why shells and dotenv parsers disagree, and safer ways to load .env.

    Sharing .env files guide