Security¶
Reggie's security model covering authentication, authorization, storage, and API protection.
Authentication¶
Provider: Clerk (see ADR-001)
Flow:
1. User signs in via Clerk UI components in the Next.js frontend
2. Clerk issues a JWT (RS256 signed)
3. Frontend sends Authorization: Bearer <token> to the API
4. FastAPI verifies the JWT signature using Clerk's PEM public key (networkless -- no round-trip to Clerk)
5. Backend looks up profiles.clerk_id to link the Clerk user to a Reggie profile
Key properties:
- RS256 signature verification is networkless (PEM key stored as env var)
- No Clerk API calls on the hot path -- pure cryptographic verification
- JWTs include standard claims (sub, iat, exp)
Authorization¶
Role model: Simple role-based access via profiles.role column.
| Role | Access |
|---|---|
user |
Own profile, own plates, make offers |
admin |
All user access + claims management, admin dashboard |
FastAPI dependencies:
from app.utils.auth import get_current_user, require_admin
@router.get("/my-plates")
def my_plates(user=Depends(get_current_user)): # Any authenticated user
...
@router.get("/admin/claims")
def list_claims(user=Depends(require_admin)): # Admin only
...
Storage Security¶
Cloudflare R2 stores claim documents (V5C ownership certificates).
- Bucket:
reggie-claim-documents(EU jurisdiction,-J euflag) - Access: Via R2 API keys (not public)
- Documents are accessed through signed URLs generated by the backend
API Security¶
CORS: Configured via ALLOWED_ORIGINS environment variable. Production restricts to getreggie.co.uk and admin.getreggie.co.uk. Development allows all origins.
Input validation: Pydantic schemas validate all request bodies. Plate registrations are normalized (uppercased, whitespace/dashes stripped) before any database lookup.
Rate limiting: Not yet implemented at the application level. CloudFront provides basic DDoS protection.
Secrets Management¶
| Environment | Secret Storage |
|---|---|
| Local dev | .env files (generated from .env.example, gitignored) |
| AWS stages | SST Secrets (backed by AWS SSM Parameter Store) |
| CI | GitHub Actions environment variables |
See Environment Variables for the complete list.
Web Scraping¶
The market data scraper respects:
- robots.txt directives
- 2-second delay between requests
- Dealer listings marked inactive after 7 days unseen