Mostly solved, largely based on Programmatically adding roles for collaboration groups for RTC in a custom Authenticator - #4 by mr_z_ro. Briefly, here is what I changed:
update_auth_model
: Similar to the “official” RTC instructions, users are now added to “collaborative groups” (same name as the “collaborative users”), primarily so that the list of collaborations is available to thepost_auth_hook
. The role assignments remained the same, but are now also applied to the corresponding “collaborative group”.post_auth_hook
(new): For each group inauth_model["groups"]
, a “collaborative user” (same name as the “collaborative group”) is created usinghandler.auth_to_user
. The user is assigned to acollaborative
group, primarily to distinguish “collaborative users” from “real users” in the downstreampre_spawn_hook
.- Both the “real users” and the “collaborative users” are also explicitly assigned a
user
role containing theself
scope, because authenticator-managed roles override the default role assignments.
Huge thanks to @mr_z_ro for documenting his approach - without this, it would have taken me forever to stumble upon BaseHandler.auth_to_user
and realize that the user
role gets overridden! In general, I think the instructions on Real-time collaboration without impersonation — JupyterHub documentation could benefit from a revamp for authenticator-managed groups/roles following the release of JH5.
Side note: I’ve initially attempted to create the “collaborative users” using the REST API (i.e., created a service with an access token + added a corresponding service role to the authenticator). This didn’t work because of session state etc, but it also took me a while to realize that there was a deadlock when synchronously querying the REST API from within the authenticator (Deadlock when using REST API from Authenticator.post_auth_hook · Issue #3654 · jupyterhub/jupyterhub · GitHub).
Closing.