## TL;DR

Add the username to the authenticator allow list (or remove the restriction) so the spawn request is authorized.
Set c.Authenticator.allowed_users to include the user, or c.Authenticator.admin_users for admins, then restart the hub.
The 403 comes from authorization, not authentication: the user logged in fine but is not permitted to launch a server.

```text
jupyterhub 403 forbidden: user not in the allowed list for this server
```

## Use this when

- Login succeeds but the spawn page or API returns 403 forbidden
- New team members get 403 while existing users spawn normally
- The message mentions the user not being in the allowed list

## Not for this skill when

- The 403 appears on the OAuth callback before login completes - that is item 104
- Spawn starts then fails with a timeout - that is item 100
- All users including admins get errors - that is a hub outage, not an allow list

## Steps

1. Confirm the exact 403 source in the hub log: kubectl logs -n YOUR_NAMESPACE deploy/hub | grep -i 'not in allowed'.
   Expected: a line naming the user and the allow-list check.

2. Open the hub config (config.yaml for Zero to JupyterHub) and add the user: hub: config: Authenticator: allowed_users: [username1, username2].
   Expected: the config file contains every user who should spawn.

3. If the whole org should have access, replace the allow list with an open policy or drive it from the OAuth group claim, for example c.Authenticator.manage_groups and group-based spawn rights.
   Expected: new users stop needing manual list edits.

4. Apply with helm upgrade and wait for the hub pod to restart.
   Expected: kubectl get pods shows the hub pod Running with a fresh start time.

5. Log in as the affected user and click Start My Server.
   Expected: spawn proceeds past the 403 and the pod enters Pending then Running.

## Tool compatibility

JupyterHub 4.x / 5.x, Zero to JupyterHub chart 3.x / 4.x, any Authenticator (Dummy, OAuthenticator, LDAP)

## Variant phrasings

### JupyterHub 403 user not authorized to spawn server

Same fix applies: see the Steps section above.

### JupyterHub forbidden after login for new user

Same fix applies: see the Steps section above.

### allowed_users 403 on singleuser server start

Same fix applies: see the Steps section above.

## Why it happens

JupyterHub separates authentication (who you are) from authorization (what you may do). When allowed_users is set, any authenticated user outside the set gets a 403 at spawn time even though login succeeded. This commonly bites after onboarding: the identity provider accepts the user, so login looks healthy, but the hub-side list was never updated. Admins bypass it only if they are also in admin_users. Group-based authenticators move the membership decision to the identity provider so the hub config stops being a manual roster.

## Edge cases / pitfalls

- allowed_users is case-sensitive; '[recipient email]' and '[recipient email]' are different entries.
- Some OAuth providers normalize usernames differently than the hub expects; compare the hub log username against the list.
- Removing the allow list entirely opens spawn to anyone who can authenticate, which may surprise cost owners.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_x21L1daUjvm1539Lqe2bdA
