Skip to content

Add SSH Switch v0.2.3 - #1127

Open
nicholasyoannou wants to merge 3 commits into
SteamDeckHomebrew:mainfrom
nicholasyoannou:add/ssh-switch
Open

nicholasyoannou wants to merge 3 commits into
SteamDeckHomebrew:mainfrom
nicholasyoannou:add/ssh-switch

Conversation

@nicholasyoannou

@nicholasyoannou nicholasyoannou commented Sep 13, 2026 •

Copy link
Copy Markdown

Add SSH Switch to Plugin Store

SSH Switch 0.2.1 is a simple plugin that provides SSH controls in Decky's Quick Access Menu, allowing you to control startup of the SSH service, alongside an assistant companion on PC to mount the Deck over SFTP/SSHFS (OS-dependant).

  • Start or stop SSH immediately.
  • Choose whether SSH starts at boot, independently of its current running state.
  • Verify the current account password before entering and confirming a replacement password. Blank passwords are rejected.
  • Show the address, port, username, SSH fingerprint and remote folders for connecting from a computer.

The release on the Decky SSH Switch repository also provides companion SSHFS mount and unmount helpers for Windows, Linux and macOS. These run on the user's computer, which can be used alongside the "Connect from Computer" popup for ease of connection. Windows also supports persistent drives and optional saved settings, with the saved password encrypted for that Windows account. The "Connect from Computer" popup adds SSH management alongside the interface information shown by Decky Network Info.

SSH Switch settings New password and confirmation dialog, shown after current-password verification

Task Checklist

Developer

  • I am the original author or an authorized maintainer of this plugin.
  • I have abided by the licenses of the libraries I am utilizing, including attaching license notices where appropriate.
  • Generative AI was NOT used to write a majority of the code I am submitting.

Regarding AI Use: I've used GPT-6 Astra to assist with parts of the implementation, debugging and code review. I’ve modified and tested the Decky plugin on my Steam Deck and the Windows companion scripts on Windows 11.

Plugin

  • I have verified that my plugin works properly on the Stable and Beta update channels of SteamOS.

I've tested and verified the plugin on both update channels on SteamOS (Steam Deck).

  • I have verified my plugin is unique or provides more/alternative functionality to a plugin already on the store.

Similar functionality has been proposed in Easy SSH (#1034), which remains open (but stale), and Decky SSH (#1104), which was closed without merging. Both provide SSH controls from the Quick Access Menu, and Decky SSH also includes password changes with current-password verification.

SSH Switch shares those features and adds separate control over whether SSH starts at boot, along with a “Connect from computer” screen showing the connection details, host fingerprint and available remote folders. The companion mount and unmount scripts for Windows, Linux and macOS use those details to help users access their Deck’s files from their computer, with the Windows script inspired by MonroeWorld's script as a base. This connection and file-access workflow is the main additional functionality offered by this submission.

Backend

  • No: I am using a custom backend other than Python.
  • Yes: I am using a tool or software from a 3rd party FOSS project that does not have it's dependencies statically linked.
  • No: I am using a custom binary that has all of it's dependencies statically linked.

The backend is Python and uses systemctl, sshd and chpasswd. It also dynamically loads SteamOS’s libcrypt.so.1 for password verification and hashing. The plugin does not bundle or download additional native binaries. The companion mounting scripts run separately on the user’s computer.

Community

  • I have tested and left feedback on two other pull requests for new or updating plugins.
  • I have commented links to my testing report in this PR.

Testing

  • Tested by a third party on SteamOS Stable or Beta update channel.

@nicholasyoannou
nicholasyoannou requested a review from a team as a code owner September 13, 2026 23:24
@github-actions github-actions Bot added the plugin-addition Adding a plugin to the Plugin Store label Sep 13, 2026
@github-actions

Copy link
Copy Markdown

Issues Found

No issues with your PR description were found.

Next Steps

  1. If we found any issues above, please edit your pull request description to resolve them and leave a comment saying you've done so.
  2. For the quickest review, please see the Community section of the pull request template for how you can help other developers.
  3. Once your description is correct, a maintainer will review your pull request as soon as possible.

Thank you for your contribution! If you need any help, please reach out on our Discord server. ❤️

@spmzt

spmzt commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

"Connect from computer" lists only IPv4 addresses (main.py:152). The mount scripts reject IPv6 addresses (mount-unix.sh:14, mount-windows.ps1:19), so the helpers fail on an IPv6-only network.

Other than this, LGTM, tested on SteamOS Beta Channel

@nicholasyoannou nicholasyoannou changed the title Add SSH Switch v0.2.1 Add SSH Switch v0.2.2 Sep 17, 2026
@nicholasyoannou

Copy link
Copy Markdown
Author

@spmzt Thanks for your comment, appreciate the feedback.

I've added IPv6 support to the "Connect from computer" popup displayed, and compatibility in the scripts for IPv6 also. It will only show the IPv6/IPv4 based on if it's enabled. SteamOS seemingly silently switched IPv6 back on by default for some (see ValveSoftware/SteamOS#2024) but oddly I've tested it on my own Steam Deck and the IPv6 loopback is disabled when it's already connected via IPv4 (SteamOS dual-stack network problem). Personal router supports IPv4 and IPv6 but oddly IPv6 is disabled on my Deck.

I've tested this with your IPv6 enabler plugin #1130 and can verify IPv6 connectivity works as intended. I've left some feedback on your referenced PR also. Have tested #1128.

I've also added a quick QOL update for the connectivity scripts to change the default steamdeck to steamdeck.local for mDNS enhacements, and to UI/UX so users can easily find the connection instructions via a QR code/URL link to mount their Steam Deck.

@spmzt

spmzt commented Sep 17, 2026

Copy link
Copy Markdown
Contributor

Tested again on my Steamdeck, LGTM.

P.S. Not related to this PR, but could you please use python3 instead of python? I'm using FreeBSD (doesn't matter for linux/decky) and I've to change it in order to make tests work:

diff --git a/package.json b/package.json
index 8de0cc6..667353c 100644
--- a/package.json
+++ b/package.json
@@ -14,7 +14,7 @@
     "clean": "node scripts/clean.mjs",
     "build": "rollup -c",
     "typecheck": "tsc --noEmit",
-    "test": "python -B -m unittest discover -s tests -v",
+    "test": "python3 -B -m unittest discover -s tests -v",
     "package": "node scripts/check-version.mjs && pnpm run clean && pnpm run typecheck && pnpm run build && node scripts/package.mjs",
     "verify-package": "node scripts/verify-package.mjs"
   },

