Skip to content

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 eu flag)
  • 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