Shared authentication middleware for PARGO backend services
Project description
pargo-auth
Authentication and user management for PARGO. This repo serves two purposes:
- PyPI Package (
pargo-auth) - JWT verification middleware for FastAPI - User Service - API for user profile and settings management
Architecture
pargo-auth/
├── src/pargo_auth/ # Library (published to PyPI)
│ ├── middleware.py # Supabase JWT verification
│ ├── models.py # AuthenticatedUser dataclass
│ └── exceptions.py # Auth errors
├── app/ # Service (deployed to server)
│ ├── main.py # FastAPI application
│ ├── routes/users.py # /v1/me endpoints
│ └── services/ # Database operations
├── docker/Dockerfile # Service container
└── pyproject.toml # Package configuration
Part 1: PyPI Package
The pargo-auth package provides JWT verification for any PARGO backend.
Installation
pip install pargo-auth
Usage
from fastapi import Depends
from pargo_auth import get_current_user, AuthenticatedUser
@app.get("/protected")
async def protected(user: AuthenticatedUser = Depends(get_current_user)):
return {"user_id": user.sub, "email": user.email}
Configuration
Set environment variables:
SUPABASE_URL=https://your-project.supabase.co
ENV=local # Skip verification in local dev
AuthenticatedUser
| Field | Type | Description |
|---|---|---|
sub |
str |
Supabase user ID (stable, canonical identity) |
email |
str | None |
User's email |
email_verified |
bool |
Whether email is verified |
supabase_uid |
str |
Alias for sub |
raw_claims |
dict | None |
Full JWT payload |
Optional Auth
For endpoints that work with or without authentication:
from pargo_auth import SupabaseAuth
auth = SupabaseAuth()
@app.get("/content")
async def get_content(user: AuthenticatedUser | None = Depends(auth.get_user_optional)):
if user:
return {"personalized": True, "user": user.sub}
return {"personalized": False}
Part 2: User Service
The service manages user data in Hetzner Postgres (auth schema).
Endpoints
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /v1/me |
Required | Get profile + settings (creates user on first call) |
| PATCH | /v1/me |
Required | Update profile |
| PATCH | /v1/me/settings |
Required | Update settings |
| DELETE | /v1/me |
Required | Soft delete account |
| GET | /health |
None | Health check |
Database Schema
Uses the auth schema in Postgres:
auth.users- Core user identity (synced from Supabase JWT)auth.user_identities- Login methods (apple, google, email)auth.user_settings- App preferencesauth.audit_events- Security/login event log
Running Locally
# Install dependencies
pip install -r requirements-service.txt
pip install -e .
# Set environment
export SUPABASE_URL=https://your-project.supabase.co
export DATABASE_URL=postgresql://postgres:password@localhost:5432/pargo_test
export ENV=local
# Run
uvicorn app.main:app --reload --port 8040
Docker
docker build -f docker/Dockerfile -t pargo-auth .
docker run -p 8040:8040 \
-e SUPABASE_URL=https://your-project.supabase.co \
-e DATABASE_URL=postgresql://... \
pargo-auth
Response Examples
GET /v1/me
{
"user": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"supabase_uid": "846eddd7-f5ae-4d72-8082-accde7da68f2",
"email": "user@example.com",
"email_verified": true,
"display_name": "John Doe",
"preferred_lang": "da",
"created_at": "2026-02-02T10:00:00Z",
"last_login_at": "2026-02-02T12:00:00Z"
},
"settings": {
"push_enabled": true,
"email_enabled": true,
"map_style": "standard",
"settings_json": {}
}
}
Development
Package Development
# Install in editable mode
pip install -e ".[dev]"
# Run tests
pytest
Publishing (automatic)
Push to main triggers GitHub Actions:
- Bumps version
- Publishes to PyPI
Design Decisions
| Decision | Rationale |
|---|---|
supabase_uid is canonical ID |
JWT sub is stable even if email changes |
User created on first /me call |
No separate signup flow needed |
| Soft delete | GDPR compliance, account recovery possible |
| Separate settings table | Clean separation, flexible JSONB for future |
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pargo_auth-0.1.7.tar.gz.
File metadata
- Download URL: pargo_auth-0.1.7.tar.gz
- Upload date:
- Size: 17.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c84340e30df98a4a776c9053ee9fa117cc37af2aed3587d339040a2ee8636e5
|
|
| MD5 |
76fad9027ba7ced9b1f81f4e079c7d4b
|
|
| BLAKE2b-256 |
b23674fc9172e035a4da24ea6b296858903e6e5d2ccf831853b0c84bf6a3c09b
|
Provenance
The following attestation bundles were made for pargo_auth-0.1.7.tar.gz:
Publisher:
publish.yml on pargoorg/pargo-auth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pargo_auth-0.1.7.tar.gz -
Subject digest:
5c84340e30df98a4a776c9053ee9fa117cc37af2aed3587d339040a2ee8636e5 - Sigstore transparency entry: 1639938200
- Sigstore integration time:
-
Permalink:
pargoorg/pargo-auth@4a2ec45c0e591a53a2ca2d39dcffae36acdb2de6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/pargoorg
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a2ec45c0e591a53a2ca2d39dcffae36acdb2de6 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pargo_auth-0.1.7-py3-none-any.whl.
File metadata
- Download URL: pargo_auth-0.1.7-py3-none-any.whl
- Upload date:
- Size: 7.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
156af18f2e1c53a7d7cc80ac14caa6a86dedfcd6a986a468b4c0b42ad153a956
|
|
| MD5 |
f1da4b8e0e3336426f17e046835d9e92
|
|
| BLAKE2b-256 |
fa687209f7b0fe12ea9c2430325ada05533b227a8a8a01dbf543136eb9ff1775
|
Provenance
The following attestation bundles were made for pargo_auth-0.1.7-py3-none-any.whl:
Publisher:
publish.yml on pargoorg/pargo-auth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pargo_auth-0.1.7-py3-none-any.whl -
Subject digest:
156af18f2e1c53a7d7cc80ac14caa6a86dedfcd6a986a468b4c0b42ad153a956 - Sigstore transparency entry: 1639938402
- Sigstore integration time:
-
Permalink:
pargoorg/pargo-auth@4a2ec45c0e591a53a2ca2d39dcffae36acdb2de6 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/pargoorg
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4a2ec45c0e591a53a2ca2d39dcffae36acdb2de6 -
Trigger Event:
workflow_dispatch
-
Statement type: