NetBox SSH Browser
NetBox SSH Browser is a terminal application for browsing NetBox devices and opening SSH sessions. It groups devices by location and role, with search by name or IP address. Connections use the system OpenSSH client, directly or through a configured jump host. On macOS, iTerm2 can open selected devices in separate tabs.
Inventory is synchronized manually and cached locally for use when NetBox is unavailable. Hosts missing from NetBox can be added to a separate manual inventory. The application reads NetBox data without modifying it and does not store SSH credentials.
Contents
- Recent Changes
- What It Does
- Safety Model
- Requirements
- Installation
- Configuration
- First Run
- Navigation
- Manual Inventory
- Inventory Rules
- Local Cache
- Development
- Compatibility
- Acknowledgements
Recent Changes
- SSH jump host with saved per-device selection (
J). The target SSH client runs on the jump host and supports password prompts without TCP forwarding. - Device type and name filters using glob patterns, such as
MX*andTEST-*. - Navigation restores the selected entry when returning from a site or branch.
See CHANGELOG.md for release details.
What It Does
- Reads regions, sites, and devices from the NetBox REST API.
- Builds a navigable location tree from NetBox region and site relationships.
- Groups countries under parent regions, branches under cities, and devices under Device Roles.
- Searches all cached devices by name or primary IP address.
- Connects to
primary_ip4, thenprimary_ip6, and finally the device name when no primary IP is assigned. - Uses the current shell user and the existing OpenSSH configuration.
- Supports a configurable SSH jump host with persistent per-device selection.
- Keeps the last successful inventory available when NetBox is offline.
Safety Model
- Synchronization is manual and runs only after pressing
S. - The application performs read-only
GETrequests to NetBox. - NetBox remains responsible for authentication and object permissions.
- The API token is read from the private user configuration or, when set, from
NETBOX_API_TOKEN. It is never written to cache or logs. - The NetBox token and URL are removed from the child SSH process environment.
- SSH is started as an argument list without
shell=True. - Host keys, SSH Agent, keys, and connection options remain managed
by the system OpenSSH client and
~/.ssh/config. - A failed or interrupted sync never overwrites the previous valid cache.
- The cache directory is mode
0700and the cache file is mode0600. - The application does not require
sudoor write to system directories.
Requirements
- Python 3.11 or newer.
- A NetBox REST API token with view permissions for DCIM regions, sites, and devices.
- The system
sshcommand. - A terminal with standard TUI support, such as iTerm2, Terminal.app, or a Linux terminal emulator.
NetBox API v1 and v2 tokens are supported. Tokens beginning with nbt_ use
Bearer authentication; legacy tokens use Token authentication.
Installation
Install with pipx to keep dependencies isolated and add nssh to PATH.
macOS
brew install pipx
pipx ensurepath
pipx install netbox-ssh-browser
Open a new terminal after pipx ensurepath.
Linux
On Ubuntu 23.04 or newer:
sudo apt update
sudo apt install pipx
pipx ensurepath
pipx install netbox-ssh-browser
On Fedora, replace the first two commands with sudo dnf install pipx. Open a
new terminal after updating PATH.
Windows
Install Python 3.13 from WinGet in PowerShell:
winget install --exact --id Python.Python.3.13
Close all PowerShell windows and reopen PowerShell to refresh PATH.
Check Python and install pipx:
py --version
py -m pip install --user pipx
py -m pipx ensurepath
Reopen PowerShell again to pick up the pipx paths, then install the package:
pipx --version
pipx install netbox-ssh-browser
nssh --version
nssh --version prints the installed package version. If you use Scoop,
you can install pipx with scoop install pipx instead.
Verify, upgrade, and uninstall
nssh --version
pipx upgrade netbox-ssh-browser
pipx uninstall netbox-ssh-browser
pipx normally places the command link in ~/.local/bin on macOS and Linux,
and %USERPROFILE%\.local\bin on Windows. The isolated application code is
stored under the platform-specific PIPX_HOME:
- macOS:
~/Library/Application Support/pipx/venvs/netbox-ssh-browser - Linux:
~/.local/share/pipx/venvs/netbox-ssh-browser - Windows:
%LOCALAPPDATA%\pipx\venvs\netbox-ssh-browser
Check the paths used by your installation:
pipx environment --value PIPX_HOME
pipx environment --value PIPX_BIN_DIR
Local development
Create an isolated editable installation:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e .
To run the development version without activating the environment, add a symlink:
ln -s \
"/absolute/path/to/netbox-ssh-browser/.venv/bin/nssh" \
"$HOME/bin/nssh"
The link remains valid only while the project and .venv stay at the same
location.
For release preparation and PyPI publication, see PUBLISHING.md.
Configuration
Set the NetBox URL and API token in config.toml:
[netbox]
url = "https://netbox.example.com"
api_token = "your-token"
verify_ssl = true
Enter the token without a Bearer or Token prefix; the application adds it.
NETBOX_URL and NETBOX_API_TOKEN override the values in the file.
Press C in nssh to create or edit the configuration. On macOS and Linux,
you can also create it manually:
mkdir -p ~/.config/netbox-ssh-browser
nano ~/.config/netbox-ssh-browser/config.toml
chmod 600 ~/.config/netbox-ssh-browser/config.toml
To use a different file:
export NETBOX_SSH_CONFIG="/path/to/config.toml"
Configuration files are checked in this order:
NETBOX_SSH_CONFIG.~/.config/netbox-ssh-browser/config.toml.config.tomlin the current working directory.
Environment variables override corresponding TOML values. Keep the user
configuration private with mode 0600 and never commit a real token.
NetBox settings
TLS certificate verification is enabled by default. For a development instance with a self-signed certificate, you can disable it:
[netbox]
verify_ssl = false
For production, keep verify_ssl = true and use a certificate trusted by the
client.
Inventory filters
[sync]
device_statuses = ["active"]
ignored_manufacturers = ["Example Manufacturer"]
ignored_device_types = ["MX*"]
ignored_name_patterns = ["*CORE", "TEST-*"]
device_roles = [
"Access Switch",
"Core Router",
"Edge Router",
]
device_statusescontains NetBox status slugs. An empty list downloads all statuses.device_rolescontains exact Device Role names, compared case-insensitively. An empty list includes every role.ignored_manufacturersaccepts manufacturer names, slugs, or display values, compared case-insensitively. An empty list excludes nothing.ignored_device_typescontains case-insensitive glob patterns matched against a device type's model, slug, and display value.ignored_name_patternscontains case-insensitive glob patterns matched against device names.*matches any text and?matches one character.- Status filters are sent to the NetBox API. Other inventory filters are applied before the cache is written.
SSH jump host
Press C and set the jump host in config.toml:
[ssh]
jump_host = "jump-host"
Use a hostname, IP address, user@host, or an alias from ~/.ssh/config.
For example, admin@bastion.example.com connects to the bastion as admin.
Highlight a NetBox or manual device and press J to enable the jump host.
Press Enter to connect, or select devices for an iTerm2 multi-tab launch.
Press J again to use direct SSH. An empty jump_host setting prevents new
selections.
Devices marked J use the jump host; others connect directly. Choices are saved
in jump-host-devices.json alongside manual.json and
survive restarts and inventory syncs.
The connection runs a second SSH client on the jump host:
ssh -tt jump-host "ssh target"
The jump host needs an SSH client and network access to the target. Target DNS resolution, SSH settings, host keys, and authentication are handled there. This works when TCP forwarding is disabled and allows password prompts on the target connection. The application does not store passwords.
First Run
-
Set
urlandapi_tokenin the private userconfig.toml. -
Run the application:
nssh
-
Press
Sto load inventory from NetBox. The list is empty until the first sync. -
Check the status bar for errors.
-
Use the arrow keys and
Enterto browse locations and connect to a device.
The /api/status/ endpoint is checked first. Inventory is saved only after all
required API requests and filters complete successfully.
Navigation
| Key | Action |
|---|---|
Up / Down |
Move between selectable entries |
Enter |
Open a location or start SSH for a device |
Ctrl+T / Space |
Select or unselect a device for a multi-session launch |
Ctrl+U |
Clear all selected devices |
J |
Enable or disable the configured jump host for a device |
Esc |
Close search or return to the previous level |
/ |
Search all cached devices by name or primary IP |
S |
Sync from NetBox |
+ |
Add a manual device to the current branch |
C |
Edit the active config.toml in the shell editor |
M |
Edit manual.json in the shell editor |
Q |
Quit |
Location and role headings group the entries:
Region Group A
Country A
Country B
City A
branch-a-01
branch-a-02
Access Switch
switch-01 192.0.2.10
switch-02 switch-02.example.com
Arrow keys skip headings. Opening a device suspends the browser and starts SSH; when the session ends, the browser returns to the same view. Going back from a site or branch restores the previous selection.
In iTerm2 on macOS, select devices with Ctrl+T or Space, then press Enter
to open each connection in a separate tab. The nssh tab stays open. macOS may
ask for permission to automate iTerm2 on the first launch. Ctrl+U clears the
selection. Other terminals support one SSH session at a time and show a message
if you try to open multiple sessions.
C and M open files in $VISUAL, then $EDITOR if set. The fallback is
nano on macOS/Linux and notepad on Windows. Missing files are created before
opening the editor; changes are reloaded after a successful exit. The editor
process does not inherit the NetBox URL or API token.
Manual Inventory
Manual devices are stored in manual.json, separately from the NetBox cache.
Open a branch, press +, and enter:
- device name,
- IP address or hostname,
- Device Role.
The current location supplies the region, country, city, and branch. Manual
devices are marked ◇ and included in / search and SSH connections.
To edit the file directly, use this format:
{
"version": 1,
"devices": [
{
"region": "Region Group A",
"country": "Country A",
"city": "City A",
"branch": "branch-a-01",
"role": "Access Switch",
"name": "manual-switch-01",
"target": "192.0.2.50"
}
]
}
Missing locations are added to the displayed tree from manual.json. Sync does
not modify this file. Invalid JSON or an unsupported format stops startup with
an error.
The file is stored in the user data directory:
- macOS:
~/Library/Application Support/netbox-ssh-browser/manual.json - Linux:
~/.local/share/netbox-ssh-browser/manual.json - Windows: the
netbox-ssh-browserdata directory under%LOCALAPPDATA%
The directory is mode 0700 and the file is mode 0600 where supported.
Inventory Rules
- NetBox API pagination is followed until every permitted object is downloaded.
- Device status filters are queried separately and results are deduplicated by NetBox object ID.
- Devices not assigned to a visible site and region cannot be placed in the location tree and are skipped.
- Empty regions, countries, cities, branches, and Device Role groups are removed.
- A site is not duplicated when its name matches the final region name.
- IP prefixes are stripped before invoking SSH; for example,
192.0.2.10/24becomes192.0.2.10. - SSH target priority is
primary_ip4,primary_ip6, thendevice.name. - The cache contains only objects visible to the NetBox user associated with the API token.
- Manual devices are merged only in memory and are never written to the NetBox cache.
Local Cache
The cache is stored per user:
- macOS:
~/Library/Caches/netbox-ssh-browser/devices.json - Linux:
~/.cache/netbox-ssh-browser/devices.json - Windows: the
netbox-ssh-browsercache directory under%LOCALAPPDATA%
The JSON cache contains the sync timestamp, location tree, Device Roles, device names, and primary IP addresses. It never contains the NetBox API token or SSH credentials.
The cache format is version 2. Invalid or unsupported cache files are ignored.
Old formats and paths are not migrated; press S to rebuild the cache.
Development
Source files in src/netbox_ssh:
cli.pyloads configuration and starts the Textual application.config.pymerges TOML settings and environment variables.netbox.pyhandles authentication, pagination, status filtering, and API requests.service.pycoordinates synchronization and inventory filtering.model.pybuilds and prunes the location tree.cache.pyvalidates and atomically writes cache version 2.manual.pyvalidates, stores, and merges persistent manual devices.jump_state.pystores persistent per-device jump-host choices.tui.pyimplements navigation, search, background sync, and SSH handoff.terminal.pycontains the optional multi-tab iTerm2 integration.
Run local checks before submitting changes:
python -m unittest discover -s tests -v
python -m compileall -q src tests
Compatibility
See COMPATIBILITY.md for the supported Python, operating system, terminal, and NetBox versions.
Manually tested on:
- macOS on Apple silicon (MacBook Pro M5 Pro) with iTerm2,
- Ubuntu under WSL2 on Windows,
- native Windows with PowerShell, Windows Terminal, and Windows OpenSSH.
CI runs the test suite on macOS, Ubuntu, and Windows with Python 3.11 and 3.13.
Acknowledgements
Development of NetBox SSH Browser was assisted by OpenAI Codex.
Metadata
Release files for netbox-ssh-browser 0.1.5
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| netbox_ssh_browser-0.1.5.tar.gz | 2.5 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| netbox_ssh_browser-0.1.5-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 2.6 MB
Release files / netbox_ssh_browser-0.1.5.tar.gz
| Download URL | netbox_ssh_browser-0.1.5.tar.gz |
|---|---|
| Size | 2.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
523a78d89b6f4439d0afad51efd38c29cde8fd906cb357947aab042310747f92
|
|
BLAKE2b-256 checksum How to use checksums |
5a885615edef73ef10d8fe61163acfafb30f4d45bb90a3da773cc758834ce51d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / netbox_ssh_browser-0.1.5-py3-none-any.whl
| Download URL | netbox_ssh_browser-0.1.5-py3-none-any.whl |
|---|---|
| Size | 30.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
51fddb5f7e06c9901071dac9f3497ea64284c4a0d4826630f4da99624485e22f
|
|
BLAKE2b-256 checksum How to use checksums |
e5cd4a04dbb35ef22581b6b1a04e4188a68d7ae0f007aacd9eddc62d19acd743
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency log