Skip to main content

More Info:

Deploy keys can have significant access to a repository and should be rotated on a regular basis.

Risk Level

Medium

Address

Security

Compliance Standards

  • Cloudanix Best Practice

Triage and Remediation

Remediation

Using Console

To remediate a “Repo Deployment Keys Rotated” finding in GitHub, you essentially need to create a new SSH deploy key pair and replace the old deploy key in the repository via the GitHub web console.Below are the minimal, step‑by‑step instructions.

1. Generate a New SSH Key Pair (Deploy Key)

Run this on a secure machine that will hold the private key (e.g., your CI server or a secure admin machine):
  • Press Enter for no passphrase (deploy keys usually must be non‑interactive).
  • This creates:
    • Private key: ~/.ssh/<repo-name>-deploy-key
    • Public key: ~/.ssh/<repo-name>-deploy-key.pub
Copy the public key:
Keep the private key secure; you’ll configure it wherever the deployment/CI runs.

2. Add the New Deploy Key in GitHub Console

  1. Go to the repository in GitHub.
  2. Click Settings (top of repo).
  3. In the left menu, click Deploy keys.
  4. Click Add deploy key.
  5. Fill in:
    • Title: Something clear (e.g., CI Deploy Key (rotated 2026-07-25)).
    • Key: Paste the public key you copied.
    • Allow write access:
      • Enable only if this key must push to the repo; otherwise leave unchecked.
  6. Click Add key.

3. Update the System That Uses the Deploy Key

On the system that actually performs the deployment (CI/CD tool, build server, etc.):
  1. Replace the old private key with the new private key (<repo-name>-deploy-key).
  2. Ensure SSH config (if used) points to this new key, for example in ~/.ssh/config:
  3. Test connectivity:
    You should see a message like “Hi <user>! You’ve successfully authenticated…”

4. Remove the Old Deploy Key (Complete the Rotation)

Once you confirm your deployments/CI work with the new key:
  1. In the same repo, go to Settings → Deploy keys.
  2. Find the old deploy key entry.
  3. Click Delete (or the trash icon) next to the old key.
  4. Confirm deletion.

5. (Optional) Enforce Better Practices

  • Use read-only keys unless write is strictly needed.
  • Rotate keys on a regular schedule.
  • Track which system each deploy key belongs to via clear titles.
If you tell me your CI/CD tool (e.g., GitHub Actions, Jenkins, GitLab CI, etc.), I can give the exact steps to plug the new private key into that system.
Here’s how to remediate a “Repo Deployment Keys Rotated” issue by rotating GitHub deploy keys using the GitHub CLI (gh).Assumptions:
  • You have gh installed and authenticated (gh auth login).
  • You have ssh-keygen available.

1. Identify the repo and existing deploy keys

Note the id and title of the key(s) you want to rotate.

2. Generate a new SSH key pair

Files created:
  • Private: ~/.ssh/deploy_key_$OWNER_$REPO
  • Public: ~/.ssh/deploy_key_$OWNER_$REPO.pub

3. Add the new deploy key via GitHub CLI

Verify it was added:

4. Update automation/CI to use the new private key

Wherever the old deploy key was used (CI/CD tool, server, etc.):
  1. Replace the old private key with:
    ~/.ssh/deploy_key_$OWNER_$REPO
  2. Ensure permissions are strict:
  3. Test connectivity:

5. Remove the old deploy key via GitHub CLI

Once the new key is confirmed working:
  1. Get the ID of the old key:
  2. Delete the old key (replace OLD_KEY_ID):
  3. Confirm removal:

6. (Optional) Enforce a rotation practice

  • Document:
    • Key name pattern
    • Rotation interval (e.g., 90 days)
    • Procedure above as standard runbook.
  • If “GitHub IAM” is a scanner/policy engine, re-run it to confirm the misconfiguration is cleared.
Below is a concrete, step‑by‑step way to “remediate” a Repo Deployment Keys Rotated finding for GitHub using Python – i.e., automatically rotate (replace) deploy keys on a repo via the GitHub API.

1. Prerequisites

  1. Personal Access Token (PAT) (or GitHub App token) with:
    • repo scope (for private repos)
    • Or at least public_repo (for public repos)
  2. Python 3.8+ installed.
  3. requests and cryptography (for generating SSH keys):
Set your GitHub token as an environment variable (safer than hard‑coding):

2. High‑Level Rotation Flow

For each affected repository:
  1. Generate a new SSH keypair.
  2. Add the new public key as a deploy key via GitHub API.
  3. Update any systems/CI/CD pipelines that use the private key.
  4. Remove the old deploy key from the repo via GitHub API.

3. Generate a New SSH Keypair in Python


4. Add the New Deploy Key via GitHub API

GitHub API endpoint:
POST /repos/{owner}/{repo}/keys
Important:
Save private_key_pem securely (secret manager, CI/CD secret, etc.) and update any service that uses the old deploy key to now use this new private key.

5. List Existing Deploy Keys (Find Old Key to Remove)

GitHub API endpoint:
GET /repos/{owner}/{repo}/keys
Use this to identify the old key either by title, a known substring in the key, or manually.

6. Remove the Old Deploy Key

GitHub API endpoint:
DELETE /repos/{owner}/{repo}/keys/{key_id}

7. Putting It All Together (Rotation Script)

  1. Generate new keypair.
  2. Add new public key as deploy key.
  3. Update your CI/CD/deployment system with the new private key.
  4. Confirm it can clone/push.
  5. Delete the old deploy key.
You can wrap the above steps into a single script that:
  • Accepts owner, repo, and the old_key_title (or old_key_id) as input.
  • Outputs the new private key so you can inject it into your secrets store.

8. Optional: Automate Regular Rotation

To make this a recurring remediation:
  • Put the rotation script into a secure automation environment (e.g., GitHub Actions, Jenkins, or a separate runner).
  • Store the PAT or GitHub App token in a secret manager.
  • Schedule the job (e.g., run monthly/quarterly).
  • After each run, automatically update the target systems’ SSH private key secrets.

If you share the name pattern of the old keys and how your CI/CD currently stores the private key (GitHub Actions secret, Jenkins credential, etc.), I can tailor the Python script to fully automate the update on that side as well.
Rotating the key is done by generating a new SSH key pair, updating the applications to use the new private key, then removing the old github_repository_deploy_key resource from Terraform so terraform plan shows the old key being destroyed and the new key created.

Additional Reading: