Authentication Guide#

This guide covers the dual authentication system and user management for AUP Learning Cloud.

Table of Contents#

  • Overview

  • Authentication Methods

  • Configuration

  • Admin Management

  • User Management

  • Deployment

  • Troubleshooting

Overview#

AUP Learning Cloud supports dual authentication to accommodate different user types:

  1. GitHub OAuth: For technical teams and organization members

  2. Native Authenticator: For students and external users (admin-managed accounts)

Key Features#

  • Auto-admin on install: Initial admin created automatically with random password

  • No self-registration: Only admins can create native accounts

  • Individual passwords: Each user has their own password (can be changed)

  • Unified admin panel: All users managed in /hub/admin

  • Batch operations: CSV/Excel-based bulk user management

  • Script-based admin management: Use set-admin command

Authentication Methods#

Comparison#

Feature

GitHub OAuth

Native Authenticator

User Type

Technical teams, org members

Students, external users

Account Creation

GitHub organization invite

Admin creates manually

Password

Managed by GitHub

User-defined (changeable)

Access Control

Based on GitHub teams

Based on username patterns or groups

Best For

Staff, developers, researchers

Course students, temporary users

Login Flow#

Users see a combined login page with GitHub OAuth button and native login form:

+-------------------------------+
|  JupyterHub Login              |
+-------------------------------+
|  [ Sign in with GitHub ]       | <-- GitHub OAuth
|                                |
|  --- Or use local account ---  |
|                                |
|  Username: [____________]      |
|  Password: [____________]      | <-- Native Auth
|  [ Sign In ]                   |
+-------------------------------+

Configuration#

Get Credentials After Install#

# Get admin password
kubectl -n jupyterhub get secret jupyterhub-admin-credentials \
  -o go-template='{{index .data "admin-password" | base64decode}}'

# Get API token for scripts
export JUPYTERHUB_TOKEN=$(kubectl -n jupyterhub get secret jupyterhub-admin-credentials \
  -o go-template='{{index .data "api-token" | base64decode}}')

Resource Access Mapping#

Configure which resources different user groups can access in values.yaml:

custom:
  teams:
    mapping:
      cpu:
        - cpu
      gpu:
        - Course-CV
        - Course-DL
        - Course-LLM
      official:
        - cpu
        - Course-CV
        - Course-DL
        - Course-LLM
      native-users:
        - Course-CV
        - Course-DL
        - Course-LLM

Native Authenticator Settings#

The CustomFirstUseAuthenticator class settings:

class CustomFirstUseAuthenticator(FirstUseAuthenticator):
    service_name = "Native"
    create_users = False  # Only admin-created users can login

Important: create_users = False prevents users from creating accounts themselves. Users must be created by an admin first.

Admin Management#

Initial Admin#

Created automatically on helm install when custom.adminUser.enabled: true.

Adding More Admins#

Use the set-admin command (NOT config files):

# Grant admin to users
python scripts/manage_users.py set-admin teacher01 teacher02

# Grant admin from file
python scripts/manage_users.py set-admin -f new_admins.csv

# Revoke admin
python scripts/manage_users.py set-admin --revoke student01

Or via Admin Panel (/hub/admin):

  1. Click username

  2. Check “Admin” checkbox

  3. Save

Admin Users Summary#

Method

When to Use

custom.adminUser.enabled: true

Initial admin on install

manage_users.py set-admin

Add/remove admins later

Admin Panel /hub/admin

Quick single-user changes

User Management#

Prerequisites#

Install required dependencies:

pip install pandas openpyxl requests

Set environment variables:

export JUPYTERHUB_URL="http://localhost:30890"  # Or your hub URL
export JUPYTERHUB_TOKEN=$(kubectl -n jupyterhub get secret jupyterhub-admin-credentials \
  -o go-template='{{index .data "api-token" | base64decode}}')

Batch User Operations#

For detailed batch user management, see User Management Guide.

Quick Reference:

# Generate user template
python scripts/generate_users_template.py --prefix student --count 50 --output users.csv

# Create users from file
python scripts/manage_users.py create users.csv

# List all users
python scripts/manage_users.py list

# Grant admin privileges
python scripts/manage_users.py set-admin teacher01 teacher02

# Revoke admin privileges
python scripts/manage_users.py set-admin --revoke student01

# Export/backup users
python scripts/manage_users.py export backup.xlsx

# Delete users
python scripts/manage_users.py delete remove_list.csv

Manual User Management#

Via JupyterHub Admin Panel (/hub/admin):

  1. Add single user: Click “Add Users” button

  2. Delete user: Click username -> “Delete User”

  3. Make admin: Click username -> Check “Admin” -> “Save”

  4. Stop user server: Click “Stop Server” button

