How to Send SSH Keys Safely to a New Employee or Contractor
The first time I had to onboard a remote contractor in 2018, I asked my senior engineer how to send the SSH private key. He said, "just paste it in Slack and tell them to delete it." I knew that was wrong. I also didn't know what was right. So I did what he said, and the key sat in our Slack workspace's data export for the next five years.
Sending SSH private keys is one of the most common credential transfers engineering teams perform โ onboarding new hires, granting contractor access to staging servers, distributing deploy keys for CI/CD systems. It's also one of the most consistently fumbled. This article covers what you actually need to know to send SSH keys safely without creating an audit trail you'll regret.
Why SSH keys deserve more care than other credentials
A leaked password is bad. A leaked SSH private key is often worse:
- Long lifetime by default. Passwords get rotated quarterly. SSH keys often live unrotated for years.
- Wide blast radius. A single key may unlock many servers, repositories, and CI runners.
- Hard to detect compromise. SSH access often doesn't trigger the same alerting as failed logins do.
- Frequently shared without thought. Many teams treat keys like API tokens โ copy-paste them around.
If you're going to share an SSH private key with a new employee or contractor, the channel and the rotation policy both need to be deliberate.
The two-key pattern: don't send the original
Before discussing the channel, the most important rule: never send the original key. Generate a new keypair specifically for the recipient.
ssh-keygen -t ed25519 -C "jane@contractor.example" -f ~/.ssh/contractor_jane
This produces contractor_jane (private) and contractor_jane.pub (public). You add the public key to whatever servers Jane needs access to:
# On the server
echo "ssh-ed25519 AAAA... jane@contractor.example" >> ~/.ssh/authorized_keys
Then you send Jane the private key. When she leaves, you remove that one line from authorized_keys and her access is gone. No mass rotation, no impact on other team members.
Ed25519 keys are the right default in 2026 โ shorter, faster, and more resistant to common implementation mistakes than RSA.
Why email and Slack are wrong for SSH keys
A typical Ed25519 private key is ~400 characters. It's small enough to paste anywhere โ which is exactly the problem.
Email keeps the key in the recipient's inbox forever, in your sent folder forever, and on at least three SMTP servers' disks for the lifetime of those servers' retention policies.
Slack keeps the key in indexes, integrations, push notifications, and the workspace export. Even after deletion.
Google Drive / Dropbox create unencrypted copies on their servers and the recipient's local sync folder. They show up in version history, "recently viewed," and shared link audit logs.
SMS / WhatsApp seem ephemeral but get backed up to iCloud and Google Drive in plaintext.
The common failure pattern: you send the key once, the recipient adds it to their ~/.ssh/, and assumes the source channel doesn't matter anymore. But the source channel is exactly where the next breach starts โ six months from now when one of those services is compromised.
What "safe enough" looks like for SSH key transfer
The channel needs to satisfy:
- End-to-end encrypted โ the relay service can't read the key.
- One-time read โ the link is destroyed after the recipient retrieves the key.
- Hard expiry โ even unread, the link expires.
- No long-lived copy on either end โ the channel doesn't persist the message in archives, search indexes, or backups.
- Recipient-friendly โ no account required, no install, just click and copy.
The simplest path that satisfies all five is a self-destructing share link.
A real onboarding flow
Here's how I onboard a new contractor today:
# 1. Generate a contractor-specific keypair
ssh-keygen -t ed25519 -C "contractor_jane_2026q4" -f ~/.ssh/contractor_jane
# 2. Add the public key to the relevant servers
ssh ops@bastion "echo '$(cat ~/.ssh/contractor_jane.pub)' >> ~/.ssh/authorized_keys"
# 3. Read the private key into a self-destructing share
cat ~/.ssh/contractor_jane | wl-copy
# (or pbcopy on macOS, xclip on Linux)
I open snapsend.site, paste the private key into a Text Share, set expiry to 1 hour, password-lock it for an extra layer.
I send Jane the link via Slack with the password sent through a different channel (SMS or a phone call). She clicks once, the key is decrypted in her browser, the link is destroyed.
She saves the key:
# In Jane's terminal
mkdir -p ~/.ssh && chmod 700 ~/.ssh
nano ~/.ssh/contractor_jane # paste the key
chmod 600 ~/.ssh/contractor_jane
She tests:
ssh -i ~/.ssh/contractor_jane ops@bastion
Total time: under five minutes. Total persistent copies of the private key: one (Jane's ~/.ssh/).
Rotation and revocation
The advantage of contractor-specific keys is that revocation is trivial. When Jane's engagement ends:
# On every server she had access to
ssh ops@bastion "sed -i '/contractor_jane_2026q4/d' ~/.ssh/authorized_keys"
That single line removes her access. Other team members are unaffected. No mass rotation, no Slack-thread coordination.
For permanent employees, the same pattern applies โ generate a per-user keypair, add the public key to the servers they need, send the private key via a self-destructing channel. When they leave, you have one authorized_keys line per server to remove.
The role of password managers and bastion hosts
This article is about the transfer of an SSH key. For storage and operational use, your team should also have:
- A password manager that supports SSH key storage โ 1Password and Bitwarden both have SSH agent integration so users can keep the key encrypted at rest and use it without copying it around.
- A bastion or jump host โ direct SSH access to production from individual workstations is rarely the right pattern. Route through a bastion that logs all sessions.
- Short-lived certificates instead of long-lived keys โ Teleport, Hashicorp Vault SSH, or Step CA can issue SSH certificates that expire in hours instead of years. This is the gold standard for production access.
For one-off transfers and bootstrap, though, a self-destructing share link is the right tool.
Where SnapSend fits in
SnapSend is what I use for the share-link step. The encryption key lives in the URL fragment, so the SnapSend backend can't decrypt the SSH key even if compelled. The link self-destructs on first read or at the expiry you set. The recipient doesn't need an account โ they click, see the key, copy it into ~/.ssh/, and the link is incinerated.
For SSH keys specifically, I add a passphrase lock on the SnapSend share, send the link via one channel (Slack), and the passphrase via another (SMS). That's two-channel verification with no persistent copy of the key in either channel.
Stop pasting SSH keys into chat
The cost of doing this right is five minutes per onboarding. The cost of doing it wrong is the next breach disclosure mentioning your company by name.
Try SnapSend free at snapsend.site โ no account needed.