Reference Manual
/

πŸš€ Installation, Updates & Air-Gap

sshs3 is a modern, security-conscious desktop client that pairs an authentic OpenSSH terminal with a dual-pane file manager, Amazon S3 object storage, and Kubernetes workload debugging inside a single desktop application.

sshs3 Welcome Interface
sshs3 start screen with quick connection shortcuts and clean workspace

Installation Packages

PlatformFormatExecution / Installation Details
Linux Standalone AppImage Requires no root privileges. Make executable and run: chmod +x sshs3-*.AppImage && ./sshs3-*.AppImage
Debian / Ubuntu Native .deb sudo dpkg -i sshs3_*_amd64.deb (auto-resolves via apt)
Fedora / RHEL Native .rpm sudo dnf install sshs3-*.x86_64.rpm
Windows Setup Installer sshs3-Setup-*.exe β€” Bundles the VcXsrv X11 server for seamless remote GUI window rendering out of the box.
Windows Portable Standalone sshs3-*-portable.exe β€” Standalone single-binary requiring zero installation.
Windows Portable ZIP sshs3-*.zip β€” Pre-extracted archive. When run alongside a local data/ directory, all user profiles and settings are saved locally to <exe-dir>/data rather than %APPDATA%, providing true USB portability.
πŸ’‘ Air-Gap Security Flag
sshs3 checks GitHub Releases every 6 hours for software updates without telemetry. For air-gapped or high-security networks, export the environment variable:
export SSHS3_DISABLE_UPDATES=1
When set, all network update checks are completely locked off and no outbound update requests are made.

πŸ—‚οΈ Connection Manager & Complete Field Reference

The Connection Manager provides unified configuration across all your remote servers, local shells, clusters, and buckets.

SSH Profile Form
SSH profile creation dialog with basic parameters and authentication selector

SSH Profile Field Reference

Field NameDefaultPurpose & DescriptionLimitations & Constraints
Profile Name Required Friendly display label used in tab headers and connection lists. Cannot be empty.
Group / Folder Empty Organises profiles into tree folders (e.g. Production/Web). Subfolders supported with forward slashes (/).
Hostname / IP Required Target FQDN (e.g. server.internal) or IPv4/IPv6 address. Must be resolvable via DNS or reachable directly or via ProxyJump.
Port 22 Target SSH daemon listening port. Integer between 1 and 65535.
Username Required Remote user account (e.g. ubuntu, root, deploy). POSIX username standards.
Initial SFTP Path Empty Default folder opened in the file manager upon connecting. Leave empty to open your home directory.
Jump Host / ProxyJump None Reach the server through another saved profile, or a manual bastion such as jumpuser@bastion.example.com:22. Works for terminals and SFTP. The jump host must accept your credentials without an interactive prompt that sshs3 cannot answer.
Outgoing Proxy Off Connect through an HTTP, SOCKS4 or SOCKS5 proxy (host, port, optional username and password). The proxy password is stored encrypted in the OS keyring.
Dotfiles Pool & Sync Policy Not assigned Assign a dotfiles pool to this profile and choose to be asked before updating (diff banner on connect) or to update silently. See Environment & Profile Sync.

Authentication Methods

sshs3 supports 5 distinct authentication methods:

