SSH Key & Certificate Manager for GitHub
For individuals and enterprises alike
Whether you're a solo developer managing personal projects or an enterprise team with hundreds of engineers,
cassh brings security best practices to your SSH workflow β without the complexity.
Personal GitHub.com users β no server required:
# 1. Install GitHub CLI (if you haven't)
brew install gh
gh auth login
# 2. Install cassh
brew tap shawntz/cassh
brew install --cask cassh
# 3. Launch cassh β setup wizard opens automatically β done!Enterprise users β see Server Setup for CA and Entra configuration.
You might think: "I already use gh to upload my SSH key β why do I need this?"
The gh CLI is great for the initial setup, but it doesn't manage your keys:
| The Problem | Without cassh | With cassh |
|---|---|---|
| Key lifecycle | Keys live forever until you manually delete them | Automatic rotation (4 hours to 90 days) |
| Laptop lost/stolen | Your key still works until you notice and revoke it | Key auto-expires per your policy |
| Shared/work computer | That SSH key might still be there months later | Set short rotation for shared environments |
| Multiple machines | Different keys everywhere, no central management | Same workflow on every Mac |
| SSH config | Manually edit ~/.ssh/config for each account |
Automatic configuration |
Security isn't just for enterprises. Your personal GitHub account has access to your private repos, your contributions to other projects, and possibly deploy keys. Treat it accordingly.
Permanent SSH keys are a security liability:
| Scenario | With Permanent Keys | With cassh |
|---|---|---|
| Laptop lost | Manual revocation required, often missed | Certificate expires automatically |
| Employee offboarding | Hunt down and revoke all their keys | Certificates expire within hours |
| Compliance audit | "When was this key last rotated?" | Full lifecycle tracking |
| Key compromise | Blast radius until detected | Limited to certificate validity window |
cassh issues 12-hour certificates signed by your internal CA. No revocation lists to manage, no keys to track, no manual intervention needed.
Most developers juggle multiple GitHub accounts β work and personal, or multiple organizations. cassh manages them all from a single menu bar app.
- Enterprise connections use certificates that auto-expire
- Personal connections use keys with configurable rotation
- Each connection gets its own SSH key and config entry
- Status at a glance β green means you're good, yellow means expiring soon, red means action needed
| Feature | Personal | Enterprise |
|---|---|---|
| One-click setup wizard | β | β |
| Automatic SSH config | β | β |
| Per-connection Git identity | β | β |
| Menu bar status indicator | β | β |
| Key/cert rotation | β (configurable) | β (12h default) |
| Multi-account support | β | β |
| Revoke & renew from menu bar | β | β |
| Dotfiles-friendly config | β | β |
| Microsoft Entra SSO | β | β |
| CA-signed certificates | β | β |
| MDM deployment (PKG) | β | β |
Download cassh β Launch β Setup Wizard β Enter GitHub username β Done
Behind the scenes:
- cassh generates an Ed25519 SSH key
- Uploads it to GitHub via
gh ssh-key add - Configures
~/.ssh/configautomatically - Tracks key age and rotates per your policy
- On rotation: deletes old key from GitHub, generates new key, uploads new key
Click menu bar β Generate Certificate β SSO login β Certificate installed
Behind the scenes:
- Opens browser to your cassh server
- Authenticates via Microsoft Entra ID
- Server signs your public key with the CA (includes
login@HOSTNAMEextension) - Certificate returned and installed automatically via
cassh://URL scheme - Certificate expires in 12 hours β repeat as needed
Setup: Just paste any SSH clone URL from your GitHub Enterprise (e.g., user_123@github.company.com:org/repo.git) and cassh extracts the hostname and SCIM-provisioned username automatically.
-
Install prerequisites:
brew install gh gh auth login
-
Install cassh via Homebrew:
brew tap shawntz/cassh brew install --cask cassh
-
Launch β the setup wizard opens automatically
-
Add Personal Account β enter your GitHub username, choose rotation policy
-
Done! β
git cloneyour repos and go
See the Full Documentation for:
- Server Setup β CA keys, Entra app configuration
- Deployment β Fly.io, Render, Railway, VPS
- Client Distribution β MDM deployment with PKG
cassh stores your connections in a simple TOML config file. The config is dotfiles-friendly β store it in ~/.config/cassh/config.toml to back up with your dotfiles.
# ~/.config/cassh/config.toml
[[connections]]
id = "personal-github"
type = "personal"
name = "Personal GitHub"
github_host = "github.com"
github_username = "yourusername"
ssh_key_path = "~/.ssh/cassh_personal_id_ed25519"
key_rotation_hours = 168 # Rotate every 7 days
[[connections]]
id = "enterprise-work"
type = "enterprise"
name = "Work GitHub"
server_url = "https://cassh.yourcompany.com"
github_host = "github.yourcompany.com"
github_username = "user_123" # SCIM-provisioned username from SSH clone URL
ssh_key_path = "~/.ssh/cassh_work_id_ed25519"
ssh_cert_path = "~/.ssh/cassh_work_id_ed25519-cert.pub"Git Identity: cassh can also manage per-connection git identities. When you add a connection, optionally specify your user.name and user.email. cassh uses Git's includeIf to automatically apply the correct identity based on the repo's remote URL. Your work repos use your work email, personal repos use your personal email β automatically.
See the Configuration Reference for all options, or check out config.example.toml for a complete example.
See the full roadmap for details.
| Status | Feature |
|---|---|
| β | GitHub Enterprise SSH certificates |
| β | GitHub.com personal SSH key management |
| β | Automatic key rotation with configurable policies |
| β | Multi-account support (enterprise + personal) |
| β | Setup wizard for first-run configuration |
| β | macOS menu bar app with connection status |
| β | Microsoft Entra ID (Azure AD) SSO |
| π§ | Policy integrity verification |
| π | GitLab support |
| π | Bitbucket support |
| π | Linux support |
Legend: β Complete | π§ In Progress | π Planned
Caution
For Enterprise deployments:
- Protect your CA private key β it can sign certificates for anyone
- Use HTTPS β OAuth tokens are transmitted
- Restrict Entra app β limit which users can authenticate
- Review access logs regularly
Tip
For Personal users:
- Use a short rotation policy (4-24h) on shared or work computers
- Use a longer policy (7-90 days) on personal machines you control
- cassh stores keys in
~/.ssh/with proper permissions (0600)
flowchart LR
subgraph Client
A[Menu Bar App]
end
subgraph Server
B[cassh Server]
C[Internal CA]
end
subgraph External
D[Microsoft Entra ID]
E[GitHub Enterprise]
end
A -->|1. Request cert| B
B -->|2. OIDC auth| D
D -->|3. Identity verified| B
B -->|4. Sign pubkey| C
C -->|5. SSH certificate| B
B -->|6. Return cert| A
A -->|7. SSH with cert| E
flowchart LR
subgraph Client
A[Menu Bar App]
B[gh CLI]
end
subgraph External
C[GitHub.com]
end
A -->|1. Generate SSH key| A
A -->|2. Upload via gh| B
B -->|3. Add to GitHub| C
A -->|4. SSH with key| C
A -.->|5. On rotation: delete old, upload new| B
cassh is built and maintained by Shawn Schwartz, a PhD candidate in Psychology at Stanford. By day, he builds software for cognitive neuroscience research. By night, he builds security tools like this one.
If cassh saved you time or made your workflow more secure:
- Sponsor on GitHub
- Star this repo and share it with others
Every bit of support helps me justify the time spent on this free and open-source side project instead of my dissertation.
Security tooling should be auditable. You shouldn't have to trust a black box with your SSH authentication.
Contributions welcome! Check out CONTRIBUTING.md to get started.
Apache 2.0 β See LICENSE for details. Β© Shawn Schwartz, 2025.