Allow the assignment of secrets to objects other than devices #1238

Closed
opened 2025-12-29 16:30:28 +01:00 by adam · 23 comments
Owner

Originally created by @elmmare on GitHub (Sep 18, 2017).

Originally assigned to: @jeremystretch on GitHub.

Issue type

[X] Feature request
[ ] Bug report
[ ] Documentation

Environment

  • Python version: 2.7.5
  • NetBox version: 2.1.4

Description

Secret cannot be attached to Sites and Racks but only to devices.

Usage cases:
*Store combination lock codes for racks or cage
*Store Site access codes

Originally created by @elmmare on GitHub (Sep 18, 2017). Originally assigned to: @jeremystretch on GitHub. <!-- Before opening a new issue, please search through the existing issues to see if your topic has already been addressed. Note that you may need to remove the "is:open" filter from the search bar to include closed issues. Check the appropriate type for your issue below by placing an x between the brackets. If none of the below apply, please raise your issue for discussion on our mailing list: https://groups.google.com/forum/#!forum/netbox-discuss Please note that issues which do not fall under any of the below categories will be closed. ---> ### Issue type [X] Feature request <!-- Requesting the implementation of a new feature --> [ ] Bug report <!-- Reporting unexpected or erroneous behavior --> [ ] Documentation <!-- Proposing a modification to the documentation --> <!-- Please describe the environment in which you are running NetBox. (Be sure to verify that you are running the latest stable release of NetBox before submitting a bug report.) --> ### Environment * Python version: 2.7.5 * NetBox version: 2.1.4 <!-- BUG REPORTS must include: * A list of the steps needed to reproduce the bug * A description of the expected behavior * Any relevant error messages (screenshots may also help) FEATURE REQUESTS must include: * A detailed description of the proposed functionality * A use case for the new feature * A rough description of any necessary changes to the database schema * Any relevant third-party libraries which would be needed --> ### Description Secret cannot be attached to Sites and Racks but only to devices. Usage cases: *Store combination lock codes for racks or cage *Store Site access codes
adam added the status: acceptedtype: feature labels 2025-12-29 16:30:28 +01:00
adam closed this issue 2025-12-29 16:30:28 +01:00
Author
Owner

@jeremystretch commented on GitHub (Sep 20, 2017):

Extending secrets from devices to multiple objects requires replacing the ForeignKey field tied to the Device model with a GenericForeignKey. This in itself is straightforward, however we have to consider how this relationship should be displayed in the API.

Currently, a secret retrieved via the API looks like this:

{
    "id": 1234,
    "device": {
        "id": 5678,
        "url": "http://localhost:8000/api/dcim/devices/5678/",
        "name": "MyDevice",
        "display_name": "MyDevice"
    },
    "role": <...>,
    "name": "root",
    "plaintext": null,
    "hash": "<hash>",
    ...
}

If we switch to a generic relationship, we need some way to indicate the type of the parent object, both while retrieving existing secrets and while creating new ones. The DRF documentation talks about this briefly, but does not suggest any particular approach.

