* Add ModelAction and register_model_actions() API for custom permission actions * Add ObjectTypeSplitMultiSelectWidget and RegisteredActionsWidget * Integrate registered actions into ObjectPermissionForm * Add JavaScript for registered actions show/hide * Register custom actions for DataSource, Device, and VirtualMachine * Add tests for ModelAction and register_model_actions * Refine registered actions widget UI - Use verbose labels (App | Model) for action group headers - Simplify template layout with h5 headers instead of cards - Consolidate Standard/Custom/Additional Actions into single Actions fieldset * Hide custom actions field when no applicable models selected The entire field row is now hidden when no selected object types have registered custom actions, avoiding an empty "Custom actions" label. * Add documentation for custom model actions - Add plugin development guide for registering custom actions - Update admin permissions docs to mention custom actions UI - Add docstrings to ModelAction and register_model_actions * Add RESERVED_ACTIONS constant and fix dedup in registered actions - Define RESERVED_ACTIONS in users/constants.py for the four built-in permission actions (view, add, change, delete) - Replace hardcoded action lists in ObjectPermissionForm with the constant - Fix duplicate action names in clean() when the same action is registered across multiple models (e.g. render_config for Device and VirtualMachine) - Fix template substring matching bug in objectpermission.html detail view by passing RESERVED_ACTIONS through view context for proper list membership * Fix shared action pre-selection and additional actions leakage on edit * Prevent duplicate action registration in register_model_actions() * Remove stale comment in RegisteredActionsWidget * Rebuild frontend assets after rebase onto feature * Refactor SplitMultiSelectWidget to use class attributes for widget classes * Reject reserved action names in register_model_actions() * Show all registered actions with enable/disable instead of show/hide * Validate action name is not empty and clarify RESERVED_ACTIONS origin * Adapt custom actions panel for declarative layout system Convert the ObjectPermission detail view to use the new panel-based layout from #21568. Add ObjectPermissionCustomActionsPanel that cross-references assigned object types with the model_actions registry to display which models each custom action applies to. Also fix dark-mode visibility of disabled action checkboxes in the permission form by overriding Bootstrap's disabled opacity. * Flatten registered actions UI and declare via Meta.permissions Implement two changes requested in review of #21560: 1. Use Meta.permissions for action declaration - Add Meta.permissions to DataSource, Device, and VirtualMachine - register_models() auto-registers actions from Meta.permissions - Remove explicit register_model_actions() calls from apps.py - Add get_action_model_map() utility to utilities/permissions.py 2. Flatten the ObjectPermission form UI - Show a single deduplicated list of action checkboxes (one per unique action name) instead of grouped-by-model checkboxes - RegisteredActionsWidget uses create_option() to inject model_keys and help_text; JS enables/disables based on selected object types - render_field.html bypasses outer wrapper for registeredactionswidget so widget emits rows with identical DOM structure to CRUD checkboxes - Unchecking a model now also unchecks unsupported action checkboxes Fixes #21357 * Address review feedback on registered actions - Sort model_keys in data-models attribute for deterministic output - Rename registered_actions field label to 'Registered actions' - Target object_types selected list via data-object-types-selected attribute instead of hardcoded DOM ID - Reduce setTimeout delay to 0ms since moveOption() is synchronous * Consolidate ObjectPermission detail view actions panel Merge ObjectPermissionActionsPanel and ObjectPermissionCustomActionsPanel into a single Actions panel that shows CRUD booleans and all registered actions in one table, matching the form's consolidated layout. Also fix data-object-types-selected attribute value (True -> 'true') and update plugin docs to show Meta.permissions as the primary registration approach. * Address additional bot review feedback - clean() collects all validation errors before raising instead of stopping at the first - Fix stale admin docs (still referenced "Custom actions" and "grouped by model") * Update netbox/netbox/registry.py Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com> * Fix model_actions registry to use set operations The registry was changed to defaultdict(set) but the registration code still used list methods. Update .append() to .add() and fix tests to use set-compatible access patterns. * Rename permission migrations for clarity * Move ModelAction validation into __post_init__ * Drop model name from permission descriptions * Simplify ObjectPermission form and remove custom widgets Replace the dynamic UI with standard BooleanField checkboxes for each registered action. No custom widgets, no JavaScript, no template changes. - Remove RegisteredActionsWidget, ObjectTypeSplitMultiSelectWidget, and registeredActions.ts - Use dynamic BooleanFields for registered actions (renders identically to CRUD checkboxes) - Move action-resolution logic from panel to ObjectPermission model - Remove object-type cross-validation from form clean() - Remove unused get_action_model_map utility * Remove register_model_actions from public API Meta.permissions is the documented approach for plugins. The register_model_actions function is now an internal implementation detail. * Sort registered actions and improve test coverage Sort action names alphabetically for stable display order. Add tests for cloning, empty registry, and models_csv output. * Add help_text to registered action checkboxes * Return model_keys as list from get_registered_actions() Move string joining to the template so callers get native list data instead of a pre-formatted CSV string. * Improve detail view: human-friendly descriptions and additional actions Return dicts from get_registered_actions() with help_text and verbose model names. Add get_additional_actions() for manually-entered actions that aren't CRUD or registered. Show both in the Actions panel. * Renumber permission migrations after feature merge Resolve migration conflicts with default_ordering_indexes migrations. Renumber to 0023 (core), 0232 (dcim), 0056 (virtualization) and update dependencies. --------- Co-authored-by: Jeremy Stretch <jstretch@netboxlabs.com>
NetBox exists to empower network engineers. Since its release in 2016, it has become the go-to solution for modeling and documenting network infrastructure for thousands of organizations worldwide. As a successor to legacy IPAM and DCIM applications, NetBox provides a cohesive, extensive, and accessible data model for all things networked. By providing a single robust user interface and programmable APIs for everything from cable maps to device configurations, NetBox serves as the central source of truth for the modern network.
NetBox's Role | Why NetBox? | Getting Started | Get Involved | Screenshots
NetBox's Role
NetBox functions as the source of truth for your network infrastructure. Its job is to define and validate the intended state of all network components and resources. NetBox does not interact with network nodes directly; rather, it makes this data available programmatically to purpose-built automation, monitoring, and assurance tools. This separation of duties enables the construction of a robust yet flexible automation system.
The diagram above illustrates the recommended deployment architecture for an automated network, leveraging NetBox as the central authority for network state. This approach allows your team to swap out individual tools to meet changing needs while retaining a predictable, modular workflow.
Why NetBox?
Comprehensive Data Model
Racks, devices, cables, IP addresses, VLANs, circuits, power, VPNs, and lots more: NetBox is built for networks. Its comprehensive and thoroughly inter-linked data model provides for natural and highly structured modeling of myriad network primitives that just isn't possible using general-purpose tools. And there's no need to waste time contemplating how to build out a database: Everything is ready to go upon installation.
Focused Development
NetBox strives to meet a singular goal: Provide the best available solution for making network infrastructure programmatically accessible. Unlike "all-in-one" tools which awkwardly bolt on half-baked features in an attempt to check every box, NetBox is committed to its core function. NetBox provides the best possible solution for modeling network infrastructure, and provides rich APIs for integrating with tools that excel in other areas of network automation.
Extensible and Customizable
No two networks are exactly the same. Users are empowered to extend NetBox's native data model with custom fields and tags to best suit their unique needs. You can even write your own plugins to introduce entirely new objects and functionality!
Flexible Permissions
NetBox includes a fully customizable permission system, which affords administrators incredible granularity when assigning roles to users and groups. Want to restrict certain users to working only with cabling and not be able to change IP addresses? Or maybe each team should have access only to a particular tenant? NetBox enables you to craft roles as you see fit.
Custom Validation & Protection Rules
The data you put into NetBox is crucial to network operations. In addition to its robust native validation rules, NetBox provides mechanisms for administrators to define their own custom validation rules for objects. Custom validation can be used both to ensure new or modified objects adhere to a set of rules, and to prevent the deletion of objects which don't meet certain criteria. (For example, you might want to prevent the deletion of a device with an "active" status.)
Device Configuration Rendering
NetBox can render user-created Jinja2 templates to generate device configurations from its own data. Configuration templates can be uploaded individually or pulled automatically from an external source, such as a git repository. Rendered configurations can be retrieved via the REST API for application directly to network devices via a provisioning tool such as Ansible or Salt.
Custom Scripts
Complex workflows, such as provisioning a new branch office, can be tedious to carry out via the user interface. NetBox allows you to write and upload custom scripts that can be run directly from the UI. Scripts prompt users for input and then automate the necessary tasks to greatly simplify otherwise burdensome processes.
Automated Events
Users can define event rules to automatically trigger a custom script or outbound webhook in response to a NetBox event. For example, you might want to automatically update a network monitoring service whenever a new device is added to NetBox, or update a DHCP server when an IP range is allocated.
Comprehensive Change Logging
NetBox automatically logs the creation, modification, and deletion of all managed objects, providing a thorough change history. Changes can be attributed to the executing user, and related changes are grouped automatically by request ID.
Note
A complete list of NetBox's myriad features can be found in the introductory documentation.
Getting Started
- Just want to explore? Check out our public demo right now!
- The official documentation offers a comprehensive introduction.
- Check out our wiki for even more projects to get the most out of NetBox!
Get Involved
- Follow @NetBoxOfficial on Twitter!
- Join the conversation on the discussion forum and Slack!
- Already a power user? You can suggest a feature or report a bug on GitHub.
- Contributions from the community are encouraged and appreciated! Check out our contributing guide to get started.





