Skip to main content

appkit-user

Python 3.13+ License: MIT

Enterprise user management and authentication for Reflex applications.

appkit-user provides comprehensive user authentication, authorization, and management capabilities for Reflex applications. It includes OAuth2 integration with GitHub and Azure, role-based access control (RBAC), multi-tenant user profiles, and secure session management.


✨ Features

  • OAuth2 Authentication - GitHub and Azure OAuth2 providers with PKCE support
  • Role-Based Access Control - Flexible RBAC with custom roles and permissions
  • Multi-Tenant Support - User profiles organized by tenants and projects
  • Session Management - Secure session handling with automatic cleanup
  • User Management UI - Complete admin interface for user CRUD operations
  • Authentication Decorators - Easy-to-use decorators for protecting routes and components
  • Profile Management - User profile editing with role assignment
  • Security Features - CSRF protection, secure redirects, and session validation

🚀 Installation

As Part of AppKit Workspace

If you're using the full AppKit workspace:

git clone https://github.com/jenreh/appkit.git
cd appkit
uv sync

Standalone Installation

Install from PyPI:

pip install appkit-user

Or with uv:

uv add appkit-user

Dependencies

  • greenlet>=3.2.4 (async utilities)
  • appkit-commons (shared utilities)
  • appkit-ui (UI components)
  • requests_oauthlib>=2.0.0 (OAuth2 client)

🏁 Quick Start

Basic OAuth Configuration

Configure OAuth providers in your application:

from appkit_user.configuration import GithubOAuthConfig, AzureOAuthConfig

# GitHub OAuth
github_config = GithubOAuthConfig(
    client_id="your-github-client-id",
    client_secret="secret:github-client-secret",
    redirect_url="http://localhost:3000/auth/github/callback",
)

# Azure OAuth
azure_config = AzureOAuthConfig(
    client_id="your-azure-client-id",
    client_secret="secret:azure-client-secret",
    tenant_id="your-tenant-id",
    redirect_url="http://localhost:3000/auth/azure/callback",
)

Protecting Routes

Use authentication decorators to protect your pages:

import reflex as rx
from appkit_user.authentication.components import requires_authenticated, requires_role


# Require authentication
@requires_authenticated
def protected_page():
    return rx.text("This page requires login")


# Require specific role
@requires_role("admin")
def admin_page():
    return rx.text("Admin only content")


# Require admin privileges
@requires_admin
def super_admin_page():
    return rx.text("Super admin content")

Login Integration

Add login functionality to your app:

from appkit_user.authentication.components import login_form


def login_page():
    return login_form(
        header="My App", logo="/img/logo.svg", logo_dark="/img/logo_dark.svg"
    )

📖 Usage

OAuth Configuration

GitHub OAuth

Configure GitHub OAuth application:

from appkit_user.configuration import GithubOAuthConfig

config = GithubOAuthConfig(
    client_id="gh_oauth_client_id",
    client_secret="secret:github_oauth_secret",
    redirect_url="https://myapp.com/auth/github/callback",
    scopes=["user", "user:email", "read:org"],  # Optional custom scopes
)

Azure OAuth

Configure Azure AD application:

from appkit_user.configuration import AzureOAuthConfig

config = AzureOAuthConfig(
    client_id="azure_client_id",
    client_secret="secret:azure_client_secret",
    tenant_id="tenant-id",  # or "common" for multi-tenant
    redirect_url="https://myapp.com/auth/azure/callback",
    is_public_client=False,  # Set to True for PKCE-only apps
    scopes=["openid", "profile", "email", "User.Read"],
)

Authentication Decorators

Basic Authentication

from appkit_user.authentication.components import requires_authenticated


@requires_authenticated
def dashboard():
    return rx.text("Welcome to your dashboard!")

Role-Based Access

from appkit_user.authentication.components import requires_role


@requires_role("editor")
def content_editor():
    return rx.text("Content editor interface")


@requires_role("viewer", fallback=rx.text("Access denied"))
def reports():
    return rx.text("Reports dashboard")

Admin Access

from appkit_user.authentication.components import requires_admin


@requires_admin
def admin_panel():
    return rx.text("Admin control panel")

User Management

User Table

Display and manage users:

from appkit_user.user_management.components import users_table
from appkit_user.user_management.states.user_states import UserState


