Home / Alt manpages / gh-repo-deploy-key-add(1)

  • gh-repo-deploy-key-add(1)
  • User command
  • linux

Add a GitHub Deploy Key with gh repo deploy-key add

gh repo deploy-key add gives a build server its own SSH key, so it never has to borrow your personal login. You will create a dedicated Ed25519 key, add its public half to one GitHub repository, check that GitHub recorded the access mode you meant, and have the command ready to remove it later. The examples use GitHub CLI 2.87.3, installed on the machine used for this guide.

Allow about 10 minutes. You need an authenticated gh session with permission to administer the target repository, OpenSSH's ssh-keygen, and the repository name in OWNER/REPO form. No elevated privileges are required. Keep the private key on the machine that will use it, and never paste it into a command or upload it to GitHub.

1. Choose the repository and key location

Replace the two placeholders below before running anything. A deploy key belongs to one repository, so use a separate key for each repository that needs machine access, and give it a descriptive filename so you cannot select the wrong key later.

REPO="example-owner/example-repo"
KEY="$HOME/.ssh/example-repo-deploy"
gh auth status
printf '%s\n' "$REPO" "$KEY"

The first command reports the accounts and hosts known to GitHub CLI. The last command only prints your choices back to you. Stop here if the authenticated account, repository or key path is not what you expect.

Checkpoint

Before generating anything, confirm three things: REPO names the intended repository (such as acme/widget), KEY does not point at an existing private key you still need, and the authenticated GitHub account can manage deploy keys on that repository.

2. Generate a dedicated public and private key

This step creates two files on disk. The private key has no passphrase in this unattended example, which suits a service but raises the importance of filesystem permissions and host security. If a person will use the key interactively, drop -N "" and enter a passphrase when prompted.

ssh-keygen -t ed25519 -C "example-repo deploy key" -N "" -f "$KEY"
chmod 600 "$KEY"
ls -l "$KEY" "$KEY.pub"

Do not accept an overwrite prompt unless you have deliberately checked the existing file. Expect a new private key at $KEY and a public key at the same path with .pub appended; the public file is the one that goes to GitHub.

If you chose the wrong path, remove only the newly created pair after checking it carefully: rm -- "$KEY" "$KEY.pub". Do not use a wildcard in that recovery command.

3. Add the public key as read-only

Read-only is the safer default for checkout, deployment or monitoring. The command takes the public key file as its positional argument. Pass --repo explicitly so it cannot accidentally target a different repository inferred from the current directory.

gh repo deploy-key add "$KEY.pub" \
  --repo "$REPO" \
  --title "example-repo deployment"

On success, GitHub CLI returns a success message and the key becomes available to that repository. The installed command also accepts the short forms -R for --repo and -t for --title. There is no confirmation prompt in the documented usage, so check the repository and public key path before you press Enter.

4. Verify the title, key and access mode

List the repository's deploy keys and request fields that make the result unambiguous:

gh repo deploy-key list \
  --repo "$REPO" \
  --json id,title,key,readOnly

Find the entry titled example-repo deployment. Its readOnly value should be true, and its key value should begin with the same Ed25519 public-key material shown here:

cut -d ' ' -f 1-2 -- "$KEY.pub"

Do not treat a matching title alone as proof that the right key was installed; titles are labels and can be reused. If the entry is missing, check the command's error, authentication and repository spelling, then run the list command again.

5. Grant write access only when required

A read-only deploy key cannot push. If the service genuinely needs to push to this repository, add a separate key with write permission rather than broadening an existing key without review.

gh repo deploy-key add "$KEY.pub" \
  --repo "$REPO" \
  --title "example-repo deployment writer" \
  --allow-write

Warning

--allow-write is a security-sensitive change, since anyone who obtains the private key may be able to alter the repository. Protect the host, restrict the private key to the service account, and prefer read-only access whenever the job only downloads code. Verify this second entry with the same list command and expect readOnly to be false.

6. Remove a key when the machine or job is retired

Deleting a deploy key is the recovery path for a lost host, a replaced job or an incorrect entry. Use the numeric id returned by the list command, not a title guessed from memory.

gh repo deploy-key delete KEY_ID --repo "$REPO"
gh repo deploy-key list --repo "$REPO" --json id,title,key,readOnly

Confirm that the deleted ID no longer appears. Then remove the local private and public files only if this machine no longer needs them: rm -- "$KEY" "$KEY.pub". The GitHub CLI manual warns that keys added by it are tied to the current authentication token; de-authorising that token or the GitHub CLI application also removes keys added through it, so plan for that dependency when designing an unattended deployment.

Done means

  • Checked the intended repository and authenticated account before the change.
  • Kept the private key local and protected with mode 600, passing only the public key to gh.
  • Confirmed the list output shows the expected title, key material and readOnly value.
  • Documented a need and a rotation plan for any write-enabled key.
  • Recorded the deploy-key ID so it can be deleted without guessing.