Skip to content

How-To Guides

Practical step-by-step guides for common tasks with pico-client-auth.

Available Guides

Guide Description
Custom Role Resolver Extract roles from a roles array or external service
Public Endpoints Mark endpoints as publicly accessible
Testing Auth Test controllers with mock tokens and role overrides
Post-Quantum (ML-DSA) Enable ML-DSA-65/87 post-quantum JWT verification

Quick Reference

Protecting All Routes (Default)

All routes require a valid JWT by default. No configuration needed.

@controller(prefix="/api")
class MyController:
    @get("/data")
    async def get_data(self):
        # Only accessible with valid Bearer token
        claims = SecurityContext.require()
        return {"user": claims.sub}

Public Endpoints

from pico_client_auth import allow_anonymous

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

Role-Based Access

from pico_client_auth import requires_role

@get("/admin")
@requires_role("admin")
async def admin(self):
    return {"admin": True}

@get("/content")
@requires_role("editor", "admin")  # Any of these roles
async def content(self):
    return {"drafts": 5}

Group-Based Access

from pico_client_auth import requires_group

@get("/team")
@requires_group("engineering", "platform")  # Any of these groups
async def team_dashboard(self):
    return {"team": True}

Accessing User Claims

from pico_client_auth import SecurityContext

# In controller, service, or anywhere within a request
claims = SecurityContext.require()
print(claims.sub, claims.email, claims.org_id)

# Check roles
if SecurityContext.has_role("admin"):
    # ...

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", [])