Private Key Authentication
SSH Private Key configuration with passphrase encryption
  • Password: Plain password prompt or stored encrypted in OS Keychain / DPAPI. Limitation: Interactive passwords cannot be sampled by the background Performance Bar on Windows.
  • SSH Key: Select a private key file on disk (~/.ssh/id_ed25519, ~/.ssh/id_rsa) with optional passphrase.
  • SSH Agent: Inherits keys currently loaded in your running system ssh-agent or Windows agent service.
  • Smartcard (PKCS#11): Hardware authentication via PIV modules (p11-kit, libykcs11, OpenSC, Net iD). PIN is held ephemerally according to your chosen policy.
  • FIDO2 / Security Key: Hardware keys (YubiKey 5). Supports Resident Keys scanned directly from the hardware token or generated in-app.
FIDO2 Security Key Setup
FIDO2 hardware security key configuration and in-app key generator

Access Check & Key Deployment (GUI)

Access Check and Key Deployment
5-stage Access Check timeline and multi-key ssh-copy-id deployment dialog

Click Install key… to deploy one or more public keys directly into ~/.ssh/authorized_keys in a single session. The 5-stage Access Check timeline diagnoses connectivity:

  1. Reach Host: Verifies TCP connection.
  2. Host Key: Confirms server key matches known_hosts.
  3. Login Methods: Silently probes OpenSSH daemon for allowed auth methods without requiring PIN or touch.
  4. Key Installed: Checks if public key is present in authorized_keys.
  5. Login Works: Verifies login succeeds.

Advanced SSH Options

Advanced SSH Parameters
Finer protocol controls: Agent forwarding, X11, Compression, KeepAlive, Ciphers, KEX and MACs
ParameterFlagPurposeCaveat / Limitation
Agent Forwarding -A Exposes local SSH agent to remote host for chaining connections. Security warning: Only enable on trusted servers.
X11 Forwarding -Y Forwards remote GUI applications to local screen. On Windows, requires VcXsrv (bundled in Setup installer).
Compression -C Gzip compression of network traffic. Useful on slow connections; slightly increases CPU load.
ServerAliveInterval 0 Periodic keep-alive packets in seconds. What happens when a session ends or drops (reconnect, close or keep) is set globally under Settings β†’ Terminal β†’ On Logout / Session End. Set to 30 or 60 to prevent firewall NAT timeouts.
X11 Display Location 127.0.0.1:0.0 Where forwarded X11 windows are drawn. Leave the default unless you use a custom X server. Only used when X11 forwarding is on.
Custom Ciphers / KEX / MACs Empty (OpenSSH defaults) Comma-separated algorithm lists passed to OpenSSH, e.g. chacha20-poly1305@openssh.com,aes128-gcm@openssh.com. The server must support at least one entry, otherwise the connection fails.

πŸ’» Terminal, Tabs & Ergonomics

sshs3 pairs an xterm-compatible terminal frontend with your genuine system OpenSSH process via node-pty.

Konsole-Style Recursive Splits
Arbitrary horizontal and vertical split panes with independent sessions

Clipboard & Selection

  • Copy on Select (Settings β†’ Terminal): text you select is copied to the system clipboard automatically. Each selection is also kept in an encrypted, searchable clipboard history.
  • Paste: Shift+Insert pastes (the latest history entry when Copy on Select is on, otherwise the system clipboard); middle-click pastes the latest history entry. The system paste shortcut works as well.
  • Right-click: with Copy on Select on, opens the clipboard history. Pane splitting is done from the pane toolbar or the shortcuts below.
  • Dynamic Zoom: scale the font with Ctrl++, Ctrl+- and reset with Ctrl+0.

Konsole-Style Recursive Split Panes

ActionShortcutDescription
Split RightCtrl+Shift+DSubdivides active pane vertically, adding a pane to the right
Split DownCtrl+Shift+ESubdivides active pane horizontally, adding a pane below
Next PaneCtrl+Shift+NCycle keyboard focus forward through panes
Previous PaneCtrl+Shift+PCycle keyboard focus backward through panes
UnsplitToolbar buttonMaximises the active pane and closes all other split panes

Local Shells with Managed SSH_AUTH_SOCK

Opening a local shell tab automatically injects SSH_AUTH_SOCK. If you have unlocked a smartcard or YubiKey in an SSH session under Global PIN caching, that unlocked key is immediately available inside local shell commands (e.g. git pull or ssh) without asking for a second PIN.

✨ Terminal Productivity

Features built into every terminal tab and split pane. Shortcuts act on the terminal that has keyboard focus and can be rebound under Settings β†’ Keyboard Shortcuts.

  • Searches the whole scrollback (Settings β†’ Terminal β†’ Scrollback Buffer). Matches update as you type and a counter shows the position, e.g. 3/6.
  • Enter jumps to the next match, Shift+Enter to the previous, Esc closes the bar. Selected text is used as the search term.
  • Match colours follow the theme: red on Breeze, yellow/orange on Light and Dark. The active match is clearly stronger than the rest.
  • Stepping through matches selects them, but never triggers Copy on Select.

Hold Ctrl (Cmd on macOS) and click:

  • URLs (http://, https://) open in your default browser, in terminals and Kubernetes log views.
  • File paths in SSH terminals (/var/log/syslog, ~/notes.md, /srv/app.py:42:7) open the folder in a new SFTP file manager tab. A terminal cannot tell files from folders, so a path without a trailing / opens its parent folder. ~/ is resolved as /home/<user> (/root for root), and the SFTP tab always uses the pane's own connection, even if you have hopped to another host with ssh inside it.
  • Paths are not clickable in local shell or Kubernetes exec terminals.

Snippets (Ctrl+Shift+L)

  • A searchable palette of saved commands. Enter types the command into the prompt; Ctrl+Enter types and runs it. Multi-line snippets are pasted as one paste.
  • Click New to add one; the pencil and bin icons edit and delete. A snippet can be limited to the current connection or available everywhere.
  • Variables: {{host}}, {{user}}, {{date}} (format yyyy-mm-dd HH:mm).
  • Stored unencrypted in snippets.json in the app's data folder. Do not put passwords or tokens in snippets.

Copy Last Command Output (Ctrl+Shift+G)

  • Copies what the previous command printed to the clipboard (and to the clipboard history when Copy on Select is on). A short notice confirms how many lines were copied.
  • Exact in shells that emit OSC 133 prompt marks (fish, and zsh/bash with shell integration).
  • Otherwise inferred from your Enter presses. With a multi-line prompt, the first prompt line can be included in the copy. Full-screen programs (vim, less) are ignored.

Clipboard History (Ctrl+Shift+R)

  • Requires Copy on Select. Selections are stored encrypted with the OS keyring; without a keyring the history stays in memory only and nothing is written to disk.
  • Right-click or Ctrl+Shift+R opens a searchable list: ↑/↓ to navigate, Enter or click to paste, the bin icon to delete an entry, Clear all to empty it.
  • Shift+Insert and middle-click paste the latest entry.

Terminal Settings

SettingDefaultDescription
Terminal Font Size13Base font size. Ctrl++, Ctrl+-, Ctrl+0 adjust it on the fly.
Terminal Font FamilyMonospace stackPick a preset or enter a custom monospaced font.
Cursor StyleBlockBlock, underline or bar.
Scrollback Buffer (lines)5000History kept per terminal pane, used by search. Higher values use more memory.
Copy text automatically on selectionOffCopies every selection to the clipboard and records it in the encrypted clipboard history.
Clipboard history scopeGlobalShare the history between all hosts, or keep a separate history per connection.
Empty clipboard history on exitOffWipes the history when the app quits (and on next start, in case it crashed).
On Logout / Session EndReconnectWhat happens when a session ends: reconnect, close the tab, or keep it open.

⚑ Live Performance Bar & Diagnostics

The Performance Bar is an opt-in live telemetry strip directly above active terminals. It provides real-time system metrics without requiring third-party monitoring agents or extra logins.

Terminal Metrics Bar
Live Performance Bar displayed at the top of an active SSH terminal session
Performance Diagnostics History Modal
Comprehensive 15-minute diagnostic view with CPU/Memory donut charts, per-filesystem bars, and line graphs

Enabling & Configuring the Bar

The bar is off by default. While it is off, nothing is polled and no extra commands run. Turn it on under Settings β†’ Performance.

  • Layout: text, bars or sparklines.
  • Refresh interval: 2, 5, 10 or 30 seconds. Kubernetes sessions refresh at most every 10 s (metrics-server updates slowly), and so do SSH sessions on Windows, which opens a fresh connection per sample.
  • Metrics (default: CPU, memory, load): CPU, memory, load, swap, disk, network, uptime, iowait, steal, disk I/O, processes, per-core CPU, page cache, per-filesystem disks and latency for SSH hosts; restarts, ready, age, node and resources for Kubernetes pods.
  • Sources: SSH sessions are sampled over the already open OpenSSH connection by reading /proc (Linux hosts), local shells sample the local machine, and Kubernetes sessions use the metrics API.
  • Details: click the bar to open the history view (up to the last 15 minutes while the tab is active).

How to Interpret System Telemetry & Diagnostics

  • I/O Wait (`iowait`): Time CPU spends idling while waiting for disk I/O to complete. If CPU appears low (e.g. 20%) but iowait is above 50–60%, the server is suffering from a disk or storage bottleneck (e.g. saturated database disk or slow AWS EBS volume), not a CPU deficiency.
  • Steal (`steal`): Time the virtual CPU was ready to execute, but the cloud hypervisor (AWS, GCP, Azure) allocated CPU cycles to other tenants. High steal (>5–10%) indicates "noisy neighbors" on shared cloud infrastructure.
  • Memory: Used vs. Page Cache/Buffers: Linux opportunistically uses free RAM for disk page caching. sshs3's donut chart explicitly separates memory locked by applications (Used) from reclaimable cache (Cache/Buffers) and completely free memory, preventing unnecessary panic over high cached memory.
  • Load Average vs. Core Count: Load is normalized against server cores. On a 4-core machine, Load 4.0 represents 100% saturation; on an 8-core machine, Load 4.0 is only 50% capacity.
  • Kubernetes Requests vs. Limits: Real-time gauges show container memory usage against limits, giving early warnings before the Linux kernel OOM Killer terminates containers with Exit Code 137.

☸️ Kubernetes & OpenShift Workloads

Inspect, manage, and debug Kubernetes and OpenShift workloads directly from sshs3 without requiring external plugins or daemonsets.

Kubernetes Cluster Explorer
Contexts, namespaces, and pod hierarchy parsed directly from ~/.kube/config

Key Capabilities

  • Interactive Container Exec (`tty`): Open interactive pseudo-terminals (sh, bash, or custom commands) into any pod container, fully integrated with split-view panes.
    ⚠️ Scratch / Distroless Containers
    Containers built from scratch or distroless images without a shell binary cannot launch interactive exec terminals.
  • Live Log Streaming: Follow container stdout/stderr in real time with optional timestamps, a tail-lines limit (200 by default so busy containers do not flood the view), support for crashed containers (previous: true), and text search with Ctrl+F.
  • Container File Explorer (`K8sPodStorageProvider`): Browse, upload, download, and edit files inside running containers using the Dual-Pane File Manager.
  • Port Forwarding: Forward remote pod or service ports to your local workstation loopback interface with live byte counters.
  • Live Pod Debugging (kubectl debug): Attach an ephemeral debug container to a running pod without restarting it, sharing the target container's process namespace. Presets: Netshoot (network troubleshooting), RHEL Support Tools, BusyBox, Curl and Ubuntu, plus custom images and commands under Settings β†’ Kubernetes & Debug. An interactive terminal opens in the debug container.
  • OpenShift `oc login`: Paste an oc login command to authenticate directly into your kubeconfig.

πŸ“ Dual-Pane File Manager (SFTP, Local, S3 & K8s)

sshs3 features a dual-pane file explorer capable of transferring data across any combination of protocols: Local ↔ SFTP, SFTP ↔ S3, Local ↔ S3, or Local ↔ Kubernetes Pods.

Dual-Pane File Manager
Dual-pane file transfers with transfer queue and conflict resolution

SFTP v3 Engine via OpenSSH

Carried directly over ssh -s sftp via your host system's OpenSSH binary. Features a 16 MB packet safety guard and concurrent chunking for multi-gigabyte transfers.

Keyboard Ergonomics in File Manager

  • Enter: Open the selected folder, or open the file in the built-in editor.
  • Backspace / Alt+Up: Navigate up one folder level. Alt+Left / Alt+Right: back and forward in history.
  • Ctrl+C / Ctrl+X / Ctrl+V: copy, cut (dimmed until pasted) and paste files and folders. Ctrl+A selects all.
  • F2 rename, Delete delete (with confirmation), F5 refresh, Home / End jump to the first or last item. Typing letters jumps to the matching file name.
  • Ctrl+F: Filter the list; wildcards are supported (*.log, data-?-final.csv).
  • Ctrl+Shift+K: Search in Files — content search (with regex) across local disk, SFTP and S3.

Built-in Editor & Directory Sync

  • Built-in Editor: Open files from local disk, SFTP, S3 or pods in a plain-text editor with a live Markdown preview (Source | Preview switch). Press Ctrl+S to save directly back to the server. There is no syntax highlighting; use the external editor hand-off if you want your own editor.
  • Live Log Tail: Follow a growing log file (tail -f) in the same viewer, with pause, resume and search.
  • Directory Synchronisation: Compare two folders side-by-side with color-coded diff indicators and execute one-way or two-way synchronisation.
  • Permissions & Chmod: Visual and octal file permission editor (e.g. 0755, 0644) with recursive options.

Git Integration (Local & SFTP)

The file manager detects Git repositories automatically, both in local folders and on remote servers over SFTP.

  • Branch & status indicator: current branch, uncommitted/untracked changes, and commits ahead (↑) or behind (↓) origin.
  • Git Pull: update the repository with one click, no terminal needed.
  • Open in GitHub/GitLab: opens the repository web page when remote.origin.url is configured.
  • Clone Git repository here…: clone into the current folder (or right-click a sub-folder and choose Git Clone inside…), with optional shallow-clone depth.
  • On/off switch: toggle under Settings β†’ Git & GitHub. When off, no background git polling happens and all Git controls are hidden.

☁️ S3 Cloud Object Storage

Connect natively to Amazon S3, Cloudflare R2, MinIO, Wasabi, Backblaze B2, and custom S3 endpoints using AWS SDK v3.

S3 Profile Configuration
S3 profile form with endpoint configuration, path-style addressing, and encryption

Advanced S3 Operations & File Sharing

  • Presigned URLs: Generate secure, time-limited download links (15 minutes, 1 hour, 12 hours, 1 day, or 7 days, the maximum) to share files with external clients or colleagues without opening public access on your bucket.
  • Object Versioning: View complete version history for overwritten or updated objects and restore earlier versions with a single click.
  • AWS SSO Login: Sign in with the AWS SSO device flow (compatible with the AWS CLI's ~/.aws/sso/cache), then pick an account and role for short-lived credentials.
  • Bucket Administration: Edit bucket policies and CORS rules and manage tags, directly from the file manager.
  • Path-Style Addressing: Mandatory for MinIO, Ceph, and private IP endpoints to prevent DNS lookup failures.
  • Direct Server-to-S3 Transfers: Transfer files between an SFTP host and S3 bucket without streaming through your local workstation disk.

πŸ›‘οΈ Security, Hardware Keys & Smartcards

Security is the foundation of sshs3. All operations adhere strictly to zero-trust architecture.

Security Settings
PIN caching policies and preferred PKCS#11 module configuration

Visual Touch-Presence Banner

When authenticating with a FIDO2 hardware key, sshs3 displays an animated touch-presence banner: "Touch your security key to authenticate..." so you always know when your key is awaiting physical touch, preventing mysterious timeouts.

PIN Caching (Settings β†’ Security & Smartcard)

PINs are never written to disk, cached on disk or logged. Choose how long a PIN is remembered in memory:

  • Always Prompt (default): No caching across connections; reconnecting asks for the PIN again. Use this where policy requires re-authenticating the card on every login.
  • Once Per Terminal Connection: The PIN is entered once into a private, app-managed ssh-agent shared by that terminal tab and its dotfiles sync. The agent is killed when the terminal disconnects, and reconnecting asks again. Automatic reconnects after a dropped connection reuse the open agent.
  • Global (App Lifetime): The PIN is entered once per card and shared by every terminal and profile using it, including local shell tabs opened afterwards, until you quit or lock it. Most convenient, least strict. A card icon in the top bar lists what is cached and has a Lock All Now button.

πŸ”‘ Public Key Deployment (`ssh-copy-id` GUI)

Install public keys onto remote servers effortlessly using sshs3's built-in key deployment tool and 5-stage Access Check timeline.

Idempotent Multi-Key Installation

  • Select local .pub files, active SSH agent keys, smartcard/FIDO2 public keys, or paste a key string.
  • Installs into ~/.ssh/authorized_keys in a single session; sets correct 0700 and 0600 permissions.
  • Reports whether each key was "Installed" or "Already Present".
  • Smart authentication: Uses your password or existing credentials for the setup and avoids attempting to authenticate with the key being deployed.

Offline / Copy Command Generator

Need to configure an offline server? Click Copy Command in the Access section to generate a ready-to-paste shell script:

mkdir -p ~/.ssh && chmod 700 ~/.ssh && echo 'ssh-ed25519 AAAAC3... user@box' >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys

🌐 Networking, Proxies & SSH Tunnels

Navigate complex topologies, jump hosts, and internal private subnets with ease.

SSH Tunnels Panel
Independent background SSH Tunnels manager

ProxyJump vs. Standalone SSH Tunnels

  • ProxyJump: Configured per profile; lives inside that specific terminal session for hopping through bastions.
  • Standalone SSH Tunnels: Independent background processes managed from the SSH Tunnels button in the top bar. They continue running even when all terminal tabs are closed!

Tunnels Capabilities

  • Local Port Forwarding (`-L`): Expose remote databases (e.g. `127.0.0.1:5432`) locally.
  • Remote Port Forwarding (`-R`): Expose local development servers to the remote network.
  • Dynamic SOCKS5 (`-D`): Spawns a local SOCKS5 proxy (e.g. `127.0.0.1:1080`) for routing web browser traffic through the remote server.

πŸ”„ Environment & Profile Sync

Synchronization Settings
Client-side encrypted profile sync and dotfiles pool management

Dotfiles Pool Sync (Opt-In)

Maintain your favorite aliases, .bashrc, and .vimrc configurations on remote servers without cluttering persistent server configuration. The dotfiles pool stages your files into an isolated session directory upon login.

You choose exactly which files belong in a pool. Open the Dotfiles Pool Manager in Synchronization settings and use Add Files... (or drag files in); nothing is added in bulk, so pooling only ~/.kube/config means picking just that file. Files are listed grouped by target directory with a read-only preview, a file mode, and a status showing whether the local source file has changed (Refresh re-reads it). To edit a pooled file, use Open Master Directory. You can also right-click a file in the file manager and choose Add to Dotfiles Pool.... Pooled files are stored unencrypted on this device, so avoid pooling files that contain credentials.

Remote Profile Sync ("Own Your Data")

Synchronise profiles across multiple workstations using your own storage backend (S3 bucket or private SFTP server). Everything is client-side encrypted with AES-256-GCM before upload—no proprietary cloud required. Unlock with a master password or a smartcard / hardware token. Profile sync is opt-in and off by default.

⌨️ Keyboard Shortcuts & Settings Reference

Keyboard Shortcuts Table
Built-in keyboard shortcuts reference inside application settings
ShortcutActionContext
Ctrl+Shift+TNew TerminalGlobal
Ctrl+Shift+FNew File ManagerGlobal
Ctrl+WClose TabGlobal
Ctrl+TabSwitch to Next TabGlobal
Ctrl+Shift+TabSwitch to Previous TabGlobal
Ctrl+Shift+OConnection ManagerGlobal
Ctrl+,Open SettingsGlobal
Ctrl+Shift+KSearch in Files (content search across local/SFTP/S3)File Manager
Ctrl+Shift+DSplit Pane Vertically (Right)Terminal
Ctrl+Shift+ESplit Pane Horizontally (Down)Terminal
Ctrl+Shift+NNext Split PaneTerminal
Ctrl+Shift+PPrevious Split PaneTerminal
Ctrl+Shift+SSearch in TerminalTerminal
Ctrl+Shift+RClipboard HistoryTerminal
Ctrl+Shift+GCopy Last Command OutputTerminal
Ctrl+Shift+LSnippetsTerminal
Ctrl++ / Ctrl+-Zoom Font In / OutTerminal
Ctrl+0Reset Font ZoomTerminal
Ctrl+FFind / Recursive File SearchFile Manager
Ctrl+SSave File to Remote TargetBuilt-in Editor

πŸ™ Git & GitHub (Developer Keys & Commit Signing)

A central place under Settings β†’ Git & GitHub for developer SSH keys, Git providers and cryptographic commit signing.

Git & GitHub Settings
Developer SSH keys, Git commit signing and file manager Git integration

Developer SSH Keys & Git Providers

  • Collects public keys from ~/.ssh, the active SSH agent and the smartcard cache (YubiKey/PIV/FIDO2).
  • Copy puts the public key on the clipboard.
  • GitHub / GitLab opens the provider's SSH key settings with the key title filled in and the key text copied, ready to paste (Ctrl+V).

Git Commit Signing (~/.gitconfig)

  • Shows the active signing format (ssh) and public key.
  • Sign Active / Git Sign configures the chosen key as signing key in one click; Automatic Signing toggles commit.gpgsign.
  • ~/.ssh/allowed_signers is maintained automatically so local signatures verify cleanly.
  • Change Key / Custom Key lets you paste any public key or key path.

Lookup Public Keys (username.keys)

Inspect and copy the public keys of any user on GitHub, GitLab or a self-hosted GitLab via their official .keys endpoints.

App theme