@nicholasyoannou

Copy link
Copy Markdown
Author

Glad it's all working good. For OS-compatibility sake since Windows (not WSL) uses python instead of python3 (depending on how it's installed), I've added a small .mjs script that changes this (OS-dependant) for ease for future testing.

@github-actions

Copy link
Copy Markdown

This pull request is stale as no updates or testing reports have been posted within the last 7 days. Please ensure you are actively recruiting testers or resolving the issues discussed. If you do not remove the stale label or comment, this will be closed in 7 days. Please close this pull request if you need more time to resolve issues so we can keep our repo healthy.

@github-actions github-actions Bot added the stale label Sep 28, 2026
@nicholasyoannou

Copy link
Copy Markdown
Author

PR is not stale. The plugin has undergone testing and can confirm there are no outlying problems. Awaiting someone with privileges to review and approve

@github-actions github-actions Bot removed the stale label Sep 29, 2026
@github-actions

github-actions Bot commented Oct 6, 2026

Copy link
Copy Markdown

This pull request is stale as no updates or testing reports have been posted within the last 7 days. Please ensure you are actively recruiting testers or resolving the issues discussed. If you do not remove the stale label or comment, this will be closed in 7 days. Please close this pull request if you need more time to resolve issues so we can keep our repo healthy.

@github-actions github-actions Bot added the stale label Oct 6, 2026
@nicholasyoannou

Copy link
Copy Markdown
Author

Not stale

@github-actions github-actions Bot removed the stale label Oct 7, 2026
@nanwangjkl

nanwangjkl commented Oct 9, 2026 •

Copy link
Copy Markdown

Plugin Testing Report

Installed Plugins

  • SteamGridDB - 1.8.1
  • Bluetooth - 2.3.1
  • Decktation - 0.3.18
  • SSH Switch - 0.2.2
  • Time Changer - 0.1.12

Specifications

  • SteamOS 3.8.28_20260922.1(Stable)
  • Steam 1791918634 (Stable)
  • Decky 3.2.10 (Stable)

Issues

Has the following major blocking issue(s): 0
Has the following minor non-blocking issue(s): 1

Summary

Tested by installing from the repo release, exercising the UI (SSH on/off, startup toggle, password change flow, connection info dialog), and running the macOS mount helper from a computer. I also reviewed the backend, frontend and mount scripts in depth. Honestly, this is some of the highest-quality plugin code I've read in this ecosystem — nothing blocking, only one minor.

Major Blocking Issues

None.

Minor Non-Blocking Issues

  1. No localization: all strings are hardcoded English. The Steam client locale is readable via window.LocalizationManager.m_rgLocalesToUse, and a bundled dictionary with an English fallback would cover Chinese (and other) users with little code.

Tester Note

As the maintainer of another plugin (Time Changer), I want to call out the security engineering here, because it sets the bar for the category: the two-phase password verification with a single-use, TTL-bound token and a shadow-hash guard against TOCTOU; passwords only ever traveling over stdin; hashing before chpasswd --encrypted to shut down line-protocol injection; constant-time comparisons; ctypes buffers zeroed after use; and the uid/account restrictions. The operational details are just as good — full exit-code checking, asyncio.Lock serialization, before/after state verification, and the sshd.socket edge-case guard. The decision to leave systemd state untouched in _unload (user choice persists) versus restoring transient state is exactly the right distinction. Great work — approved from my side.

