# AccessToken does not have the expected scope users!user - Access to Custom API not possible

**URL:** <https://discourse.jupyter.org/t/accesstoken-does-not-have-the-expected-scope-users-user-access-to-custom-api-not-possible/34571>\
**Category:** JupyterHub\
**Tags:** jupyterhub, help-wanted\
**Created:** [April 14, 2025, 2:14pm UTC](https://discourse.jupyter.org/t/accesstoken-does-not-have-the-expected-scope-users-user-access-to-custom-api-not-possible/34571 "2025-04-14T14:14:02Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![LeafLikeApple](https://avatars.discourse-cdn.com/v4/letter/l/c77e96/32.png) [@LeafLikeApple](https://discourse.jupyter.org/u/LeafLikeApple)\
**Post date:** [April 14, 2025, 2:14pm UTC](https://discourse.jupyter.org/t/accesstoken-does-not-have-the-expected-scope-users-user-access-to-custom-api-not-possible/34571/1 "2025-04-14T14:14:02Z")

</div>

Hello everyone,

in an external tool the users should be able to enter their own information, for this I have written my own handler, which inherits from `APIHandler`.  
I have given the routes `@needs_scope(“users”)`.

As far as I understand the documentation, a user should have the scope `users!user=NAME`. But, when I create an AccessToken for the user, this token does not have the scope.  
I get this message when I try to access the new route:  
`Action is not authorised with current scopes; requires any of [users]`.  
But when I pass `users!user=NAME` as scope in the token creation process, I get this message:  
`Not assigning requested scopes users!user=NAME,list:users!user=NAME not held by User NAME`  
Am I missing something with the scopes function?

Many thanks for your help

---

<div class="post-metadata">

**Author:** ![minrk](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/minrk/32/13_2.png) [@minrk](https://discourse.jupyter.org/u/minrk)\
**Post date:** [April 23, 2025, 7:50am UTC](https://discourse.jupyter.org/t/accesstoken-does-not-have-the-expected-scope-users-user-access-to-custom-api-not-possible/34571/2 "2025-04-23T07:50:46Z")

</div>

Can you describe more about what you are trying to do? `@needs_scope` and `APIHandler` are for internal implementation of JupyterHub, not for use in external Services implementations.

Users do not have the scope `users!user=NAME` by default. What sort of actions are you trying to accomplish that `users` is the right scope to require? Maybe a more specific [scope](https://jupyterhub.readthedocs.io/en/stable/rbac/scopes.html#available-scopes) that users actually do have will suffice. If you really want to grant users greater permissions than the default, you can set permissions for all users by adding scopes to the `user` role.

---

<div class="post-metadata">

**Author:** ![LeafLikeApple](https://avatars.discourse-cdn.com/v4/letter/l/c77e96/32.png) [@LeafLikeApple](https://discourse.jupyter.org/u/LeafLikeApple)\
**Post date:** [April 30, 2025, 9:39am UTC](https://discourse.jupyter.org/t/accesstoken-does-not-have-the-expected-scope-users-user-access-to-custom-api-not-possible/34571/3 "2025-04-30T09:39:22Z")

</div>

It’s a bit complicated, but I’ll try to describe it as best I can.  
I have a tool A, which stores additional information about the users, e.g. users can create their own profiles. JupyterHub has read and write access to it. This runs within Kubernetes.  
Now an external tool B should use the API of JupyterHub to create new users, create tokens for the user. In addition, the user should be able to change the data of Tool A using the AccessToken. For this purpose, I have written my own handler, which inherits from `APiHandler` and which can access Tool A.  
Maybe I don’t need `@needs_scope` then, because the user is already authenticated by AccessToken and I was just thinking too complicated?

---

<div class="post-metadata">

**Author:** ![minrk](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.jupyter.org/minrk/32/13_2.png) [@minrk](https://discourse.jupyter.org/u/minrk)\
**Post date:** [April 30, 2025, 11:10am UTC](https://discourse.jupyter.org/t/accesstoken-does-not-have-the-expected-scope-users-user-access-to-custom-api-not-possible/34571/4 "2025-04-30T11:10:48Z")

</div>

For writing a Service, you probably shouldn’t import anything outside `jupyterhub.services.auth`. The handler classes etc. are not for use in any external integrations like tool A or tool B. `APIHandler` assumes it is part of JupyterHub itself with access to lots of private internal state, and there is no supported mechanism to add API endpoints within the Hub (it’s not technically impossible, but it’s not supported and never required).

So the first step is: don’t use the private JupyterHub Handler classes in your services. You can use Hub[O]Auth to authenticate with the Hub and [check\_scopes](https://jupyterhub.readthedocs.io/en/latest/reference/api/services.auth.html#jupyterhub.services.auth.HubAuth.check_scopes) for checking if the authenticated user has the required scopes. I don’t know what scopes you want to check for with the information you’ve provided, but for services the `access:services!service=service_name` scope (the default access scope for a service) is usually enough. You only need to get finer grained than that if some users should have different permissions than others _when talking to your service_. You can check out some of the [services examples](https://github.com/jupyterhub/jupyterhub/tree/5.3.0/examples/service-whoami) to see how authenticating with the Hub might look.
