API referenceAuthentication

Authentication

Pencheff SaaS uses Clerk for identity. Once a user is signed in, the frontend sends every request with a Bearer JWT that Clerk issues on the browser side.

Server-side verification

The FastAPI backend validates the JWT on every request via auth/deps.py — it checks signature, issuer, audience, expiry, and maps the sub claim to a User row, creating one on first login.

Calling the API from a script

# Fetch a short-lived token from Clerk (machine-to-machine)
TOKEN=$(curl -sX POST https://api.clerk.com/v1/machine_auth_tokens \
  -H "Authorization: Bearer $CLERK_M2M_KEY" \
  -d "{\"subject\":\"user_xxx\"}" | jq -r .token)
 
# Use it
curl https://app.pencheff.com/api/scans \
  -H "Authorization: Bearer $TOKEN"

Local development

Set these env vars when running the API / web locally:

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...
CLERK_JWT_KEY=pk_test_jwks_...

The web app uses NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY directly.

API keys (coming soon)

Long-lived personal access tokens for CI/CD are on the roadmap — track issue #42.

For now, use the MCP / CLI locally with the hosted SaaS’ read-only API via a Clerk M2M token or the plugin-side-only interactsh-client callback.