Join our Newsletter — 33% off our NHI Course
Home› Guides› Private Keys in Repositories Guide: Finding, Revoking and…
Guide Secrets Management

Private Keys in Repositories Guide: Finding, Revoking and Preventing Leaked PEM, PKCS12 and SSH Keys

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 27 October 2026 12 min read
On this page

A private key committed to a repository is a machine identity handed to everyone who can clone it, and unlike an API key no provider will revoke it for you. PEM files, PKCS #12 bundles, OpenSSH keys and signing keys end up in Git through test fixtures, deployment scripts, Docker contexts and "temporary" commits, and they stay in history long after the file is deleted. Private key rules are among the highest volume findings in secret scanners, and each one needs a decision: what the key unlocks, whether it is encrypted, who must revoke it and whether history should be rewritten. This guide explains the key formats and what they identify, who holds privileged access to them, how scanners detect them and where they miss, how to respond and how to stop keys reaching repositories. It is written for application security, platform and PKI teams. It goes deeper than the Git Secret Scanning Guide on this one credential type.

Key takeaways

  • Revoke first, rewrite second. GitHub's own guidance is that rotating or revoking the secret is the first step and may be enough; rewriting history has costs and never reaches existing clones and forks.
  • Nobody revokes generic private keys for you. GitHub's generic patterns (rsa_private_key, ec_private_key, openssh_private_key, pgp_private_key, generic_private_key) have no partner notification and no validity check, so the owning team must act.
  • Encrypted is not safe. A passphrase-protected PEM, an OpenSSH key with a bcrypt KDF or a password-protected PKCS #12 file can be attacked offline indefinitely; treat it as exposed.
  • The key type decides the response. A TLS key needs certificate revocation and reissue, an SSH key needs removal from every authorized_keys and forge account, a signing key may require re-signing releases.
  • Prevention is generation in the right place. Keys created inside an HSM, KMS, SSH certificate authority or CI secret store never exist as files a developer can commit.

How private keys work as identities in repositories

A private key proves possession of an identity: a server name in a certificate, an SSH user or deploy key, a signing identity for code or packages, a token issuer, or a cloud service account. Finding one in Git therefore starts with identifying the format and then the identity bound to it.

FormatHow it looks in a repositoryTypical identityCan be encrypted
PKCS #8 (RFC 5208, RFC 5958)PEM label PRIVATE KEY, or ENCRYPTED PRIVATE KEYTLS server or client keys, JWT signing keys, cloud keysYes (EncryptedPrivateKeyInfo)
PKCS #1 RSALegacy PEM label RSA PRIVATE KEYOlder TLS and application keysYes, via legacy PEM encryption headers
SEC1 elliptic curveLegacy PEM label EC PRIVATE KEYTLS, device and signing keysYes, legacy headers
OpenSSH (openssh-key-v1)PEM-style label OPENSSH PRIVATE KEY, often named id_ed25519 or id_rsaSSH user, deploy and automation keysYes: cipher plus bcrypt KDF with salt and rounds
OpenPGPPGP PRIVATE KEY BLOCKRelease signing, package repository signing, emailYes (passphrase)
PKCS #12Binary .p12 or .pfx fileCode signing and client certificates with chainYes (password)
Embedded keysA PEM string inside JSON, YAML or code, such as a service account key file's private_key fieldCloud service accounts, OAuth client assertionsUsually not

