Security¶
Implement secure authentication and authorization in your Ravyn application with built-in security tools.
What You'll Learn¶
- Security fundamentals (OAuth2, JWT, etc.)
- Available security schemes
- Implementing authentication
- Authorization patterns
- Best practices
Quick Start¶
from ravyn import Ravyn, get, Inject
from ravyn.security.jwt import JWTAuth
@get("/protected", dependencies={"auth": Inject(JWTAuth())})
async def protected_route(auth: dict) -> dict:
return {"user": auth["sub"], "message": "Authenticated!"}
app = Ravyn(routes=[Gateway(handler=protected_route)])
In This Section¶
Getting Started¶
- Introduction - Security concepts and overview
- Available Security - Built-in security schemes
- Interaction - How security works in Ravyn
Implementation Guides¶
- OAuth2 + JWT - JWT-based OAuth2 authentication
- Simple OAuth2 - Basic OAuth2 implementation
Advanced Topics¶
- Basic Auth - HTTP Basic Authentication
- OAuth2 Scopes - Fine-grained permissions
Security Concepts¶
OAuth2¶
OAuth2 is a comprehensive specification for authentication and authorization. It enables:
-
Third-party login - "Sign in with Google/Facebook/GitHub"
-
Token-based auth - Stateless authentication
-
Scopes - Fine-grained permissions
-
Multiple flows - Password, client credentials, authorization code
JWT (JSON Web Tokens)¶
JWTs are compact, URL-safe tokens for transmitting information:
-
Stateless - No server-side session storage
-
Self-contained - Contains all user information
-
Secure - Cryptographically signed
-
Standard - Widely supported
OpenID Connect¶
Built on top of OAuth2, OpenID Connect adds:
-
Standardization - Reduces OAuth2 ambiguities
-
User info - Standard user profile endpoint
-
ID tokens - JWT-based identity tokens
Supported Security Schemes¶
Ravyn supports OpenAPI security schemes:
| Scheme | Type | Description |
|---|---|---|
| API Key | apiKey | Custom keys in headers/cookies/query |
| Bearer Token | http (bearer) | JWT or opaque tokens |
| Basic Auth | http (basic) | Username/password |
| OAuth2 | oauth2 | OAuth2 flows |
| OpenID Connect | openIdConnect | OIDC authentication |
Quick Examples¶
JWT Authentication¶
from ravyn import Ravyn, get, Inject
from ravyn.security.jwt import JWTAuth
@get("/users/me", dependencies={"auth": Inject(JWTAuth())})
async def get_current_user(auth: dict) -> dict:
return {"user_id": auth["sub"], "email": auth["email"]}
API Key Authentication¶
from ravyn import Ravyn, get, Security
from ravyn.security import APIKeyHeader
api_key_scheme = APIKeyHeader(name="X-API-Key")
@get("/data", security=[api_key_scheme])
async def get_data(api_key: str = Security(api_key_scheme)) -> dict:
if api_key != "secret-key":
raise HTTPException(status_code=401)
return {"data": "sensitive"}
OAuth2 with Scopes¶
from ravyn import Ravyn, get
from ravyn.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(
tokenUrl="/token",
scopes={"read": "Read access", "write": "Write access"}
)
@get("/items", security=[oauth2_scheme])
async def read_items(token: str = Security(oauth2_scheme, scopes=["read"])):
return {"items": []}
Why Ravyn Security?¶
Ravyn simplifies security implementation:
-
Standards-based - OAuth2, JWT, OpenAPI
-
Easy integration - Built-in tools and decorators
-
Automatic docs - Security schemes in OpenAPI
-
Flexible - Multiple authentication methods
-
Production-ready - Battle-tested patterns
Common Patterns¶
Pattern 1: JWT + Refresh Tokens¶
# Login returns access + refresh tokens
@post("/login")
async def login(credentials: LoginRequest) -> dict:
user = await authenticate(credentials)
return {
"access_token": create_access_token(user),
"refresh_token": create_refresh_token(user),
"token_type": "bearer"
}
# Protected route requires access token
@get("/protected", dependencies={"auth": Inject(JWTAuth())})
async def protected(auth: dict) -> dict:
return {"user": auth["sub"]}
Pattern 2: Role-Based Access¶
from ravyn import get, Inject
from ravyn.permissions import IsAuthenticated, HasRole
@get(
"/admin",
permissions=[IsAuthenticated, HasRole("admin")]
)
async def admin_only() -> dict:
return {"message": "Admin access granted"}
Pattern 3: API Key + Rate Limiting¶
from ravyn import get, Security
from ravyn.security import APIKeyHeader
from ravyn.middleware import RateLimitMiddleware
api_key = APIKeyHeader(name="X-API-Key")
@get(
"/api/data",
security=[api_key],
middleware=[RateLimitMiddleware(max_requests=100)]
)
async def api_endpoint(key: str = Security(api_key)) -> dict:
return {"data": "value"}
Best Practices¶
1. Use HTTPS in Production¶
# Good - enforce HTTPS
if not request.url.scheme == "https" and os.getenv("ENV") == "production":
raise HTTPException(status_code=403, detail="HTTPS required")
2. Store Secrets Securely¶
# Good - environment variables
import os
JWT_SECRET = os.getenv("JWT_SECRET_KEY")
API_KEY = os.getenv("API_KEY")
3. Use Short-Lived Access Tokens¶
# Good - 15 minute access tokens
access_token = create_jwt(
user_id=user.id,
expires_in=900 # 15 minutes
)
Next Steps¶
Choose your authentication method:
- OAuth2 + JWT - Most common pattern
- Simple OAuth2 - Basic implementation
- Basic Auth - Simple username/password
- Available Security - All security schemes