How to Access User Public SSH Keys via GitHub API Endpoints
GitHub exposes every user's public SSH keys through the unauthenticated REST endpoint https://api.github.com/users/{username}/keys (JSON format) and the legacy shortcut https://github.com/{username}.keys (plain text), both accessible without authentication but subject to standard rate limiting.
The tiimgreen/github-cheat-sheet repository documents how to access user public SSH keys via GitHub API endpoints for automation and security auditing. These endpoints expose public key metadata without requiring credentials, making them ideal for verifying user identities or pre-populating authorized_keys files across your infrastructure.
Public SSH Key Endpoints
GitHub maintains two distinct public interfaces for retrieving user SSH keys. Each serves different use cases depending on whether you need structured metadata or just the raw key strings.
JSON REST API Endpoint
The primary method for programmatic access is the official GitHub REST API endpoint:
GET https://api.github.com/users/{username}/keys
This endpoint returns a JSON array where each object contains three fields:
- id – The unique identifier for the key
- key – The actual public SSH key string (e.g.,
ssh-rsa AAAAB3...) - title – The descriptive label assigned by the user
This structured format allows you to parse metadata and distinguish between multiple keys registered to the same account.
Legacy Plain-Text Shortcut
For simple shell scripts or quick manual checks, GitHub provides a legacy URL pattern documented in the cheat sheet's README.md:
https://github.com/{username}.keys
This returns a plain-text list with one SSH key per line, omitting the id and title metadata. While easier to pipe into authorized_keys files, this format provides no programmatic way to identify which key corresponds to which device.
Rate Limits and Authentication
Because these endpoints expose public data, no Authorization header is required for basic access. However, unauthenticated requests are subject to GitHub's standard rate limit of 60 requests per hour per IP address.
To obtain a higher request quota, include a personal access token in the request header:
curl -H "Authorization: token YOUR_TOKEN" \
https://api.github.com/users/tiimgreen/keys
Authenticated requests also provide more detailed logging in GitHub's API monitoring tools.
Practical Implementation Examples
The following implementations demonstrate how to fetch and process public SSH keys using common tools and programming languages.
Fetching Keys with curl
Retrieve plain-text keys for quick scripting:
curl https://github.com/tiimgreen.keys
Fetch structured JSON with metadata:
curl https://api.github.com/users/tiimgreen/keys
Parsing JSON in Python
When you need to process key metadata programmatically, Python's requests library handles the JSON parsing efficiently:
import requests
username = "tiimgreen"
url = f"https://api.github.com/users/{username}/keys"
resp = requests.get(url)
resp.raise_for_status()
keys = resp.json()
for key in keys:
print(f"{key['title']}: {key['key']}")
This script extracts the title and key fields, allowing you to filter by device name or validate specific key fingerprints.
Using the GitHub CLI
The official gh command-line tool provides a concise interface for API queries:
gh api /users/tiimgreen/keys
This automatically handles authentication if you've run gh auth login, and formats the JSON output with syntax highlighting.
Source Documentation
According to the tiimgreen/github-cheat-sheet source code, the plain-text shortcut (https://github.com/{user}.keys) is documented in the "SSH keys" section of README.md. While the cheat sheet highlights the legacy shortcut for quick command-line usage, the official REST API endpoint (/users/:username/keys) provides the richer, structured data preferred for automation and integrations.
Summary
- Two endpoints exist: The JSON API (
api.github.com/users/{username}/keys) provides structured data with metadata, while the legacy shortcut (github.com/{username}.keys) offers plain-text output. - No authentication required: Both endpoints work without tokens, though authentication increases rate limits significantly.
- Response format differs: The API returns an array of objects with
id,key, andtitle; the shortcut returns only the key strings. - Documented in README.md: The tiimgreen/github-cheat-sheet repository tracks these methods in its SSH keys documentation section.
Frequently Asked Questions
Do I need a personal access token to fetch public SSH keys?
No. Because SSH keys are public profile data, both the api.github.com endpoint and the .keys shortcut work without authentication. However, adding a token in the Authorization header increases your rate limit from 60 requests to a significantly higher quota per hour and helps avoid IP-based blocking during bulk operations.
What is the difference between the .keys shortcut and the API endpoint?
The .keys shortcut returns only the raw SSH key strings in plain text, making it ideal for piping directly into ~/.ssh/authorized_keys files. The API endpoint returns JSON containing the id, key, and title fields, which allows you to identify specific devices and manage keys programmatically using the key's unique identifier.
How do I handle rate limits when fetching multiple user keys?
If you need to fetch keys for hundreds of users, authenticate your requests using a GitHub personal access token or GitHub App installation token. This raises the limit from 60 requests per hour to a much higher threshold. Implement exponential backoff for 403 responses, and consider caching results since public SSH keys change infrequently.
Can I access my own private keys through these endpoints?
No. These endpoints only expose public SSH keys that you have added to your GitHub account for authentication purposes. Private keys never leave your local machine, and GitHub has no API endpoint for retrieving private key material.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →