$user token in permissions constraint not behaving according to documentation #11099

Closed
opened 2025-12-29 21:40:18 +01:00 by adam · 1 comment
Owner

Originally created by @Padnezz on GitHub (Apr 29, 2025).

Deployment Type

Self-hosted

NetBox Version

v4.0.10

Python Version

3.11

Steps to Reproduce

  1. New netbox instance with empty db
  2. Create user u1 with default privileges, active user
  3. Create permissions structure p1 with the following settings:
    --Can view
    --Can edit
    --Object type: Tenancy: Contact assignments
    --User: u1
    --Constraint: {"contact__name": "$user"}
    -With default values in all other choices
  4. Create site s1, with default values in all other choices
  5. Create device role dr1, with default values in all other choices
  6. Create manufacutrer m1, with default values in all other choices
  7. Create device type dv1, using manufacturer m1, with default values in all other choices
  8. Create device d1, using device role dr1, manufacturer m1, device type dv1, with default values in all other choices
  9. Create contact role cr1
  10. Create contact with same name as user u1
  11. Create API key for user u1,
  12. Run API call to assign contact u1 with contact role cr1 to device d1 (All IDs are 1 as we don't expect to have anything else beforehand)
    curl -X 'POST' "${NB_HOST}/api/tenancy/contact-assignments/" -H 'accept: application/json' -H 'Content-Type: application/json' -H "Authorization: Token ${NB_KEY}" -d '{ "object_type": "dcim.device", "object_id": 1,"contact": {"id" : 1},"role": {"id": 1}}'

Expected Behavior

Contact u1 with contact role cr1 is assigned on device d1, using the API key from user u1. This is because the permissions constraint should pass, because the name of contact u1 string equals the username of u1. This happens up until Netbox version v4.0.9.
According to the documentation in https://netboxlabs.com/docs/netbox/en/stable/administration/permissions/ > User Token, we understand that we can use $user as a string value. Our prod instance (Netbox version v3.7.8) is built upon this behavior using contacts and users in the Netbox instance.

Observed Behavior

API instead returns {"detail":"You do not have permission to perform this action."} and no action is performed on the device d1. This happens in Netbox version v4.0.10 and beyond. Setting the string u1 in the permissions constraint instead of $user works though.
We were unable to test the example constraint according to documentation https://netboxlabs.com/docs/netbox/en/stable/administration/permissions/ > User Token as the API does not return a created_by object on dcim.device GET requests.

Is this PR the reason for this? https://github.com/netbox-community/netbox/pull/17268
Should we be using $user another way?

Originally created by @Padnezz on GitHub (Apr 29, 2025). ### Deployment Type Self-hosted ### NetBox Version v4.0.10 ### Python Version 3.11 ### Steps to Reproduce 1. New netbox instance with empty db 2. Create user `u1` with default privileges, active user 3. Create permissions structure `p1` with the following settings: --Can view --Can edit --Object type: Tenancy: Contact assignments --User: u1 --Constraint: `{"contact__name": "$user"}` -With default values in all other choices 4. Create site `s1`, with default values in all other choices 5. Create device role `dr1`, with default values in all other choices 6. Create manufacutrer `m1`, with default values in all other choices 7. Create device type `dv1`, using manufacturer `m1`, with default values in all other choices 8. Create device `d1`, using device role `dr1`, manufacturer `m1`, device type `dv1`, with default values in all other choices 9. Create contact role `cr1` 10. Create contact with same name as user `u1` 11. Create API key for user `u1`, 12. Run API call to assign contact `u1` with contact role `cr1` to device `d1` (All IDs are `1` as we don't expect to have anything else beforehand) `curl -X 'POST' "${NB_HOST}/api/tenancy/contact-assignments/" -H 'accept: application/json' -H 'Content-Type: application/json' -H "Authorization: Token ${NB_KEY}" -d '{ "object_type": "dcim.device", "object_id": 1,"contact": {"id" : 1},"role": {"id": 1}}'` ### Expected Behavior Contact `u1` with contact role `cr1` is assigned on device `d1`, using the API key from user `u1`. This is because the permissions constraint should pass, because the name of contact `u1` string equals the username of `u1`. This happens up until Netbox version `v4.0.9`. According to the documentation in https://netboxlabs.com/docs/netbox/en/stable/administration/permissions/ > _**User Token**_, we understand that we can use `$user` as a string value. Our prod instance (Netbox version `v3.7.8`) is built upon this behavior using contacts and users in the Netbox instance. ### Observed Behavior API instead returns `{"detail":"You do not have permission to perform this action."}` and no action is performed on the device `d1`. This happens in Netbox version `v4.0.10` and beyond. Setting the string `u1` in the permissions constraint instead of `$user` works though. We were unable to test the example constraint according to documentation https://netboxlabs.com/docs/netbox/en/stable/administration/permissions/ > _**User Token**_ as the API does not return a `created_by` object on `dcim.device` GET requests. Is this PR the reason for this? https://github.com/netbox-community/netbox/pull/17268 Should we be using `$user` another way?
adam added the type: bug label 2025-12-29 21:40:18 +01:00
adam closed this issue 2025-12-29 21:40:19 +01:00
Author
Owner

@jeremystretch commented on GitHub (Apr 29, 2025):

The $user token resolves to the current user's numeric ID, not it's username, so attempting to bind a user to a contact in this manner won't work.

You could instead instead add a custom field on the Contact model to establish a relationship to the User model, and assign the contact u1 with the user u1. The update the permission constraint to:

{
    "contact__custom_field_data__user": "$user"
}

Hope that helps. I'm going to close this out as the ability to match on the name of the current user is not supported.

@jeremystretch commented on GitHub (Apr 29, 2025): The `$user` token resolves to the current user's numeric ID, not it's username, so attempting to bind a user to a contact in this manner won't work. You could instead instead add a custom field on the Contact model to establish a relationship to the User model, and assign the contact `u1` with the user `u1`. The update the permission constraint to: ``` { "contact__custom_field_data__user": "$user" } ``` Hope that helps. I'm going to close this out as the ability to match on the name of the current user is not supported.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/netbox#11099