RFC 7468 defines the standard textual labels (PRIVATE KEY for PKCS #8 and ENCRYPTED PRIVATE KEY); the RSA PRIVATE KEY and EC PRIVATE KEY labels are older formats that remain common in the wild. The OpenSSH format is described in OpenSSH's PROTOCOL.key: a header naming the cipher and KDF, the public keys, then the private keys, which may be stored with cipher none. Matching the public half is how you identify the key: derive the public key or fingerprint and search certificate inventories, Certificate Transparency logs, authorized_keys files and forge accounts for it. See the Machine Identity, PKI and Certificate Lifecycle Guide for inventory approaches.

Admin roles and privileged access

Two groups hold privileged access in this problem: people who can read the repository and its history, and people who can revoke the identity the key represents. They are rarely the same people.

Key foundWho can revokeRevocation actionBlast radius if missed
TLS server keyPKI or certificate ownerRevoke certificate with the CA, generate a new key, reissueImpersonation of the service, interception where traffic can be redirected
SSH user or automation keySystem owners, identity teamRemove the public key from all authorized_keys, bastions and forge accountsLateral movement wherever the key is trusted
Forge deploy keyRepository adminsDelete the deploy key, create a new one with read-only access where possibleRead or write access to the repository
Code or package signing keyRelease engineering, CARevoke the certificate or PGP key, re-sign current releases, publish the revocationMalware signed as your organisation
JWT or SAML signing keyApplication or IdP ownersRotate the key, remove the old key from JWKS or metadata, invalidate sessionsForged tokens for every user
Cloud service account keyCloud platform teamDelete the key in the cloud console or APIEverything the service account can reach
  • Repository readers are key holders: every collaborator, CI system, fork owner and mirror holds a copy. A private repository narrows that group but does not make the key secret.
  • Machine accounts with broad read access are a concentrated risk: in the GitHub code signing certificate theft a token for a machine account was used to clone repositories that held encrypted, password-protected code signing certificates, and GitHub revoked the certificates anyway.
  • Name a revoking owner in advance: for each key class, record which team revokes and how fast, so a scanner alert is not left with the developer who committed it.

Integrations, API tokens and service accounts

Most keys reach repositories because an integration needed one and generating it locally was the quickest path. Replace each pattern with a design where the key never exists as a file in a working tree.

Why the key was committedBetter patternRelated guide
CI deploys over SSHShort-lived SSH certificates issued per job, or OIDC federation to the targetSSH Protocol and Certificate Authority Guide
Application signs JWTsSigning in a KMS or HSM, with the application calling a sign APIJWT Security Guide
TLS for a service or test environmentAutomated issuance at deploy time (ACME or an internal CA), test keys generated during the test runACME and Automated Certificate Management Guide
Release signing in a pipelineSigning service or HSM-backed key, or keyless signing tied to the workload identityCode Signing Security Guide
Cloud service account key fileWorkload identity federation; disable key creation by policyGoogle Cloud Service Account Keys Security Guide
Encrypted secrets file with its key alongsideKeep the decryption key in a KMS or secret manager, never in the same repositoryCryptographic Key Management Guide

Test fixtures are the most common legitimate-looking source. Keys generated only for unit tests are still keys: if a test key is ever reused in a real environment, or trusted by a staging system, it is a real credential. Generate them at test time, or mark committed fixtures clearly and allowlist them by path in the scanner so real findings stand out. The Zeabur second breach is a reminder that long-lived credentials kept in plaintext in a configuration repository can survive a rotation exercise unnoticed.

Logging and detection

ScannerRule or typeWhat it matchesLimits
GitHub secret scanningrsa_private_key, ec_private_key, openssh_private_key, pgp_private_key, generic_private_keyPEM-style headers for each format; rated high precisionGeneric patterns: no default push protection (configurable), no partner notification, no validity check, no base64 support
GitHub secret scanninggithub_ssh_private_keySSH private keys that authenticate to GitHubProvider pattern with push protection and validity check
Gitleaksprivate-keyAny -----BEGIN ... PRIVATE KEY----- or PRIVATE KEY BLOCK with at least 64 characters of bodyMisses keys with headers stripped or split across strings
Gitleakspkcs12-fileFiles named *.p12 or *.pfx (path rule)Binary keystores under other names, such as .jks, need custom rules
Gitleaksage-secret-keyAGE-SECRET-KEY-1 keys for the age encryption toolFormat specific
  • Turn on push protection for generic patterns: GitHub lets you configure push protection for generic patterns; private key headers have few false positives, so they are good candidates. See the Push Protection Guide.
  • Scan beyond Git: container image layers, build artefacts, wiki attachments and backups of repositories hold the same files.
  • Watch use, not only presence: after a finding, look for authentication with the matching SSH public key in server logs, new certificates or signatures using the key, and cloud API calls by the service account. ATT&CK tracks this as T1552.004 Private Keys, with follow-on use such as T1021.004 SSH and T1553.002 Code Signing.

Metrics: private key findings per month by key class; median time from finding to revocation (not to file deletion); share of findings where the identity was confirmed; number of repositories with push protection on generic key patterns; share of signing and SSH automation keys held in HSM, KMS or CA-issued short-lived form.

Hardening baseline

  1. Baseline scan: scan all repositories, including full history, archived repositories and forks you control, for private key headers and keystore files. Expect a long tail of old findings.
  2. Triage by identity: for each key derive the public key or fingerprint, find what trusts it and assign a revoking owner. Test fixtures that nothing trusts can be allowlisted by path.
  3. Revoke and replace: revoke certificates, remove SSH keys, delete deploy and service account keys, rotate signing keys. Deploy and test the replacement before revoking where the service allows it, so revocation does not cause an outage; if something breaks, roll forward with another new key, never back to the leaked one.
  4. Decide on history rewrite: rewrite only when rotation is impossible or the key protects data that stays sensitive (for example decryption keys for archived data). Follow GitHub's process: git-filter-repo 2.47 or later with --sensitive-data-removal, a forced mirror push, a support request to purge cached views and pull request references, and collaborators rebasing rather than merging.
  5. Prevent recurrence: push protection for generic key patterns, pre-commit hooks, .gitignore entries for *.pem, *.key, *.p12, *.pfx and id_*, and organisation policy disabling cloud key file creation.
  6. Move key generation: issue SSH certificates and TLS certificates from automated authorities, and hold signing keys in HSM or KMS.

Small teams should focus on steps 1, 3 and 5. Larger organisations need a key-class runbook with named revoking owners and service levels, plus central reporting on findings to revocation time.

Leak response

  1. Identify the format and the identity, and whether the key is encrypted. Treat encrypted keys as exposed.
  2. Revoke or remove trust using the action for that key class; record the time.
  3. Search logs for use of the key since the earliest commit date, not just since detection.
  4. Remove the file from the default branch and decide on history rewrite; if forks exist, contact their owners.
  5. Record root cause and the preventive control added. The Secrets Rotation Runbook Template provides the evidence fields.

Framework mapping

Control areaNIST SP 800-53 Rev 5NIST CSF 2.0ISO/IEC 27001:2022 Annex AMITRE ATT&CK
Key generation, storage and destructionSC-12 Cryptographic Key Establishment and ManagementPR.DS-01A.8.24 Use of cryptographyT1552.004 Private Keys
No keys embedded in codeIA-5(7) No Embedded Unencrypted Static AuthenticatorsPR.AA-01A.8.4 Access to source codeT1552.001 Credentials In Files
Public key authentication and certificatesIA-5(2) Public Key-based Authentication, SC-17PR.AA-01A.5.17 Authentication informationT1649 Steal or Forge Authentication Certificates
SSH trust and signing keysAC-6, CM-3PR.AA-05A.8.2 Privileged access rightsT1098.004 SSH Authorized Keys, T1553.002 Code Signing
Detection and responseSI-4, AU-6DE.CM-09, RS.MI-02A.8.16 Monitoring activitiesT1021.004 SSH

Common misconfigurations

  • Deleting the file and closing the alert: the key is still in history, clones and forks, and still trusted.
  • Rewriting history before revoking: it delays the one action that ends the exposure and alerts anyone with a clone to look at the removed data.
  • "It was encrypted": passphrases on committed keys are often weak or sit in the same repository or CI configuration.
  • Test keys trusted by real systems: a fixture key added to a staging authorized_keys or trust store becomes a production credential.
  • Keystores the scanner cannot see: binary .jks or renamed PKCS #12 files pass text-based rules.
  • Signing keys on developer laptops: they are committed, backed up and synchronised; signing belongs in an HSM or signing service.

Practitioner checklist

  • Scan all repository history, images and artefacts for private key headers and keystore files.
  • Enable push protection for GitHub generic private key patterns and add pre-commit scanning.
  • Maintain a key-class runbook naming the revoking owner and the revocation action for each class.
  • Measure time from finding to revocation, not to file deletion.
  • Treat encrypted keys and keystores as exposed.
  • Rewrite history only when rotation cannot mitigate, following the git-filter-repo sensitive data process.
  • Replace SSH key files in automation with short-lived certificates or federation.
  • Move code, package and token signing keys into HSM, KMS or a signing service.
  • Disable cloud service account key creation where federation is available.

Standards and references

Related NHI Mgmt Group resources: Git Secret Scanning Guide · SSH Key Management Guide · Cryptographic Key Management Guide · Secrets Management Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 27 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org