@justjoseorg

justjoseorg commented Oct 14, 2026 •

Copy link
Copy Markdown

Tested on an AYN Odin 2 Portal (ARM64, SteamOS ARM port, Decky Loader). Installed from commit 69e0d3b.

  • Plugin loads and shows in the Quick Access Menu.
  • Stopping SSH from the plugin stopped sshd (my SSH session dropped and new connections were refused).
  • Starting it again from the plugin brought sshd back and I could reconnect.

LGTM.

@justjoseorg justjoseorg mentioned this pull request Oct 14, 2026
6 of 8 tasks
@nanwangjkl nanwangjkl mentioned this pull request Oct 18, 2026
7 of 8 tasks
@AAGaming00
AAGaming00 requested review from a team and removed request for a team October 19, 2026 21:12
@AAGaming00 AAGaming00 moved this to Ready for review in Plugin Review Oct 19, 2026
@Tormak9970

Copy link
Copy Markdown
Contributor

@nicholasyoannou please elaborate on the usage of GPT. What was it used for specifically?

@nicholasyoannou

Copy link
Copy Markdown
Author

Hi @Tormak9970, GPT Astra was used to help build from the initial templating from the Decky templates, draft and revise parts of the Python backend, Decky frontend, tests and companion scripts, investigate errors from testing, and review changes for potential issues. During development of the plugin have done multiple security audits incl. the password-changing feature, which did initially allow password changes without verification of the old one (which would've been a security disaster) before submission to the Decky Plugin DB, so was changed before pushing it across. I've done security audits on the SSH Switch codebase using Daybreak Blue and Mythos 5.1, both have returned cleanly. It was also used to help aid understanding of MonroeWorld's scripts which have been referenced across the Steam Deck subreddit various times for ease of mounting SD drive to PC for familiarity. I dabbled between Opus, GPT, and spmzt's in-development IPv6 Control plugin while testing for IPv6 implementation which was added shortly after (due to Windows interpreting IPv6 addresses differently via ipv6-literal). Happy to clarify if you need clarity on certain aspects.

@AAGaming00 AAGaming00 moved this from Ready for review to Changes requested in Plugin Review Oct 20, 2026
@Tormak9970

Tormak9970 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Hi @Tormak9970, GPT Astra was used to help build from the initial templating from the Decky templates, draft and revise parts of the Python backend, Decky frontend, tests and companion scripts, investigate errors from testing, and review changes for potential issues. During development of the plugin have done multiple security audits incl. the password-changing feature, which did initially allow password changes without verification of the old one (which would've been a security disaster) before submission to the Decky Plugin DB, so was changed before pushing it across. I've done security audits on the SSH Switch codebase using Daybreak Blue and Mythos 5.1, both have returned cleanly. It was also used to help aid understanding of MonroeWorld's scripts which have been referenced across the Steam Deck subreddit various times for ease of mounting SD drive to PC for familiarity. I dabbled between Opus, GPT, and spmzt's in-development IPv6 Control plugin while testing for IPv6 implementation which was added shortly after (due to Windows interpreting IPv6 addresses differently via ipv6-literal). Happy to clarify if you need clarity on certain aspects.

We have a no majority AI policy, is the majority of your codebase written by yourself? Also, as a side note, we can't review code like this: https://github.com/nicholasyoannou/decky-ssh-switch/blob/main/scripts/verify-package.mjs. That needs to be cleaned up

@AAGaming00 AAGaming00 moved this from Changes requested to Ready for review in Plugin Review Oct 20, 2026
@nicholasyoannou

Copy link
Copy Markdown
Author

@Tormak9970 Yes, has been written by myself, with modifications with AI. Have understood the code and logic, with various aspects added from elsewhere (MonroeWorld, with research and testing for Windows mDNS and other enhancements to scripts). Am happy to take on further feedback if certain aspects need to be changed.

As for cleanup, I've removed verify-package.mjs along with the other release scripts (release.sh and its test, clean.mjs, check-version.mjs and third-party.mjs), though were quick GitHub tooling scripts spunup meant for CI/CD, not ran on the Deck. Have changed the workflow to use gh release create instead.

@nicholasyoannou nicholasyoannou changed the title Add SSH Switch v0.2.2 Add SSH Switch v0.2.3 Oct 20, 2026
@github-project-automation github-project-automation Bot moved this from Ready for review to Approved, needs testing in Plugin Review Oct 21, 2026
@Managor

Managor commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Works great.

This branch was successfully deployed

1 active deployment
testing_env — 987ba41c Deployed Oct 21, 2026 by sidharthify via Build plugin (decky-ssh, true) #4151
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin-addition Adding a plugin to the Plugin Store

Projects

Status: Approved, needs testing

Development

Successfully merging this pull request may close these issues.

8 participants