Skip to main content

Shared authentication middleware for PARGO backend services

Project description

pargo-auth

Authentication and user management for PARGO. This repo serves two purposes:

  1. PyPI Package (pargo-auth) - JWT verification middleware for FastAPI
  2. 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 preferences
  • auth.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:

  1. Bumps version
  2. 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

pargo_auth-0.1.7.tar.gz (17.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pargo_auth-0.1.7-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

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

Hashes for pargo_auth-0.1.7.tar.gz
Algorithm Hash digest
SHA256 5c84340e30df98a4a776c9053ee9fa117cc37af2aed3587d339040a2ee8636e5
MD5 76fad9027ba7ced9b1f81f4e079c7d4b
BLAKE2b-256 b23674fc9172e035a4da24ea6b296858903e6e5d2ccf831853b0c84bf6a3c09b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pargo_auth-0.1.7.tar.gz:

Publisher: publish.yml on pargoorg/pargo-auth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for pargo_auth-0.1.7-py3-none-any.whl
Algorithm Hash digest
SHA256 156af18f2e1c53a7d7cc80ac14caa6a86dedfcd6a986a468b4c0b42ad153a956
MD5 f1da4b8e0e3336426f17e046835d9e92
BLAKE2b-256 fa687209f7b0fe12ea9c2430325ada05533b227a8a8a01dbf543136eb9ff1775

See more details on using hashes here.

Provenance

The following attestation bundles were made for pargo_auth-0.1.7-py3-none-any.whl:

Publisher: publish.yml on pargoorg/pargo-auth

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page