NetBox Tenant Switcher
[!NOTE] There's a newer, more capable successor:
netbox-scope-switcher. It generalizes this plugin — tenant becomes just one of any number of configurable, grouped scope dimensions (region, site, tag, …) whose filters cascade on each other. If you're starting fresh, prefer scope-switcher; this plugin remains available for tenant-only setups.
Pick a tenant once, and every list in NetBox shows only that tenant's objects.
netbox-tenant-switcher adds a searchable tenant selector to the top navigation
bar — rendered inside the field, just like NetBox's global search box. Choose a
tenant and, as you move between sections (Devices, Prefixes, VLANs, Sites,
Racks, …), each list view is automatically scoped to that tenant. Choose
"— All tenants —" to clear the scope.
It's ideal for MSPs, multi-customer labs, and anyone who spends the day working inside one tenant at a time and doesn't want to add a tenant filter on every page.
Screenshots
The tenant selector sits in the top navigation bar, rendered inside the field like NetBox's global search.
Open the dropdown to multi-select tenants and type to filter instantly; selected tenants float to the top.
Chosen tenants are listed comma-separated in the field and persist across the session.
Every list view (Devices, Prefixes, VLANs, …) is automatically scoped to the selected tenants.
Features
- Multi-select tenant switcher in the navbar with a checkbox per tenant and instant client-side search — no external JS dependencies.
- Selected tenants are shown comma-separated in the field, truncated with an ellipsis to fit the header; the field width adapts to the viewport and never overlaps the global search box.
- Selected tenants float to the top when the dropdown opens; the list is ordered by name.
- Selection persists in the session; no models, no migrations.
- Automatically scopes every object list view whose filterset supports a
tenant filter, by appending
?tenant_id=<id>(once per selected tenant, so multiple tenants are OR-combined). - Non-tenancy models (Manufacturers, Device Types, …) and detail views are left untouched.
- Permission-aware: the dropdown only lists tenants the user may view, and a tenant can't be selected unless the user has view access to it.
- Only ever narrows results — NetBox object permissions still apply on top.
Compatibility
| Plugin version | NetBox version | Python |
|---|---|---|
| 1.0.x | 4.6 | 3.10 – 3.12 |
Developed and verified against NetBox 4.6. It uses only stable plugin APIs
(PluginTemplateExtension.navbar() / head(), plugin middleware) and is
expected to work on nearby 4.x releases; the CI matrix in
.github/workflows/ci.yml is where additional versions should be validated.
Dependencies
- NetBox ≥ 4.6 (provides Django, Tom Select, and the tenancy models).
- No additional Python packages, external services, or other plugins required.
Installation
-
Install the package into NetBox's Python environment:
source /opt/netbox/venv/bin/activate pip install netbox-tenant-switcher
-
Enable it in
configuration.py:PLUGINS = [ "netbox_tenant_switcher", ]
-
Restart NetBox:
sudo systemctl restart netbox netbox-rq
No database migrations are required.
Docker (netbox-docker)
See deploy/ for a ready-to-use Dockerfile-Plugins,
docker-compose.override.yml, and plugins.py. In short: drop the project under
plugins/plugin-src/, add the plugin to configuration/plugins.py, then:
docker compose build netbox
docker compose up -d
Configuration
None. The plugin works out of the box; there are no PLUGINS_CONFIG settings.
How it works
-
Navbar widget (
template_content.py) — aPluginTemplateExtensionrenders a small, dependency-free multi-select (checkbox list + instant search) via thenavbar()hook; styling is injected throughhead(). It stays in one line with the selected tenants comma-separated and ellipsis-truncated. -
Set endpoint (
views.py) —GET /plugins/tenant-switcher/set/?tenant=<id>&tenant=<id>&next=<path>stores the chosen tenants in the session and redirects back.nextis validated against the current host (no open redirects) and every tenant id is checked against the user's view permission. -
Middleware (
middleware.py) — forObjectListViewpages whose filterset exposes atenant_idfilter, it appends one?tenant_id=<id>per selected tenant when no explicit tenant filter is already present.Design note: scoping is done by URL rewriting rather than by patching every queryset. This keeps the plugin decoupled from core views, applies uniformly across DCIM/IPAM/etc., and leaves the applied filter visible and removable in the UI.
Support
- Issues / bugs / features: GitHub Issues — https://github.com/Du10777/netbox-tenant-switcher/issues
- Questions: GitHub Discussions, or the NetDev Community Slack (
#netbox).
Contributing
PRs welcome. Run the test suite the way NetBox does — see
.github/workflows/ci.yml (checkout NetBox, install the plugin, then
python netbox/manage.py test netbox_tenant_switcher).
License
Apache-2.0 — matching NetBox itself. The icon in docs/img/ is
released under CC BY 4.0.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file netbox_tenant_switcher-1.0.1.tar.gz.
File metadata
- Download URL: netbox_tenant_switcher-1.0.1.tar.gz
- Upload date:
- Size: 18.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4f82b55d84983dcf1721b96f2550640d637cecb71ef4a3ff793a4f411b277dc7
|
|
| MD5 |
36d596f91b600e946606ca0cc97f5ea7
|
|
| BLAKE2b-256 |
d6f419e11471dd585f38f34c06c64c80791eaae81cdaa3553643114eeb7141d8
|
Provenance
The following attestation bundles were made for netbox_tenant_switcher-1.0.1.tar.gz:
Publisher:
publish.yml on Du10777/netbox-tenant-switcher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
netbox_tenant_switcher-1.0.1.tar.gz -
Subject digest:
4f82b55d84983dcf1721b96f2550640d637cecb71ef4a3ff793a4f411b277dc7 - Sigstore transparency entry: 2629901170
- Sigstore integration time:
-
Permalink:
Du10777/netbox-tenant-switcher@23a26b3439a0520c6b950366b578d80983bfae5d -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/Du10777
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@23a26b3439a0520c6b950366b578d80983bfae5d -
Trigger Event:
release
-
Statement type:
File details
Details for the file netbox_tenant_switcher-1.0.1-py3-none-any.whl.
File metadata
- Download URL: netbox_tenant_switcher-1.0.1-py3-none-any.whl
- Upload date:
- Size: 18.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f7f8899d75a908a6e5e9d7e9817e98240a1a60e4b69c15b3ea756543c5658d5b
|
|
| MD5 |
c54eccc1208ba1f8fe8528df1103610b
|
|
| BLAKE2b-256 |
08d488de796614f6b30f0c5747bb7a0f870476af15642765c3671b3af0eb70ea
|
Provenance
The following attestation bundles were made for netbox_tenant_switcher-1.0.1-py3-none-any.whl:
Publisher:
publish.yml on Du10777/netbox-tenant-switcher
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
netbox_tenant_switcher-1.0.1-py3-none-any.whl -
Subject digest:
f7f8899d75a908a6e5e9d7e9817e98240a1a60e4b69c15b3ea756543c5658d5b - Sigstore transparency entry: 2629902688
- Sigstore integration time:
-
Permalink:
Du10777/netbox-tenant-switcher@23a26b3439a0520c6b950366b578d80983bfae5d -
Branch / Tag:
refs/tags/v1.0.1 - Owner: https://github.com/Du10777
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@23a26b3439a0520c6b950366b578d80983bfae5d -
Trigger Event:
release
-
Statement type: