Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
elmmare opened this issue Sep 18, 2017 · 23 comments
Closed

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

elmmare opened this issue Sep 18, 2017 · 23 comments
Assignees
Labels
status: accepted This issue has been accepted for implementation type: feature Introduction of new functionality to the application
Milestone

Comments

@elmmare
Copy link

elmmare commented Sep 18, 2017

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

@jeremystretch jeremystretch changed the title Assign secret to Sites and racks Allow the assignment of secrets to objects other than devices Sep 20, 2017
@jeremystretch
Copy link
Member

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.

@darkstar
Copy link

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.

@rlaneyjr
Copy link

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.

@jeremystretch
Copy link
Member

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.

@linasjan
Copy link

Secrets for tenants also would be appreciated.

@larsuhartmann
Copy link

This feature would be highly apreciated!

@c0dyhi11
Copy link

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

@etfeet
Copy link

etfeet commented 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?

@jeremystretch jeremystretch added the status: accepted This issue has been accepted for implementation label Jan 26, 2018
@larsuhartmann
Copy link

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 :)

@c0dyhi11
Copy link

c0dyhi11 commented Apr 4, 2018 via email

@jsenecal
Copy link
Contributor

jsenecal commented 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.

@orgito
Copy link

orgito commented Jun 29, 2018

It also makes sense to attach secrets to VMs and clusters

@arionl
Copy link

arionl commented 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..

@netbox-community netbox-community deleted a comment from cusooner Apr 2, 2019
@netbox-community netbox-community deleted a comment from michalholis Jun 5, 2019
@hpreston
Copy link

hpreston commented 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...

@DanSheps
Copy link
Member

DanSheps commented 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.

@netbox-community netbox-community deleted a comment from davidc Sep 3, 2019
@netbox-community netbox-community deleted a comment from steinbachio Sep 3, 2019
@jeremystretch jeremystretch added this to the v2.9 milestone Mar 11, 2020
@jeremystretch jeremystretch modified the milestones: v2.9, v2.10 Jun 10, 2020
@jeremystretch jeremystretch added type: feature Introduction of new functionality to the application and removed type: minor feature labels Jul 24, 2020
@jameskirsop
Copy link

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.

@larsuhartmann
Copy link

larsuhartmann commented 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)

@jameskirsop
Copy link

jameskirsop commented 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.

@jeremystretch
Copy link
Member

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 jeremystretch self-assigned this Sep 18, 2020
@jeremystretch
Copy link
Member

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
Copy link
Member

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 added a commit that referenced this issue Sep 21, 2020
jeremystretch added a commit that referenced this issue Sep 22, 2020
#1503: Extend secrets assignment to virtual machines
@candlerb
Copy link
Contributor

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.

@jameskirsop
Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 18, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
status: accepted This issue has been accepted for implementation type: feature Introduction of new functionality to the application
Projects
None yet