Authentication & OAuth2
SkillSecurityapp = PyWry() result = app.login() # Blocks until auth completes
Available today. Use it from your connected AI after setup.
No other account needed.
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
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
| Backend | Use Case | Persistence |
|---|---|---|
memory | Development, single-process | None (lost on restart) |
keyring | Native desktop apps | OS credential manager |
redis | Deploy mode, multi-worker | Redis with TTL |
Install keyring support: pip install pywry[auth]
Security Notes
- PKCE is enabled by default (public client best practice)
- CSRF protection via
stateparameter 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