Skip to content

Pico-Client-Auth Documentation

pico-client-auth is a JWT authentication client for pico-fastapi applications. It provides automatic Bearer token validation, a request-scoped SecurityContext, role-based access control, and JWKS key rotation support.


Quick Install

pip install pico-client-auth

For auto-discovery with pico-boot:

pip install pico-boot pico-fastapi pico-client-auth

30-Second Example

from pico_fastapi import controller, get
from pico_client_auth import SecurityContext, allow_anonymous, requires_role

@controller(prefix="/api")
class MyController:

    @get("/me")
    async def get_me(self):
        claims = SecurityContext.require()
        return {"sub": claims.sub, "email": claims.email}

    @get("/health")
    @allow_anonymous
    async def health(self):
        return {"status": "ok"}

    @get("/admin")
    @requires_role("admin")
    async def admin_panel(self):
        return {"admin": True}
# application.yaml
auth_client:
  issuer: https://auth.example.com
  audience: my-api

Key Features

Feature Description
Auth by Default All routes require a valid JWT unless explicitly marked @allow_anonymous
SecurityContext Access authenticated user claims anywhere in the request lifecycle
Role-Based Access @requires_role("admin") decorator for fine-grained authorization
Group-Based Access @requires_group("team-id") decorator for group-level authorization
JWKS Caching Automatic key fetch with TTL and key rotation support
Extensible Roles Implement RoleResolver protocol to customise role extraction
Fail-Fast Missing configuration raises AuthConfigurationError at startup
Zero Config Auto-discovered when using pico-boot

Documentation Structure

# Section Description Link
1 Getting Started 5-minute setup guide getting-started.md
2 Tutorial Step-by-step walkthrough tutorial.md
3 User Guide Core concepts and patterns user-guide/
4 How-To Guides Practical examples how-to/
5 Architecture Design and internals architecture.md
6 API Reference Decorators, classes, exceptions reference/
7 FAQ Common questions faq.md

Core APIs at a Glance

SecurityContext

from pico_client_auth import SecurityContext

# In any handler or service (within a request)
claims = SecurityContext.require()    # Raises if not authenticated
claims = SecurityContext.get()         # Returns None if not authenticated
roles  = SecurityContext.get_roles()   # Resolved roles list
SecurityContext.has_role("admin")      # Boolean check
SecurityContext.require_role("admin")  # Raises InsufficientPermissionsError
groups = SecurityContext.get_groups()  # Group IDs tuple
SecurityContext.has_group("team-id")   # Boolean group check
SecurityContext.require_group("team")  # Raises InsufficientPermissionsError

Decorators

from pico_client_auth import allow_anonymous, requires_role, requires_group

@allow_anonymous          # Skip token validation for this endpoint
async def health(): ...

@requires_role("admin")   # 403 if user lacks the role
async def admin(): ...

@requires_group("eng")    # 403 if user not in group
async def team(): ...

Custom Role Resolver

from pico_ioc import component
from pico_client_auth import RoleResolver, TokenClaims

@component
class MyRoleResolver:
    async def resolve(self, claims: TokenClaims, raw_claims: dict) -> list[str]:
        return raw_claims.get("roles", [])

Why Pico-Client-Auth?

Concern Manual Auth Middleware pico-client-auth
Token validation DIY per project Automatic via JWKS
Key rotation Manual handling Auto-refresh on unknown kid
Security context request.state ad-hoc Typed SecurityContext with ContextVar
Role checking Scattered if/else @requires_role decorator
Configuration Hardcoded @configured from YAML/env
Testing Mock everything Replace RoleResolver, use test tokens

Next Steps

  1. New to pico-client-auth? Start with Getting Started
  2. Want examples? Check the How-To Guides
  3. Need custom roles? Read Custom Role Resolver