Security¶
Kuí provides built-in authentication helpers that integrate with the dependency injection system and auto-generate OpenAPI security schemes.
Bearer Token Authentication¶
Extract a Bearer token from the Authorization header:
from typing_extensions import Annotated
from kui.asgi import Depends, bearer_auth
@app.router.http.get("/me")
async def me(token: Annotated[str, Depends(bearer_auth)]):
user = decode_jwt(token)
return {"user": user}
- Expects:
Authorization: Bearer <token> - Returns: the token string
- Raises:
HTTPException(401)withWWW-Authenticate: Bearerif missing or invalid format - OpenAPI: generates
BearerAuthsecurity scheme
Basic Authentication¶
Extract username and password from HTTP Basic Auth:
from kui.asgi import Depends, basic_auth
@app.router.http.get("/admin")
async def admin(
credentials: Annotated[tuple[str, str], Depends(basic_auth)],
):
username, password = credentials
if not verify_password(username, password):
raise HTTPException(403)
return {"user": username}
- Expects:
Authorization: Basic <base64(username:password)> - Returns:
(username, password)tuple - Raises:
HTTPException(401)withWWW-Authenticate: Basicif missing or invalid - OpenAPI: generates
BasicAuthsecurity scheme
API Key Authentication¶
Validate an API key from a header, query parameter, or cookie:
from kui.asgi import Depends, api_key_auth_dependency
# From header
api_key = api_key_auth_dependency("X-API-Key", position="header")
@app.router.http.get("/data")
async def data(key: Annotated[str, Depends(api_key)]):
return {"data": "secret"}
# From query parameter
api_key_query = api_key_auth_dependency("api_key", position="query")
# From cookie
api_key_cookie = api_key_auth_dependency("session", position="cookie")
position:"header","query", or"cookie"- Returns: the API key string
- Raises:
HTTPException(401)if the key is missing - OpenAPI: generates
ApiKeyAuthsecurity scheme with the correct location
OpenAPI Integration¶
All security dependencies auto-generate OpenAPI securitySchemes in the components section and security requirements on operations.
from kui.asgi import Kui, OpenAPI, HttpRoute, Depends, bearer_auth
app = Kui(routes=[
HttpRoute("/me", me),
])
app.router <<= "/docs" // OpenAPI(
info={"title": "My API", "version": "1.0.0"},
).routes
The generated spec includes:
{
"components": {
"securitySchemes": {
"BearerAuth": {
"type": "http",
"scheme": "bearer"
}
}
},
"paths": {
"/me": {
"get": {
"security": [{"BearerAuth": []}]
}
}
}
}
Custom Authentication¶
Create your own authentication dependency:
from kui.asgi import Depends, Header, HTTPException
async def verify_api_token(
authorization: Annotated[str, Header(alias="authorization")],
):
if not authorization.startswith("Bearer "):
raise HTTPException(401, headers={"WWW-Authenticate": "Bearer"})
token = authorization[7:]
user = await verify_and_decode(token)
if not user:
raise HTTPException(401)
return user
@app.router.http.get("/protected")
async def protected(
user: Annotated[User, Depends(verify_api_token)],
):
return {"user": user.name}
Custom dependencies with Header/Query/Cookie parameters are auto-documented in OpenAPI but won't generate a securitySchemes entry. Use describe_extra_docs to add custom security schemes if needed.