Managed SSH Public Keys
Register the public keys for the computers and security keys you use to connect directly to Morph Cloud instances. Each key is named and belongs to your user account, so you can add a new key before retiring an old one.
Understand key scope
A managed SSH public key is owned by one user. While it is active, Morph authorizes it for direct public-key SSH to:
- instances you own; and
- instances in every organization where you are currently a member.
The key is not attached to a particular organization or instance. Joining or leaving an organization changes its effective organization access; it does not transfer ownership of the key. Revoking a key stops future direct public-key authentication with that key across this entire scope.
Other access methods use separate credentials:
| Credential or access method | What it is | What revokes it |
|---|---|---|
| Managed SSH public key | A user-owned public key stored in account settings for direct SSH | Revoke that named key in account settings |
| Generated instance credentials | A Morph-generated private/public key pair and password for one instance | Rotate that instance's credentials |
| Instance access bundle | A copy of generated instance credentials handed to a recipient | Rotate that instance's credentials and destroy copies of the bundle |
| Browser terminal | A managed in-console connection | Governed separately from managed SSH public keys |
Revoking a managed public key does not rotate generated instance credentials, invalidate an instance access bundle, or close a browser terminal session. See Generated instance SSH credentials and Share SSH access for those flows.
Generate a key pair
Ed25519 is the recommended key type for new keys. Use a distinct filename so you do not overwrite another identity.
- macOS/Linux
- Windows PowerShell
ssh-keygen -t ed25519 -a 100 \
-f ~/.ssh/morph_personal \
-C "morph-personal"
ssh-keygen -t ed25519 -a 100 `
-f "$HOME/.ssh/morph_personal" `
-C "morph-personal"
Choose a strong passphrase when prompted. The passphrase protects the private key on your computer; Morph does not receive it.
This creates two files:
~/.ssh/morph_personal: the private key. Keep it secret.~/.ssh/morph_personal.pub: the public key. This is the only file you add to Morph.
Display the public key before continuing:
cat ~/.ssh/morph_personal.pub
The output must be a single OpenSSH public-key record, optionally followed by a comment. Morph accepts:
ssh-ed25519(recommended);ecdsa-sha2-nistp256,ecdsa-sha2-nistp384, andecdsa-sha2-nistp521;ssh-rsawith a key size of at least 3072 bits; and- hardware-backed
sk-ssh-ed25519@openssh.comandsk-ecdsa-sha2-nistp256@openssh.comkeys.
Morph rejects DSA, SSH certificates, RSA keys smaller than 3072 bits, authorized_keys options, private-key material, and inputs containing more than one key record.
Add and verify a key
- Open Account settings → SSH public keys.
- Select Add public key.
- Give the key a name that identifies its device or purpose, such as
Personal laptop. - Paste the complete contents of
morph_personal.pub. - Optionally choose an expiry. An expired key remains in your inventory but is no longer authorized.
- Review the displayed access scope, then add the key.
Morph parses the public key and displays its algorithm and OpenSSH-compatible SHA256 fingerprint. Verify that fingerprint against the local public-key file:
ssh-keygen -lf ~/.ssh/morph_personal.pub -E sha256
Compare the complete SHA256:... value, not only its first or last characters. A mismatch means you pasted a different key; revoke it and add the intended public key.
Verify direct SSH access
Use the instance ID as the SSH user. IdentitiesOnly=yes prevents your agent from offering unrelated keys before the intended key:
ssh -o IdentitiesOnly=yes \
-i ~/.ssh/morph_personal \
morphvm_abc123@ssh.cloud.morph.so
On the first connection, SSH asks whether to trust the Morph SSH gateway host key. Verify the host-key fingerprint through a trusted Morph channel before accepting it. If SSH reports that the host key changed unexpectedly, stop and contact Morph support; do not bypass the warning with StrictHostKeyChecking=no.
Read lifecycle information
Account settings shows each key's name, fingerprint, algorithm, created and updated times, optional expiry, last-used time, and status:
- Active: eligible for direct public-key SSH within the user's current access scope.
- Expired: past its configured expiry and no longer authorized.
- Revoked: explicitly revoked and no longer authorized.
- Migration warning: imported from the previous single-key setting, but could not be fully normalized. Only these migrated warning rows can show an
unknownor unsupported algorithm and alegacy:<md5>fingerprint; validated new uploads always use an allowlisted algorithm and an OpenSSHSHA256:...fingerprint. Add and test a replacement key, then revoke the migrated entry.
Last used is evidence that Morph recently accepted the key; it is not a complete audit log and may update asynchronously.
Manage keys with the CLI
The CLI accepts a .pub file directly, which avoids copying private material or a truncated key into a shell argument:
morphcloud user ssh-key add \
--name "Personal laptop" \
--public-key-file ~/.ssh/morph_personal.pub \
--expires 2027-01-01T00:00:00Z
--expires accepts Unix seconds or an ISO 8601 datetime. A datetime without a timezone is interpreted as UTC.
List keys and inspect one stable key ID:
morphcloud user ssh-key list
morphcloud user ssh-key get usk_abc123
Names and expiry are editable, but the public-key material is immutable. Add a new key when the key material changes.
morphcloud user ssh-key edit usk_abc123 --name "Backup laptop"
morphcloud user ssh-key edit usk_abc123 --clear-expiry
Revoke one key by ID. The CLI asks for confirmation that shows its effective direct-SSH scope:
morphcloud user ssh-key revoke usk_abc123
Use --json with list, get, add, or edit for structured output. The older get command without an ID and the set/update aliases operate on the deprecated singular compatibility key; new automation should use the targeted managed-key commands above.
Manage keys through the API
The plural API manages the same user-owned inventory shown in account settings:
| Method | Path | Result |
|---|---|---|
GET | /api/user/ssh-keys | List your managed SSH public keys |
POST | /api/user/ssh-keys | Create a named key (201 Created) |
GET | /api/user/ssh-keys/{id} | Get one key you own |
PATCH | /api/user/ssh-keys/{id} | Change its name or optional expiry |
DELETE | /api/user/ssh-keys/{id} | Revoke that key (204 No Content) |
Items include a stable ID, name, public key, algorithm, OpenSSH SHA256 fingerprint, lifecycle timestamps, derived status, and legacy-migration information. expires is Unix seconds or null. See the REST API reference for request schemas, examples, and structured errors.
Organization owners and admins can audit member key metadata with GET /api/orgs/{org_id}/ssh-keys. This view does not change ownership: each key remains attached to its user, and current organization membership determines its effective organization access.
The singular GET and PUT /api/user/ssh-key operations remain available for older clients but are deprecated. New integrations should use the plural routes so they can target a specific key without replacing a user's compatibility key.
The complete machine-readable contract is available as the OpenAPI JSON specification.
Rotate without losing access
Use an overlap rotation instead of replacing a working key in one step:
- Generate a new key pair with a new filename.
- Add the new public key under a distinct name.
- Verify its SHA256 fingerprint.
- Connect directly with the new private key and
IdentitiesOnly=yes. - Revoke the old managed public key.
- Delete the old private key from devices where it is no longer needed.
Revocation affects future authentication; it does not terminate an SSH connection that is already established. Close existing sessions when responding to a compromise.
Revoke a key
Select Revoke on the exact named key and confirm its name and fingerprint. Revocation is targeted and cannot be undone. It does not revoke another user's keys or any Morph-generated instance credentials.
If a device or private key is lost, revoke its matching public key immediately. If you cannot identify the correct row, compare the remaining local .pub files with their displayed SHA256 fingerprints.
Troubleshooting
Permission denied (publickey)
-
Confirm that the instance ID in
morphvm_abc123@ssh.cloud.morph.sois correct. -
Confirm the key is Active, has not expired, and is within your current organization membership scope.
-
Compare the local public-key fingerprint with the fingerprint in account settings:
ssh-keygen -lf ~/.ssh/morph_personal.pub -E sha256 -
Force SSH to offer the matching private key:
ssh -vvv -o IdentitiesOnly=yes \
-i ~/.ssh/morph_personal \
morphvm_abc123@ssh.cloud.morph.soIn the debug output, look for
Offering public keyand avoid sharing output that contains sensitive local paths or environment details.
SSH offers the wrong agent key
List loaded identities with ssh-add -l, or keep using IdentitiesOnly=yes with an explicit -i path. Do not fix an agent mismatch by uploading every public key on your computer.
The private key and .pub file might not match
Derive the public key from the private key and print its fingerprint without uploading anything:
ssh-keygen -y -f ~/.ssh/morph_personal | ssh-keygen -lf - -E sha256
The result must match the fingerprint in account settings. If the private key is passphrase-protected, ssh-keygen prompts locally for the passphrase.
Morph rejects the pasted value
Paste exactly one line from a .pub file. Private-key blocks beginning with -----BEGIN ... PRIVATE KEY-----, SSH certificates, malformed base64, multiple keys, and unsupported algorithms are rejected. Do not remove or edit the encoded key body.