# users_table does not fetch on its own; load users via the page's on_load.
@rx.page(route="/admin/users", on_load=UserState.load_users)
def user_management_page():
    return rx.vstack(rx.heading("User Management"), users_table(), spacing="4")

User Profile

Manage user profiles and roles:

from appkit_user.user_management.components import profile_roles, profile_state


def user_profile_page():
    return rx.vstack(rx.heading("User Profile"), profile_roles(), spacing="4")

Session Management

Access current user session:

from appkit_user.authentication.states import UserSession


def current_user_info():
    return rx.vstack(
        rx.text(f"User: {UserSession.user.email}"),
        rx.text(f"Roles: {UserSession.user.roles}"),
        rx.text(f"Tenant: {UserSession.user.tenant_id}"),
        rx.text(f"Authenticated: {UserSession.is_authenticated}"),
    )

🔧 Configuration

OAuth Redirect URLs

Configure OAuth callback URLs in your Reflex app:

# In rxconfig.py or main app file
app.add_page(oauth_login_splash, route="/auth/github/callback", title="GitHub Login")

app.add_page(oauth_login_splash, route="/auth/azure/callback", title="Azure Login")

Custom OAuth Providers

Extend OAuth support for custom providers:

from appkit_user.configuration import OAuthConfig, OAuthProvider


class CustomOAuthConfig(OAuthConfig):
    provider: OAuthProvider = "custom"
    auth_url: str = "https://custom.provider.com/oauth/authorize"
    token_url: str = "https://custom.provider.com/oauth/token"
    user_url: str = "https://custom.provider.com/api/user"
    scopes: list[str] = ["read", "write"]

Multi-Tenant Setup

Configure tenant-based user isolation:

# Users are automatically scoped by tenant_id
# Access current tenant
current_tenant = UserSession.user.tenant_id

# Filter data by tenant
tenant_users = get_users_by_tenant(current_tenant)

📋 API Reference

Authentication Components

  • requires_authenticated() - Decorator for authentication-required content
  • requires_role() - Decorator for role-based access control
  • requires_admin() - Decorator for admin-only content
  • login_form() - Login form with OAuth providers
  • oauth_login_splash() - OAuth callback splash screen
  • default_fallback() - Default unauthorized access message

User Management Components

  • users_table() - User management table with CRUD operations
  • add_user_button() - Button to add new users
  • update_user_button() - Button to edit existing users
  • delete_user_button() - Button to remove users
  • user_form_fields() - Form fields for user creation/editing
  • profile_roles() - User profile role management
  • profile_state() - User profile state management

Configuration Classes

  • OAuthConfig - Base OAuth configuration
  • GithubOAuthConfig - GitHub OAuth settings
  • AzureOAuthConfig - Azure AD OAuth settings
  • OAuthProvider - Enum of supported OAuth providers

State Management

  • UserSession - Current user session state
  • LoginState - Login form state management

🔒 Security

  • OAuth2 PKCE Support - Proof Key for Code Exchange for enhanced security
  • Secure Redirects - Configurable redirect URLs prevent open redirect attacks
  • Session Security - Automatic session cleanup and validation
  • CSRF Protection - Built-in CSRF tokens for forms
  • Role Validation - Server-side role checking in addition to client-side decorators
  • Tenant Isolation - Multi-tenant data isolation prevents cross-tenant access

🤝 Integration Examples

Complete Authentication Flow

Set up a full authentication system:

import reflex as rx
from appkit_user.authentication.components import (
    login_form,
    requires_authenticated,
    oauth_login_splash,
)
from appkit_user.configuration import GithubOAuthConfig

# Configure OAuth
oauth_config = GithubOAuthConfig(
    client_id="your-client-id", client_secret="secret:your-client-secret"
)


# Public login page
def login():
    return login_form(
        header="My App", logo="/img/logo.svg", logo_dark="/img/logo_dark.svg"
    )


# Protected dashboard
@requires_authenticated
def dashboard():
    return rx.text(f"Welcome {UserSession.user.email}!")


# OAuth callback
def github_callback():
    return oauth_login_splash(provider="github", message="Signing in with GitHub...")


# Add to app
app = rx.App()
app.add_page(login, route="/login")
app.add_page(dashboard, route="/dashboard")
app.add_page(github_callback, route="/auth/github/callback")

