| name | security-patterns |
| description | Use when an agent writes, reviews, or audits code that handles authentication, authorization, user input, or sensitive data |
Security Patterns
Authentication
JWT (recommended for stateless APIs)
{
"sub": "user_id",
"exp": timestamp,
"iat": timestamp,
"type": "access"
}
Rules:
- Sign with
HS256 (symmetric) or RS256 (asymmetric for multi-service)
- Never put sensitive data in JWT payload — it's base64, not encrypted
- Rotate refresh tokens on each use (rotation + reuse detection)
- Store refresh tokens in DB to enable revocation
Password hashing
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))
Input Validation
Always validate at system boundaries (API endpoints, file uploads, webhooks):
class UserCreate(BaseModel):
email: EmailStr
password: str = Field(min_length=8, max_length=128)
username: str = Field(regex=r'^[a-zA-Z0-9_]+$')
Rules:
- Fail fast with clear error messages
- Never trust client-provided IDs for authorization checks
- Validate file uploads: type, size, extension
SQL Injection Prevention
query = f"SELECT * FROM users WHERE email = '{email}'"
result = await db.execute(select(User).where(User.email == email))
Authorization
async def get_document(doc_id: UUID, current_user: User, db: AsyncSession):
doc = await db.get(Document, doc_id)
if doc.owner_id != current_user.id:
raise HTTPException(status_code=403)
return doc
Rules:
- Return 403 (not 404) when user lacks permission to a known resource
- Return 404 when resource doesn't exist OR user shouldn't know it exists
- Enforce authorization at every layer (endpoint + service + DB)
Rate Limiting
Apply on all public endpoints, stricter on auth endpoints:
Secret Management
- NEVER hardcode API keys, tokens, or passwords in source code
- Read from environment variables at startup
- Fail loud if required secrets are missing:
SECRET_KEY = os.environ["SECRET_KEY"]
Error Messages
raise HTTPException(detail=f"User {email} not found in table users")
raise HTTPException(status_code=401, detail="Invalid credentials")
Security Review Checklist
Before marking code complete: