mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-17 06:52:59 +00:00
Merge pull request #3833 from minrk/token-scopes
Tokens have scopes instead of roles
This commit is contained in:
@@ -560,7 +560,19 @@ paths:
|
||||
description: A note attached to the token for future bookkeeping
|
||||
roles:
|
||||
type: array
|
||||
description: A list of role names that the token should have
|
||||
description: |
|
||||
A list of role names from which to derive scopes.
|
||||
This is a shortcut for assigning collections of scopes;
|
||||
Tokens do not retain role assignment.
|
||||
(Changed in 2.3: roles are immediately resolved to scopes
|
||||
instead of stored on roles.)
|
||||
items:
|
||||
type: string
|
||||
scopes:
|
||||
type: array
|
||||
description: |
|
||||
A list of scopes that the token should have.
|
||||
(new in JupyterHub 2.3).
|
||||
items:
|
||||
type: string
|
||||
required: false
|
||||
@@ -1314,7 +1326,16 @@ components:
|
||||
description: The service that owns the token (undefined of owned by a user)
|
||||
roles:
|
||||
type: array
|
||||
description: The names of roles this token has
|
||||
description:
|
||||
Deprecated in JupyterHub 2.3, always an empty list. Tokens
|
||||
have 'scopes' starting from JupyterHub 2.3.
|
||||
items:
|
||||
type: string
|
||||
scopes:
|
||||
type: array
|
||||
description:
|
||||
List of scopes this token has been assigned. New in JupyterHub
|
||||
2.3. In JupyterHub 2.0-2.2, tokens were assigned 'roles' insead of scopes.
|
||||
items:
|
||||
type: string
|
||||
note:
|
||||
|
@@ -41,7 +41,7 @@ Services do not have a default role. Services without roles have no access to th
|
||||
A group does not require any role, and has no roles by default. If a user is a member of a group, they automatically inherit any of the group's permissions (see {ref}`resolving-roles-scopes-target` for more details). This is useful for assigning a set of common permissions to several users.
|
||||
|
||||
**Tokens** \
|
||||
A token’s permissions are evaluated based on their owning entity. Since a token is always issued for a user or service, it can never have more permissions than its owner. If no specific role is requested for a new token, the token is assigned the `token` role.
|
||||
A token’s permissions are evaluated based on their owning entity. Since a token is always issued for a user or service, it can never have more permissions than its owner. If no specific scopes are requested for a new token, the token is assigned the `token` role.
|
||||
|
||||
(define-role-target)=
|
||||
|
||||
|
@@ -7,11 +7,11 @@ Roles and scopes utilities can be found in `roles.py` and `scopes.py` modules. S
|
||||
```{admonition} **Scope variable nomenclature**
|
||||
:class: tip
|
||||
- _scopes_ \
|
||||
List of scopes with abbreviations (used in role definitions). E.g., `["users:activity!user"]`.
|
||||
List of scopes that may contain abbreviations (used in role definitions). E.g., `["users:activity!user", "self"]`.
|
||||
- _expanded scopes_ \
|
||||
Set of expanded scopes without abbreviations (i.e., resolved metascopes, filters and subscopes). E.g., `{"users:activity!user=charlie", "read:users:activity!user=charlie"}`.
|
||||
Set of fully expanded scopes without abbreviations (i.e., resolved metascopes, filters, and subscopes). E.g., `{"users:activity!user=charlie", "read:users:activity!user=charlie"}`.
|
||||
- _parsed scopes_ \
|
||||
Dictionary JSON like format of expanded scopes. E.g., `{"users:activity": {"user": ["charlie"]}, "read:users:activity": {"users": ["charlie"]}}`.
|
||||
Dictionary represenation of expanded scopes. E.g., `{"users:activity": {"user": ["charlie"]}, "read:users:activity": {"users": ["charlie"]}}`.
|
||||
- _intersection_ \
|
||||
Set of expanded scopes as intersection of 2 expanded scope sets.
|
||||
- _identify scopes_ \
|
||||
@@ -32,17 +32,29 @@ Roles and scopes are resolved on several occasions, for example when requesting
|
||||
|
||||
### Requesting API token with specific roles
|
||||
|
||||
API tokens grant access to JupyterHub's APIs. The RBAC framework allows for requesting tokens with specific existing roles. To date, it is only possible to add roles to a token through the _POST /users/:name/tokens_ API where the roles can be specified in the token parameters body (see [](../reference/rest-api.rst)).
|
||||
:::{versionchanged} 2.3
|
||||
API tokens have _scopes_ instead of roles,
|
||||
so that their permissions cannot be updated.
|
||||
|
||||
You may still request roles for a token,
|
||||
but those roles will be evaluated to the corresponding _scopes_ immediately.
|
||||
:::
|
||||
|
||||
API tokens grant access to JupyterHub's APIs. The RBAC framework allows for requesting tokens with specific permissions.
|
||||
As of JupyterHub 2.3, it is only possible to specify scopes for a token through the _POST /users/:name/tokens_ API where the scopes can be specified in the token parameters body (see [](../reference/rest-api.rst)).
|
||||
|
||||
RBAC adds several steps into the token issue flow.
|
||||
|
||||
If no roles are requested, the token is issued with the default `token` role (providing the requester is allowed to create the token).
|
||||
If no scopes are requested, the token is issued with the permissions stored on the default `token` role
|
||||
(providing the requester is allowed to create the token).
|
||||
|
||||
If the token is requested with any roles, the permissions of requesting entity are checked against the requested permissions to ensure the token would not grant its owner additional privileges.
|
||||
If the token is requested with any scopes, the permissions of requesting entity are checked against the requested permissions to ensure the token would not grant its owner additional privileges.
|
||||
|
||||
If, due to modifications of roles or entities, at API request time a token has any scopes that its owner does not, those scopes are removed. The API request is resolved without additional errors using the scopes _intersection_, but the Hub logs a warning (see {ref}`Figure 2 <api-request-chart>`).
|
||||
If, due to modifications of roles or entities, at API request time a token has any scopes that its owner does not, those scopes are removed.
|
||||
The API request is resolved without additional errors using the scope _intersection_,
|
||||
but the Hub logs a warning (see {ref}`Figure 2 <api-request-chart>`).
|
||||
|
||||
Resolving a token's roles (yellow box in {ref}`Figure 1 <token-request-chart>`) corresponds to resolving all the token's owner roles (including the roles associated with their groups) and the token's requested roles into a set of scopes. The two sets are compared (Resolve the scopes box in orange in {ref}`Figure 1 <token-request-chart>`), taking into account the scope hierarchy but, solely for role assignment, omitting any {ref}`horizontal filter <horizontal-filtering-target>` comparison. If the token's scopes are a subset of the token owner's scopes, the token is issued with the requested roles; if not, JupyterHub will raise an error.
|
||||
Resolving a token's scope (yellow box in {ref}`Figure 1 <token-request-chart>`) corresponds to resolving all the token's owner roles (including the roles associated with their groups) and the token's requested roles into a set of scopes. The two sets are compared (Resolve the scopes box in orange in {ref}`Figure 1 <token-request-chart>`), taking into account the scope hierarchy but, solely for role assignment, omitting any {ref}`horizontal filter <horizontal-filtering-target>` comparison. If the token's scopes are a subset of the token owner's scopes, the token is issued with the requested roles; if not, JupyterHub will raise an error.
|
||||
|
||||
{ref}`Figure 1 <token-request-chart>` below illustrates the steps involved. The orange rectangles highlight where in the process the roles and scopes are resolved.
|
||||
|
||||
|
Reference in New Issue
Block a user