Krab logoKrab
Application

Sshwifty Plus

Establish SSH connections through the browser with automatically managed SSH keys. Self-host on Cloudflare Workers without running a server.

Repository: https://github.com/krab-lab/sshwifty-plus


Using a service deployed by someone else is not recommended, unless you can completely trust that person. Anyone who retains the SSHWIFTY_KEY_ENCRYPTION_SECRET can decrypt the database at any time and obtain your server addresses and SSH private keys. Deploy the service yourself and protect it with appropriate Zero Trust access controls.

Feature Changes

The following changes have been made on top of the upstream Sshwifty project.

Workers and Static Assets

  • A Cloudflare Worker hosts the static UI and handles /sshwifty/socket WebSocket SSH traffic.
  • Only SSH is supported. Telnet, server hooks, SOCKS5, and server-side file:// private-key loading are not available.
  • The SSH client uses ssh2 with an algorithm set compatible with Cloudflare Workers.

GitHub Sign-In and Account Keys

GitHub OAuth is required when SSHWIFTY_AUTH_MODE is set to github.

  • Each GitHub account receives an Ed25519 key pair and an RSA 4096-bit key pair on first sign-in.
  • Users can view and copy public keys from the account window.
  • Private keys are encrypted with SSHWIFTY_KEY_ENCRYPTION_SECRET and stored in Cloudflare D1.
  • SSH Authentication supports Saved Key; selecting it uses the managed key to connect to the remote server.
  • When Saved Key is selected, the Worker tries the Ed25519 key first and then the RSA key.

Remote Server Records

The Connected before list is stored in D1 for each GitHub account.

  • Remote records are saved automatically after a successful SSH connection.
  • Users can edit or delete saved records.
  • Passwords, uploaded private keys, and other connection credentials are not stored in remote records.

Deployment

You need the following:

  • A Cloudflare account with Workers and D1 enabled.
  • A fork of this repository in your own GitHub account.

Create a D1 Database in the Cloudflare Dashboard

  1. Sign in to the Cloudflare Dashboard.
  2. Open Storage & Databases, then select D1 SQL Database.
  3. Click Create database and name it sshwifty.
  4. Copy the database ID after creation. It is a UUID such as 84fa53bb-3b6b-4d23-9f28-bfdcc23aa243.

Check the Repository Configuration

Deployment is configured through the root wrangler.jsonc. Before connecting the repository, confirm that the D1 binding looks like this:

"d1_databases": [
  {
    "binding": "DB",
    "database_name": "sshwifty",
    "database_id": "YOUR_D1_DATABASE_ID",
    "migrations_dir": "worker/migrations"
  }
]

Write the database ID from the previous step into database_id and commit it to the deployment branch. You can edit and commit wrangler.jsonc in the GitHub web editor.

wrangler.jsonc is the configuration source for Git deployments. Do not configure conflicting databases for the same binding in both the Dashboard and the repository.

Connect the GitHub Repository in Cloudflare

  1. Open Workers & Pages.
  2. Create an application and select Continue with GitHub.
  3. Authorize Cloudflare to access GitHub and select the repository containing this project.
  4. In the build configuration, enter the following values:
SettingValue
Project namesshwifty-plus
Root directory/
Build commandnpm run generate
Deploy commandnpx wrangler deploy
  1. Save the settings and start the first deployment.

After deployment, confirm that the following binding exists in the Worker's Bindings settings:

  • Type: D1 database
  • Name: DB
  • Value: sshwifty

Create a GitHub OAuth App

Copy the production URL from the Worker's Domains settings, or add a custom domain.

  1. Open GitHub Settings -> Developer settings -> OAuth Apps.
  2. Click New OAuth App.
  3. Set the Authorization callback URL to:
https://YOUR_WORKER_DOMAIN/sshwifty/auth/github/callback

For example, if the Worker is available at https://sshwifty.example.com, the callback URL must be:

https://sshwifty.example.com/sshwifty/auth/github/callback
A custom domain is recommended.
  1. Click Generate a new client secret and record the GitHub OAuth App Client ID and Client Secret. They are entered in the Cloudflare Dashboard in the next step.

Set Variables and Secrets in the Dashboard

After the first deployment, open the Worker's Settings -> Variables and Secrets and configure the following values.

Variables

These variables are already declared in wrangler.jsonc; you do not need to add them manually. You can change them when needed.
NameValueDescription
SSHWIFTY_AUTH_MODEgithubRequires GitHub sign-in
SSHWIFTY_DIAL_TIMEOUT120SSH connection timeout in seconds
SSHWIFTY_HEARTBEAT_TIMEOUT10Heartbeat interval in seconds
SSHWIFTY_ALLOWED_HOSTSFor example, ssh.example.com:22,10.0.0.10:2222When set, only the listed hosts and ports may be connected to; wildcards and CIDR ranges are not supported
SSHWIFTY_PUBLIC_ACCESStrueAllows entry to Sshwifty without a passphrase
SSHWIFTY_PRESETS[]SSH preset JSON
SSHWIFTY_SERVER_MESSAGEAny messageOptional

To avoid differences between Dashboard values and repository configuration, commit long-lived non-sensitive values to wrangler.jsonc and manage environment-specific values in the Dashboard.

Secrets

Do not expose these values anywhere, and never write them into wrangler.jsonc.

Use Add -> Secret to add the following values:

NameValue sourcePurpose
GITHUB_CLIENT_IDGitHub OAuth App Client IDRequired for GitHub sign-in
GITHUB_CLIENT_SECRETGitHub OAuth App Client SecretRequired for GitHub sign-in
SSHWIFTY_SHARED_KEYA password you chooseOptional. When SSHWIFTY_PUBLIC_ACCESS is disabled, users must enter this passphrase before using Sshwifty
SSHWIFTY_SESSION_SECRETA strong random value you generateSigns session and OAuth state cookies
SSHWIFTY_KEY_ENCRYPTION_SECRETA strong random value you generateEncrypts SSH private keys stored in D1

For the last two values, generate random strings of at least 32 bytes and paste them into the Dashboard. They must be different.

PSWD by MAZE is recommended. Enable Include Uppercase Letters, Include Lowercase Letters, and Include Numbers.

Rotating SSHWIFTY_SESSION_SECRET signs out all active users.
Do not lose or casually rotate SSHWIFTY_KEY_ENCRYPTION_SECRET. If it is lost, existing managed SSH private keys in D1 cannot be decrypted.

After saving variables or secrets, retry the deployment in the Dashboard or push an empty commit to GitHub to create a new Worker version.

D1 Handling After the First Deployment

  1. Confirm that the latest deployment is complete and that the DB binding points to the correct sshwifty D1 database.
  2. Open https://YOUR_WORKER_DOMAIN/sshwifty/.
  3. Select Sign in with GitHub and complete authorization.
  4. The OAuth callback automatically runs the current v1 schema initialization check.

Deployment Verification

  1. Open https://YOUR_WORKER_DOMAIN/sshwifty/.
  2. Select Sign in with GitHub and complete GitHub OAuth authorization.
  3. Open the account menu and copy the Ed25519 or RSA public key.
  4. Add the public key to the destination server user's ~/.ssh/authorized_keys file.
  5. Create a new SSH connection and select Saved Key under Authentication.
  6. Confirm the server fingerprint and verify that the shell opens.
  7. Reopen the connection dialog and confirm that the remote appears in Connected before. Edit and delete actions should persist after a reload.

Issues

Please open an Issue.

Copyright © 2026 Krab. Some rights reserved.
Built with Docus.