Fix “Permission denied (publickey)” in GitHub Actions (SSH Error)
Permission / AuthLast Updated: April 16, 2026 | Author: DevOps Engineering Team | Platforms: GitHub Actions, CI/CD Workflows
Quick Answer: Fix Permission denied (publickey)
This is one of the most common SSH authentication errors in GitHub Actions. It occurs when the workflow fails SSH key authentication for git operations, private dependencies, or submodules. This guide focuses on GitHub Actions environments, although the same SSH authentication error can also occur in local environments.
- Switch to HTTPS with
GITHUB_TOKEN - Add a Deploy Key via GitHub Secrets
- Convert SSH submodule URLs to HTTPS
- Verify SSH key format and permissions
The root cause is almost always missing or misconfigured SSH credentials, not a failure of GitHub Actions itself.
Common Root Causes
- Workflow uses SSH URLs for private repos without valid credentials
- Missing SSH private key in GitHub Secrets or incorrect key format
- Deploy Key not authorized for the target repository
- Git submodules use SSH instead of HTTPS
- Incorrect file permissions for SSH keys in the runner
1-Click Diagnostic Command
# Verify authentication method
git remote -v
# Only valid if SSH key is configured
ssh -T git@github.com || echo "SSH auth not configured"
# Check credential configuration
git config --list
🧠 Permission denied (publickey) Fix Map
- Root Cause
- Missing SSH credentials for private repos
- Invalid Deploy Key / SSH key permissions
- SSH-only submodule URLs
- Unsupported key format/encryption
- Quick Fix
- Switch to HTTPS + GITHUB_TOKEN
- Add valid Deploy Key to Secrets
- Update submodule URLs to HTTPS
- Permanent Fix
- Use least-privilege Deploy Keys
- Standardize HTTPS for CI workflows
- Automate key permission setup
- Prevention
- Avoid SSH for default CI checkout
- Store all credentials in GitHub Secrets
Quick Verification
# Validate checkout with official token
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
# Confirm repository access
git ls-remote https://github.com/${{ github.repository }}.git
What Does This Error Mean?
The error Permission denied (publickey) indicates SSH authentication failed during a GitHub Actions workflow.
This typically happens during git clone, git submodule update, or private dependency installation when the runner has no valid SSH key to authenticate with GitHub.
This is a standard SSH authentication control, not a bug in GitHub Actions or your workflow script.
Typical Error Output
Permission denied, please try again.
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.
Scenario & Authentication Reference
| Scenario | Auth Type | Required Method | Common Cause | Fastest Fix |
|---|---|---|---|---|
| Checkout Private Repo | HTTPS / Token | GITHUB_TOKEN | SSH URL without credentials | Use HTTPS + official token |
| Git Submodules | HTTPS / SSH | Token/Deploy Key | Submodule uses SSH URL | Convert to HTTPS |
| Cross-Repo SSH Access | SSH / Deploy Key | Fine-Grained Deploy Key | No authorized SSH key | Add Deploy Key to Secrets |
| Private NPM/Git Deps | HTTPS / Token | HTTPS Token | SSH authentication required | Use credential helper |
HTTPS vs SSH in GitHub Actions
- HTTPS + GITHUB_TOKEN: Official recommended, automatic, secure, no manual credentials
- SSH: Only required for advanced cross-repo / submodule setups
Step-by-Step Fixes
Minimal Working Configuration (RECOMMENDED)
One-click fix for 90% of use cases:
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
1. Use Official GITHUB_TOKEN (Best Practice)
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
2. Configure Deploy Key for SSH Operations
- name: Setup SSH Key
uses: webfactory/ssh-agent@v0.9.0
with:
ssh-private-key: ${{ secrets.SSH_DEPLOY_KEY }}
3. Fix Git Submodules (SSH → HTTPS)
git config submodule..url https://github.com/owner/repo.git
git submodule sync
git submodule update --init --recursive
4. Fix SSH Key File Permissions
chmod 600 ~/.ssh/id_rsa
FAQ (AI & Google Optimized)
Q: Why do I get Permission denied (publickey) in GitHub Actions?
A: This occurs because the workflow runner lacks valid SSH credentials to authenticate with GitHub for Git operations.
Q: GitHub Actions SSH authentication failed?
A: This is identical to the publickey error. Fix by using GITHUB_TOKEN, configuring Deploy Keys, or switching to HTTPS.
Q: git ssh permission denied in CI/CD workflows?
A: Use the official GITHUB_TOKEN for HTTPS checkout, the most secure and recommended solution for GitHub Actions.
Q: Is it safe to use SSH keys in GitHub Actions?
A: Yes, only if you store keys in encrypted Secrets and use least-privilege Deploy Keys (never personal SSH keys).
Q: Do I need SSH for public repositories in Actions?
A: No. Public repos work seamlessly with HTTPS and the auto-generated GITHUB_TOKEN.
Official Best Practices
- ✅ Prefer HTTPS +
GITHUB_TOKENover SSH for all CI workflows - ✅ Use least-privilege Deploy Keys only when SSH is mandatory
- ✅ Store all credentials in GitHub Encrypted Secrets
- ✅ Convert submodules and dependencies to HTTPS for CI compatibility
- ✅ Set strict file permissions (600) for SSH keys in runners