Generate API token with fixed scope before launching server?

I have some Javascript charts that I display to the users on their spawn page, so they can see how busy the server is before they spawn.

The JS makes a fetch request to access a custom endpoint I made (/hub/sysmon) which requires a read:users scope-level token.

My current method of getting this token is to spawn the server, register a new token with that scope via the UI, copy the token, and then modify the JS that makes the fetch request to use that token.

I wish to do this more dynamically (i.e. define/generate a token with read:users scope beforehand, register it with JupyterHub, and use it within my JS).

I’ve seen register api tokens via configuration in the Docs.

I’ve seen that I can define c.JupyterHub.services, but the API tokens we generate here via openssl do not seem to have a scope, except for either admin or non-admin.

I’ve seen that I can define c.JupyterHub.load_roles, which do define scopes, but don’t let you define an API token before hand.

Would I need to define both to make this work, e.g.:

c.JupyterHub.load_roles = [{
        "name": "getmetrics",
        "scopes": ["read:users"]
    }]
c.JupyterHub.services = [{
        'name': 'getmetrics',
        'api_token': <openssl key>
    }]

?

Yes, a role is really a name for a bundle of scopes. Services can be assigned to one or more roles. So the way to create a single token with specific scopes is just what you said, with one missing line: assign the service to the role:

c.JupyterHub.load_roles = [
    {
        "name": "getmetrics",
        "scopes": ["read:users"],
        "services": ["getmetrics"], # <--- this is where the service 'getmetrics' is assigned the role 'getmetrics'
    }
]
c.JupyterHub.services = [
    {
        "name": "getmetrics",
        "api_token": "<openssl key>",
    }
]
1 Like

Thank you, it works perfectly