User Management System

Create an admin user management interface:

from appkit_user.user_management.components import users_table
from appkit_user.authentication.components import requires_admin


@requires_admin
def admin_users():
    return rx.vstack(
        rx.heading("User Management", size="5"),
        rx.flex(users_table(), direction="column", gap="4", width="100%"),
        padding="6",
        spacing="4",
    )

Role-Based Navigation

Dynamic navigation based on user roles:

def navigation():
    return rx.hstack(
        rx.link("Home", href="/"),
        rx.cond(
            UserSession.is_authenticated,
            rx.hstack(
                rx.link("Dashboard", href="/dashboard"),
                rx.cond(
                    UserSession.user.roles.contains("admin"),
                    rx.link("Admin", href="/admin"),
                    rx.text(""),  # Empty for non-admins
                ),
                rx.button("Logout", on_click=UserSession.logout),
            ),
            rx.link("Login", href="/login"),
        ),
    )

Metadata

Release files for appkit-user 1.16.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for appkit-user 1.16.1
File Size Uploaded
appkit_user-1.16.1.tar.gz 886.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for appkit-user 1.16.1
File Interpreter ABI Platform
appkit_user-1.16.1-py3-none-any.whl Python 3 none any Details

Total release size: 968.7 kB

Release files / appkit_user-1.16.1.tar.gz

Download URL appkit_user-1.16.1.tar.gz
Size 886.1 kB
Tags Source
SHA-256 checksum
How to use checksums
e6fbfd3bd62a265df973f82de514e4fd4a488e36a8e0e17e94fe9261f99dd315
BLAKE2b-256 checksum
How to use checksums
161d94815ccfabd2494aaea934ecaf85affcb7e1b8eb27fcd55cce2d54030d7f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / appkit_user-1.16.1-py3-none-any.whl

Download URL appkit_user-1.16.1-py3-none-any.whl
Size 82.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fe8445e70f5494174527592aa25aac978e4204bc45d848c4e00c62c0d10363a6
BLAKE2b-256 checksum
How to use checksums
a88ccea9e40f03068a1bed7c1838cfbaf67a98a922c598f648a711d65e86f660
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.24 {"installer":{"name":"uv","version":"0.12.24","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release history Release notifications | RSS feed

This release

1.16.1 This release

2 release files

1.15.0

2 release files

1.14.0

2 release files

1.13.7

2 release files

1.12.2

2 release files

1.12.1

2 release files

1.12.0

2 release files

1.11.3

2 release files

1.11.2

2 release files

1.11.1

2 release files

1.11.0

2 release files

1.10.2

2 release files

1.10.1

2 release files

1.10.0

2 release files

1.9.7

2 release files

1.9.6

2 release files

1.9.5

2 release files

1.9.4

2 release files

1.9.3

2 release files

1.9.2

2 release files

1.9.1

2 release files

1.9.0

2 release files

1.8.6

2 release files

1.8.5

2 release files

1.8.4

2 release files

1.8.3

2 release files

1.8.2

2 release files

1.8.1

2 release files

1.8.0

2 release files

1.7.0

2 release files

1.6.3

2 release files

1.6.2

2 release files

1.6.1

2 release files

1.6.0

2 release files

1.5.1

2 release files

1.5.0

2 release files

1.4.3

2 release files

1.4.2

2 release files

1.4.1

2 release files

1.4.0

2 release files

1.3.0

2 release files

1.2.6

2 release files

1.2.5

2 release files

1.2.4

2 release files

1.2.3

2 release files

1.2.2

2 release files

1.2.1

2 release files

1.2.0

2 release files

1.1.2

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.17.3

2 release files

0.17.2

2 release files

0.17.1

2 release files

0.17.0

2 release files

0.16.3

2 release files

0.16.2

2 release files

0.16.1

2 release files

0.16.0

2 release files

0.15.4

2 release files

0.15.3

2 release files

0.15.2

2 release files

0.15.1

2 release files

0.15.0

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.8

2 release files

0.7.7

2 release files

0.7.6

2 release files

0.7.5

2 release files

0.7.4

2 release files

0.7.3

2 release files

0.7.2

2 release files

0.7.1

2 release files

0.7.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page