Authentication & OAuth2

SkillSecurity

app = PyWry() result = app.login() # Blocks until auth completes

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Authentication & OAuth2 skill

About this capability

PyWry is a cross-platform app factory, rendering engine and UI toolkit for Python that produces native desktop, web, and notebook experiences from a single API.

What this skill tells your AI

The instructions your AI receives, as published by deeleeramone/pywry in pywry/pywry/mcp/skills/authentication/SKILL.md and read by ahel’s review.

Add OAuth2 authentication to PyWry apps — Google, GitHub, Microsoft, or any OIDC provider.

Two Modes

Native Mode (Desktop)

Opens a dedicated auth window → user logs in at provider → callback captured on ephemeral localhost server → tokens returned.

from pywry import PyWry

app = PyWry()
result = app.login()  # Blocks until auth completes

if result.success:
    app.show("<h1>Welcome!</h1>")
    app.block()

Deploy Mode (Production)

Auth routes mounted automatically when auth_enabled=True and oauth2 settings are configured.

PYWRY_DEPLOY__AUTH_ENABLED=true
PYWRY_OAUTH2__PROVIDER=google
PYWRY_OAUTH2__CLIENT_ID=your-id
PYWRY_OAUTH2__CLIENT_SECRET=your-secret

Routes: GET /auth/login, GET /auth/callback, POST /auth/refresh, POST /auth/logout, GET /auth/status, GET /auth/userinfo

Configuration

Environment Variables

# Provider: google, github, microsoft, oidc, custom
PYWRY_OAUTH2__PROVIDER=google

# Credentials
PYWRY_OAUTH2__CLIENT_ID=your-client-id
PYWRY_OAUTH2__CLIENT_SECRET=your-client-secret

# Scopes (space-separated)
PYWRY_OAUTH2__SCOPES=openid email profile

# PKCE (recommended for public clients)
PYWRY_OAUTH2__USE_PKCE=true

# Token storage: memory (default), keyring (native), redis (deploy)
PYWRY_OAUTH2__TOKEN_STORE_BACKEND=memory

# Custom provider endpoints
PYWRY_OAUTH2__AUTHORIZE_URL=https://provider.com/authorize
PYWRY_OAUTH2__TOKEN_URL=https://provider.com/token

# OIDC auto-discovery
PYWRY_OAUTH2__ISSUER_URL=https://accounts.google.com

TOML Configuration

[tool.pywry.oauth2]
provider = "github"
client_id = "your-id"
scopes = "read:user user:email"
use_pkce = true
token_store_backend = "memory"

Provider Setup

Google

from pywry.auth import GoogleProvider
provider = GoogleProvider(client_id="...", client_secret="...")
result = app.login(provider=provider)

GitHub

from pywry.auth import GitHubProvider
provider = GitHubProvider(client_id="...", client_secret="...")
result = app.login(provider=provider)

Microsoft (Azure AD)

from pywry.auth import MicrosoftProvider
provider = MicrosoftProvider(client_id="...", tenant_id="your-tenant")
result = app.login(provider=provider)

Custom OIDC

from pywry.auth import GenericOIDCProvider
provider = GenericOIDCProvider(
    client_id="...",
    issuer_url="https://your-idp.com",  # Auto-discovers endpoints
)
result = app.login(provider=provider)

Frontend Auth State

When authenticated, window.__PYWRY_AUTH__ is set with { user_id, roles, token_type }.

// Check auth
window.pywry.auth.isAuthenticated()

// Get state
window.pywry.auth.getState()  // { authenticated, user_id, roles, token_type }

// React to changes
window.pywry.auth.onAuthStateChange((state) => {
    console.log('Auth changed:', state);
});

Token Storage Backends

BackendUse CasePersistence
memoryDevelopment, single-processNone (lost on restart)
keyringNative desktop appsOS credential manager
redisDeploy mode, multi-workerRedis with TTL

Install keyring support: pip install pywry[auth]

Security Notes

  • PKCE is enabled by default (public client best practice)
  • CSRF protection via state parameter validation
  • Tokens are never injected into HTML — passed via secure cookies or IPC
  • Session cookies are HttpOnly, Secure, SameSite=Lax
  • Background token refresh happens automatically before expiry

Signals

GitHub stars
93
Forks
6
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
authentication-deeleeramone
Source
github.com/deeleeramone/pywry