Deployment#

1. Update Hub Image#

The Hub Docker image must include the jupyterhub-nativeauthenticator dependency.

File: dockerfiles/Hub/Dockerfile

RUN pip install jupyterhub-multiauthenticator jupyterhub-firstuseauthenticator

2. Rebuild Hub Image#

cd dockerfiles/Hub
./build.sh

# Or manually:
docker build -t ghcr.io/amdresearch/auplc-hub:latest .
docker push ghcr.io/amdresearch/auplc-hub:latest

3. Update Helm Values#

File: runtime/values.yaml

custom:
  adminUser:
    enabled: true

hub:
  image:
    name: ghcr.io/amdresearch/auplc-hub
    tag: latest

4. Deploy or Upgrade#

cd runtime
helm upgrade jupyterhub ./chart -n jupyterhub -f values.yaml

Or using the installer:

sudo ./auplc-installer rt upgrade

5. Verify Deployment#

# Check hub pod is running
kubectl --namespace=jupyterhub get pods

# Check hub logs for admin setup
kubectl --namespace=jupyterhub logs deployment/hub | grep -i admin

# Get admin password
kubectl -n jupyterhub get secret jupyterhub-admin-credentials \
  -o jsonpath='{.data.admin-password}' | base64 -d && echo

Troubleshooting#

Issue: “Module ‘nativeauthenticator’ not found”#

Cause: Hub image doesn’t have jupyterhub-nativeauthenticator installed.

Solution:

# Rebuild Hub image with updated Dockerfile
cd dockerfiles/Hub
./build.sh

Issue: Users can self-register#

Cause: create_users is not set to False.

Solution: Verify in jupyterhub_config.py:

class CustomFirstUseAuthenticator(FirstUseAuthenticator):
    create_users = False

Issue: API token authentication fails#

Symptoms:

Connection failed with status 403

Solutions:

  1. Verify secret exists:

    kubectl -n jupyterhub get secret jupyterhub-admin-credentials
    
  2. Check token is loaded:

    kubectl -n jupyterhub logs deployment/hub | grep "API token"
    
  3. Regenerate credentials:

    kubectl -n jupyterhub delete secret jupyterhub-admin-credentials
    helm upgrade jupyterhub ./chart -n jupyterhub -f values.yaml
    

Issue: Admin not created on install#

Symptoms: No admin user after helm install.

Solutions:

  1. Verify config:

    custom:
      adminUser:
        enabled: true  # Must be true
    
  2. Check hub logs:

    kubectl -n jupyterhub logs deployment/hub | grep -i "admin"
    
  3. Restart hub:

    kubectl -n jupyterhub rollout restart deployment/hub
    

Issue: Wrong resource permissions#

Symptoms: User sees courses they shouldn’t access, or missing expected courses.

Solution: Check resource mapping in values.yaml:

custom:
  teams:
    mapping:
      gpu:
        - Course-CV
        - Course-DL
        - Course-LLM
      # Verify user's team membership in GitHub org

Issue: Users created but can’t login#

Cause: Native users must set password on first login.

Solution:

  1. User should go to login page

  2. Enter username created by admin

  3. Enter desired password

  4. Password is saved for future logins

Alternative: Set passwords via script:

python scripts/manage_users.py set-passwords users.csv --generate

Issue: Batch script fails to connect#

Symptoms:

Connection error: Connection refused

Solutions:

  1. Verify JupyterHub URL:

    # For local dev
    export JUPYTERHUB_URL="http://localhost:30890"
    
    # For production
    export JUPYTERHUB_URL="https://your-domain.com"
    
  2. Check if hub is accessible:

    curl $JUPYTERHUB_URL/hub/api/
    
  3. Verify namespace and port forwarding (if using kubectl):

    kubectl --namespace=jupyterhub port-forward service/hub 8081:8081
    export JUPYTERHUB_URL="http://localhost:8081"
    

Security Best Practices#

  1. Protect API tokens:

    • Tokens are stored in Kubernetes secrets

    • Never commit tokens to git

    • Rotate tokens by deleting and recreating the secret

  2. User password policy:

    • Encourage strong passwords

    • Consider adding password complexity requirements

  3. Admin accounts:

    • Limit number of admin users

    • Use set-admin command to manage (auditable)

    • Review admin list regularly

  4. GitHub App:

    • Create the App under the organization, not a personal account

    • Keep GitHub organization membership updated

    • Review team permissions regularly

    • Set scope: [] – permissions are configured in the App settings

Additional Resources#