@jeremystretch commented on GitHub (Sep 20, 2017): Extending secrets from devices to multiple objects requires replacing the ForeignKey field tied to the Device model with a GenericForeignKey. This in itself is straightforward, however we have to consider how this relationship should be displayed in the API. Currently, a secret retrieved via the API looks like this: ``` { "id": 1234, "device": { "id": 5678, "url": "http://localhost:8000/api/dcim/devices/5678/", "name": "MyDevice", "display_name": "MyDevice" }, "role": <...>, "name": "root", "plaintext": null, "hash": "<hash>", ... } ``` If we switch to a generic relationship, we need some way to indicate the type of the parent object, both while retrieving existing secrets and while creating new ones. The [DRF documentation](http://www.django-rest-framework.org/api-guide/relations/#generic-relationships) talks about this briefly, but does not suggest any particular approach.
Author
Owner

@darkstar commented on GitHub (Sep 20, 2017):

How about integrating with HashiCorp's Vault (https://www.vaultproject.io) as backend storage for secrets? If it is even remotely possible/interesting I can open a feature request issue for it.

@darkstar commented on GitHub (Sep 20, 2017): How about integrating with HashiCorp's Vault (https://www.vaultproject.io) as backend storage for secrets? If it is even remotely possible/interesting I can open a feature request issue for it.
Author
Owner

@rlaneyjr commented on GitHub (Sep 21, 2017):

I agree with darkstar. I had thought about making an attempt to integrate it in myself. Then realized I am a novice at best with Python/Django and lost with GO.

@rlaneyjr commented on GitHub (Sep 21, 2017): I agree with darkstar. I had thought about making an attempt to integrate it in myself. Then realized I am a novice at best with Python/Django and lost with GO.
Author
Owner

@jeremystretch commented on GitHub (Sep 21, 2017):

I looked into Vault back when I was first working on secrets storage. While it can certainly be used in conjunction with NetBox (with Vault serving as a replacement for NetBox's built-in storage), I don't think it makes sense for NetBox to integrate directly with Vault. Doing so would incur a substantial new dependency while not providing any significant value as opposed to accessing Vault directly. Let's stick with the functionality we have now.

@jeremystretch commented on GitHub (Sep 21, 2017): I looked into Vault back when I was first working on secrets storage. While it can certainly be used in conjunction with NetBox (with Vault serving as a replacement for NetBox's built-in storage), I don't think it makes sense for NetBox to integrate directly with Vault. Doing so would incur a substantial new dependency while not providing any significant value as opposed to accessing Vault directly. Let's stick with the functionality we have now.
Author
Owner

@linasjan commented on GitHub (Sep 27, 2017):

Secrets for tenants also would be appreciated.

@linasjan commented on GitHub (Sep 27, 2017): Secrets for tenants also would be appreciated.
Author
Owner

@larsuhartmann commented on GitHub (Nov 29, 2017):

This feature would be highly apreciated!

@larsuhartmann commented on GitHub (Nov 29, 2017): This feature would be highly apreciated!
Author
Owner

@c0dyhi11 commented on GitHub (Dec 25, 2017):

Hello,

I'd also like to see secrets for other object. My use case is a place to store API keys during provisioning. I'm building an API wrapper around Terraform and Netbox to deploy infrastructure. I'd be nice to store the API key under the "Site" I'm deploying to.

My goal is that you only need to authenticate to NetBox's API and everything else to provision into: Route53, Packet.net, OpenStack, AWS, Etc... Will all be accessible through the NetBox secrets store. It's either this or stand up another secrets store (Like Vault or Rattic) and pull the NetBox API Key from there...

Thank you,
Cody Hill

@c0dyhi11 commented on GitHub (Dec 25, 2017): Hello, I'd also like to see secrets for other object. My use case is a place to store API keys during provisioning. I'm building an API wrapper around Terraform and Netbox to deploy infrastructure. I'd be nice to store the API key under the "Site" I'm deploying to. My goal is that you only need to authenticate to NetBox's API and everything else to provision into: Route53, Packet.net, OpenStack, AWS, Etc... Will all be accessible through the NetBox secrets store. It's either this or stand up another secrets store (Like Vault or Rattic) and pull the NetBox API Key from there... Thank you, Cody Hill
Author
Owner

@etfeet commented on GitHub (Dec 30, 2017):

I would also like to see secrets for virtual-machines. My use case is to store salt minion public/private rsa key pairs for automagicly provisioning and accept salt minion keys on the master via querying the netbox api. I would prefer not to story that data as custom fields on the virtual-machines which is my only option right now (with netbox). Also Would it be possible to add another field to secrets for storing public/private key pairs for devices?

@etfeet commented on GitHub (Dec 30, 2017): I would also like to see secrets for virtual-machines. My use case is to store salt minion public/private rsa key pairs for automagicly provisioning and accept salt minion keys on the master via querying the netbox api. I would prefer not to story that data as custom fields on the virtual-machines which is my only option right now (with netbox). Also Would it be possible to add another field to secrets for storing public/private key pairs for devices?
Author
Owner

@larsuhartmann commented on GitHub (Apr 4, 2018):

I could not find this Feature on any Roadmap / Release Plans
Is there any plan on when to implement this?
We are waiting eagerly for this to be introduced as we plan to store our automatically generated root passwords in netbox - although as i don't know how complicated it would be to implement this ... don't feel pressured by me :)

@larsuhartmann commented on GitHub (Apr 4, 2018): I could not find this Feature on any Roadmap / Release Plans Is there any plan on when to implement this? We are waiting eagerly for this to be introduced as we plan to store our automatically generated root passwords in netbox - although as i don't know how complicated it would be to implement this ... don't feel pressured by me :)
Author
Owner

@c0dyhi11 commented on GitHub (Apr 5, 2018):

We ended up deploying Vault for this and not doing it with Netbox…
One more system to Manage but Vault is a really good choice for secrets management.

@c0dyhi11 commented on GitHub (Apr 5, 2018): We ended up deploying Vault for this and not doing it with Netbox… One more system to Manage but Vault is a really good choice for secrets management.
Author
Owner

@jsenecal commented on GitHub (Jun 22, 2018):

@jeremystretch Another way would be to have multiple nullable FKs defined in the Secret model as this wouldnt change much the API.

@jsenecal commented on GitHub (Jun 22, 2018): @jeremystretch Another way would be to have multiple nullable FKs defined in the `Secret` model as this wouldnt change much the API.
Author
Owner

@orgito commented on GitHub (Jun 29, 2018):

It also makes sense to attach secrets to VMs and clusters

@orgito commented on GitHub (Jun 29, 2018): It also makes sense to attach secrets to VMs and clusters
Author
Owner

@arionl commented on GitHub (Mar 13, 2019):

I'd appreciate this feature as well. I'm starting to explore the secrets feature of NetBox and I've had some success mirroring AD LDAP groups into Django groups. Therefore, managing group memberships of who should be able to access a secret as AD groups mapped to Secret Roles, but leaving the crypto to NetBox, seems like a nice fit..

@arionl commented on GitHub (Mar 13, 2019): I'd appreciate this feature as well. I'm starting to explore the secrets feature of NetBox and I've had some success mirroring AD LDAP groups into Django groups. Therefore, managing group memberships of who should be able to access a secret as AD groups mapped to Secret Roles, but leaving the crypto to NetBox, seems like a nice fit..
Author
Owner

@hpreston commented on GitHub (Aug 1, 2019):

Just adding another mark of interest for this feature. Would be very helpful to have secrets attached to VM objects (and others) in addition to VMs. Currently looking at working around this by storing VMs in Netbox as Devices rather than VMs...

@hpreston commented on GitHub (Aug 1, 2019): Just adding another mark of interest for this feature. Would be very helpful to have secrets attached to VM objects (and others) in addition to VMs. Currently looking at working around this by storing VMs in Netbox as Devices rather than VMs...
Author
Owner

@DanSheps commented on GitHub (Sep 3, 2019):

Only comment on an issue if you are sharing a relevant idea or constructive feedback. Do not comment on an issue just to show your support (give the top post a 👍 instead) or ask for an ETA. These comments will be deleted to reduce noise in the discussion.

@DanSheps commented on GitHub (Sep 3, 2019): > Only comment on an issue if you are sharing a relevant idea or constructive feedback. Do not comment on an issue just to show your support (give the top post a 👍 instead) or ask for an ETA. These comments will be deleted to reduce noise in the discussion.
Author
Owner

@jameskirsop commented on GitHub (Aug 27, 2020):

While we're thinking about Secrets and how they're linked, I'd also like to see secrets able to be attached to multiple (one-to-many) devices (and other Django models).

We (in MSP land) often have a single password for a class of device (eg, core switch, routers per each customer managed in TACACS), and so to be able to have this stored once and linked, rather than over and over again against 10's of devices, would be significantly helpful in ensuring that both our Secrets are up to date across the fleet and tracking which devices share a single password (or other form of secret).

I'd be happy to attempt to author a PR for this part of this request if people think it's a good idea.

@jameskirsop commented on GitHub (Aug 27, 2020): While we're thinking about Secrets and how they're linked, I'd also like to see secrets able to be attached to multiple (one-to-many) devices (and other Django models). We (in MSP land) often have a single password for a _class_ of device (eg, core switch, routers per each customer managed in TACACS), and so to be able to have this stored once and linked, rather than over and over again against 10's of devices, would be significantly helpful in ensuring that both our Secrets are up to date across the fleet and tracking which devices share a single password (or other form of secret). I'd be happy to attempt to author a PR for this part of this request if people think it's a good idea.
Author
Owner

@larsuhartmann commented on GitHub (Aug 31, 2020):

I'd be happy to attempt to author a PR for this part of this request if people think it's a good idea.

I second that! Some of our systems have a common admin pw that is rotated by monthly scripts - it would be nice if we could use a one to many relation here!

Also it would be great to be able to "pin" secrets to other objects (ie sites, suppliers etc)

@larsuhartmann commented on GitHub (Aug 31, 2020): > I'd be happy to attempt to author a PR for this part of this request if people think it's a good idea. I second that! Some of our systems have a common admin pw that is rotated by monthly scripts - it would be nice if we could use a one to many relation here! Also it would be great to be able to "pin" secrets to other objects (ie sites, suppliers etc)
Author
Owner

@jameskirsop commented on GitHub (Sep 3, 2020):

Given the two main requests above (secrets linked to other models; secrets linked to multiple objects of the one model) without adopting a third party library, we're stuck with moving to either:

  • Changing to a GenericForeignKey field
  • Allowing secrets to be ManyToMany so that they can be linked to more than one device

and achieving one goal or the other.

It would be good to get this project's leads reading on if both ideas are worth adopting and then working out if using a 3rd party library is a good step forward to achieve this goal. If we can get a consensus on moving forward, I'll be gladly willing to start work on a PR. Being able to link secrets against more than one device is high on my list of things that will greatly help my team.

@jameskirsop commented on GitHub (Sep 3, 2020): Given the two main requests above (secrets linked to other models; secrets linked to multiple objects of the one model) without adopting a [third party library](https://github.com/tkhyn/django-gm2m), we're stuck with moving to either: - Changing to a GenericForeignKey field - Allowing secrets to be ManyToMany so that they can be linked to more than one device and achieving one goal or the other. It would be good to get this project's leads reading on if both ideas are worth adopting and then working out if using a 3rd party library is a good step forward to achieve this goal. If we can get a consensus on moving forward, I'll be gladly willing to start work on a PR. Being able to link secrets against more than one device is high on my list of things that will greatly help my team.
Author
Owner

@jeremystretch commented on GitHub (Sep 18, 2020):

Extending the data model to support assigning a secret to any number of many different types of objects would be a nightmare. The scope of this issue is limited to enabling the assignment of a secret to different types of objects, but to only one object per secret.

If you find yourself needing to associate the same secret to multiple objects, your use case is likely better served by either relying on tags or some other mechanism to infer the association of the secret to the objects, or storing the secret data outside NetBox entirely.

@jeremystretch commented on GitHub (Sep 18, 2020): Extending the data model to support assigning a secret to any number of many different types of objects would be a nightmare. The scope of this issue is limited to enabling the assignment of a secret to different _types_ of objects, but to only one object per secret. If you find yourself needing to associate the same secret to multiple objects, your use case is likely better served by either relying on tags or some other mechanism to infer the association of the secret to the objects, or storing the secret data outside NetBox entirely.
Author
Owner

@jeremystretch commented on GitHub (Sep 18, 2020):

The biggest challenge with supporting broad generic assignment is providing robust form controls. There are essentially two approaches.

Option A: Single view for all assignments

This option presents the user with a single, deterministic URL (e.g. /secrets/secrets/add/) for creating a secret assigned to any object type. This view needs to display a form which allows the user to select both the type of object as well as the specific object being assigned. For example, you might select the "device" type and then select a specific device from all that exist in NetBox.

This is problematic for two reasons. First, we would need to develop a mechanism to dynamically update the API endpoint used to populate the available objects based on the selected object type. We don't have a working example of this in NetBox today, though it's probably not too difficult to get working.

The larger issue is ensuring a sufficiently complete context for the user to select an object. In keeping with the example above, suppose you have seven different devices each named "core1" at each of seven different sites. With no other mechanism for further filtering the list of devices, the user would search for "core1" and see seven identical results. Obviously, this is not very helpful. However, we can't simply add a field to filter by site, because that might not be relevant or sufficient for other object types.

Option B: Discrete view for each object type

An alternative approach is to implement a discrete view for each type of object to which a secret may be assigned. For example, the URL to create a device secret would be something like /dcim/devices/123/secrets/add/. (We currently use this approach for adding image attachments to sites, rack, and devices.)

The biggest downside to this approach is that we can no longer offer a direct view to secret creation: A user won't be able to navigate to secrets -> add secret, because the creation of a secret relies on first having the context of the object to which it is being assigned. This approach also complicates automated testing for the same reason.

Other areas in which we support generic object assignment, such as the assignment of IP addresses to device or VM interfaces, work around this problem by providing fields to specify either object assignment. For example, when creating an IP address, the user is prompted to select either the device or VM tab, depending on the type of assignment being made (if any). This is probably a reasonable approach if we limit the scope of this issue to devices and virtual machines only, however this solution does not scale for more than a few object types.

@jeremystretch commented on GitHub (Sep 18, 2020): The biggest challenge with supporting broad generic assignment is providing robust form controls. There are essentially two approaches. ### Option A: Single view for all assignments This option presents the user with a single, deterministic URL (e.g. `/secrets/secrets/add/`) for creating a secret assigned to _any_ object type. This view needs to display a form which allows the user to select both the type of object as well as the specific object being assigned. For example, you might select the "device" type and then select a specific device from all that exist in NetBox. This is problematic for two reasons. First, we would need to develop a mechanism to dynamically update the API endpoint used to populate the available objects based on the selected object type. We don't have a working example of this in NetBox today, though it's probably not _too_ difficult to get working. The larger issue is ensuring a sufficiently complete context for the user to select an object. In keeping with the example above, suppose you have seven different devices each named "core1" at each of seven different sites. With no other mechanism for further filtering the list of devices, the user would search for "core1" and see seven identical results. Obviously, this is not very helpful. However, we can't simply add a field to filter by site, because that might not be relevant or sufficient for other object types. ### Option B: Discrete view for each object type An alternative approach is to implement a discrete view for each type of object to which a secret may be assigned. For example, the URL to create a device secret would be something like `/dcim/devices/123/secrets/add/`. (We currently use this approach for adding image attachments to sites, rack, and devices.) The biggest downside to this approach is that we can no longer offer a direct view to secret creation: A user won't be able to navigate to secrets -> add secret, because the creation of a secret relies on first having the context of the object to which it is being assigned. This approach also complicates automated testing for the same reason. Other areas in which we support generic object assignment, such as the assignment of IP addresses to device or VM interfaces, work around this problem by providing fields to specify either object assignment. For example, when creating an IP address, the user is prompted to select either the device or VM tab, depending on the type of assignment being made (if any). This is probably a reasonable approach if we limit the scope of this issue to devices and virtual machines only, however this solution does not scale for more than a few object types.
Author
Owner

@jeremystretch commented on GitHub (Sep 18, 2020):

I've created draft PR #5151 to demonstrate extending secret assignment only to virtual machines. Even if we stick with this for v2.10, it does not preclude extension to other objects in future releases.

@jeremystretch commented on GitHub (Sep 18, 2020): I've created draft PR #5151 to demonstrate extending secret assignment only to virtual machines. Even if we stick with this for v2.10, it does not preclude extension to other objects in future releases.
Author
Owner

@candlerb commented on GitHub (Nov 19, 2020):

Extending the data model to support assigning a secret to any number of many different types of objects would be a nightmare. The scope of this issue is limited to enabling the assignment of a secret to different types of objects, but to only one object per secret.

I think that if you want to relate a secret to multiple devices (or VMs), it means you want to share it between a group of similar devices (or VMs).

The current ways to group such things are by Role, and by Tag. Hence, being able to associate a secret with Role and/or Tag would solve that use case.

@candlerb commented on GitHub (Nov 19, 2020): > Extending the data model to support assigning a secret to any number of many different types of objects would be a nightmare. The scope of this issue is limited to enabling the assignment of a secret to different _types_ of objects, but to only one object per secret. I think that if you want to relate a secret to multiple devices (or VMs), it means you want to share it between a *group* of similar devices (or VMs). The current ways to group such things are by Role, and by Tag. Hence, being able to associate a secret with Role and/or Tag would solve that use case.
Author
Owner

@jameskirsop commented on GitHub (Nov 19, 2020):

If you find yourself needing to associate the same secret to multiple objects, your use case is likely better served by either relying on tags or some other mechanism to infer the association of the secret to the objects, or storing the secret data outside NetBox entirely.

Storing the secret outside of Netbox, for the use of Netbox-internal things like the NAPALM integration, would just as equally be a nightmare. We do store these in external systems at times, but then writing middleware to securely extract them so they can be used in the NAPALM authentication process creates even more headaches than the discussion we're having here does (at least for me).

I think that if you want to relate a secret to multiple devices (or VMs), it means you want to share it between a group of similar devices (or VMs).

The current ways to group such things are by Role, and by Tag. Hence, being able to associate a secret with Role and/or Tag would solve that use case.

This assessment is accurate. Typically we (as an MSP) would want to associate a set of credentials for (restricted) NAPALM access (deployed via tac_plus/TACACS+) with a customer and all their devices. This description also applies for credentials for other automated tools that require a login account like Oxidized.

How best to associate a set of credentials with a tag and then display that in the UI and make it accessible internally via Python models/the API is the next hurdle that we would face.

@jeremystretch's options above are interesting approaches. I'm not sure anyone here is suggesting that passwords should be assigned to any object, but only where it is useful to do so. Defining a set of models that we want to be able to relate passwords to should reduce the development, maintenance and testing burdens - and likely make either approach more feasible.

@jameskirsop commented on GitHub (Nov 19, 2020): > If you find yourself needing to associate the same secret to multiple objects, your use case is likely better served by either relying on tags or some other mechanism to infer the association of the secret to the objects, or storing the secret data outside NetBox entirely. Storing the secret outside of Netbox, for the use of Netbox-internal things like the NAPALM integration, would just as equally be a _nightmare_. We do store these in external systems at times, but then writing middleware to securely extract them so they can be used in the NAPALM authentication process creates even more headaches than the discussion we're having here does (at least for me). > I think that if you want to relate a secret to multiple devices (or VMs), it means you want to share it between a _group_ of similar devices (or VMs). > > The current ways to group such things are by Role, and by Tag. Hence, being able to associate a secret with Role and/or Tag would solve that use case. This assessment is accurate. Typically we (as an MSP) would want to associate a set of credentials for (restricted) NAPALM access (deployed via tac_plus/TACACS+) with a customer and all their devices. This description also applies for credentials for other automated tools that require a login account like Oxidized. How best to associate a set of credentials with a tag and then display that in the UI and make it accessible internally via Python models/the API is the next hurdle that we would face. @jeremystretch's options above are interesting approaches. I'm not sure anyone here is suggesting that passwords should be assigned to _any_ object, but only where it is useful to do so. Defining a set of models that we want to be able to relate passwords to should reduce the development, maintenance and testing burdens - and likely make either approach more feasible.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#1238