Skip to main content

Herfy Auth SDK

Authentication SDK for integrating applications with the Herfy Control Center.

Features

  • Local JWT Validation: Validate tokens locally using a shared secret (fast, no network calls)
  • Remote Token Validation: Validate tokens via Control Center API (always up-to-date)
  • OAuth2 Authorization Code Flow: Redirect users to Control Center for authentication
  • Client Credentials Flow: App-to-app authentication
  • FastAPI Integration: Ready-to-use dependencies and middleware
  • Token Caching: Built-in caching to reduce validation overhead

Installation

# From PyPI (recommended for app repos)
pip install herfy-auth==1.0.0

# With FastAPI support
pip install "herfy-auth[fastapi]==1.0.0"

# Local editable install (monorepo development)
pip install -e packages/auth-sdk

Publishing

Create a PyPI API token and add it as a GitHub repository secret:

  • PYPI_API_TOKEN

Quick Start

1. Environment Configuration

Set these environment variables:

# Required
CONTROL_CENTER_URL=https://control.herfy.com
SECRET_KEY=your-shared-jwt-secret  # Same as Control Center

# For OAuth flows (optional)
AUTH_CLIENT_ID=your-app-id
AUTH_CLIENT_SECRET=your-app-secret

# Optional settings
TOKEN_VALIDATION_MODE=local  # "local" or "remote"
TOKEN_CACHE_TTL=300  # seconds

2. FastAPI Integration

from fastapi import FastAPI, Depends
from herfy_auth import init_auth, get_current_user, require_auth, UserInfo

app = FastAPI()

# Initialize auth (call once at startup)
init_auth(
    public_routes=["/health", "/api/public"],
    public_prefixes=["/static/"],
)

# Protect routes with authentication
@app.get("/api/profile")
async def get_profile(user: UserInfo = Depends(get_current_user)):
    return {
        "id": user.id,
        "email": user.email,
        "roles": user.roles,
    }

# Require specific roles
@app.get("/api/admin")
async def admin_only(user: UserInfo = Depends(require_auth(roles=["admin"]))):
    return {"admin": True}

# Require any of multiple roles
@app.get("/api/staff")
async def staff_route(
    user: UserInfo = Depends(require_auth(roles=["admin", "agent"], any_role=True))
):
    return {"staff": True}

3. OAuth2 Login Flow

from fastapi import FastAPI, Request
from fastapi.responses import RedirectResponse
from herfy_auth import HerfyAuthClient, AuthConfig

app = FastAPI()
auth_client = HerfyAuthClient(
    control_center_url="https://control.herfy.com",
    client_id="your-app-id",
    client_secret="your-app-secret",
)

@app.get("/login")
async def login():
    # Redirect user to Control Center login
    login_url = auth_client.get_login_url(
        redirect_uri="https://your-app.com/callback",
        state="random-csrf-token",
    )
    return RedirectResponse(login_url)

@app.get("/callback")
async def callback(code: str, state: str):
    # Exchange authorization code for tokens
    tokens = await auth_client.exchange_code(
        code=code,
        redirect_uri="https://your-app.com/callback",
    )
    
    # Get user info
    user = await auth_client.validate_token(tokens.access_token)
    
    return {
        "access_token": tokens.access_token,
        "user": {
            "id": user.id,
            "email": user.email,
        }
    }

4. App-to-App Authentication

from herfy_auth import HerfyAuthClient

# For backend services that need to call the helpdesk API
auth_client = HerfyAuthClient(
    control_center_url="https://control.herfy.com",
    client_id="your-service-app-id",
    client_secret="your-service-app-secret",
)

# Get a token for API calls
async def call_helpdesk_api():
    tokens = await auth_client.get_client_credentials_token()
    
    # Use the token to call other APIs
    async with httpx.AsyncClient() as client:
        response = await client.get(
            "https://helpdesk-api.herfy.com/api/tickets",
            headers={"Authorization": f"Bearer {tokens.access_token}"}
        )
        return response.json()

API Reference

HerfyAuthClient

Main client class for authentication operations.

client = HerfyAuthClient(
    control_center_url="https://control.herfy.com",
    client_id="app-id",           # Optional: for OAuth flows
    client_secret="app-secret",   # Optional: for OAuth flows  
    jwt_secret="shared-secret",   # Optional: for local validation
)

# Validate a token
user = await client.validate_token(token)

# Get OAuth login URL
url = client.get_login_url(redirect_uri, state)

# Exchange authorization code
tokens = await client.exchange_code(code, redirect_uri)

# Get client credentials token
tokens = await client.get_client_credentials_token()

# Refresh a token
tokens = await client.refresh_token(refresh_token)

UserInfo

User information model returned from token validation.

user = await client.validate_token(token)

user.id           # User ID
user.email        # Email address
user.roles        # List of roles
user.org_roles    # Organization roles
user.permissions  # List of permissions
user.is_admin()   # Check if admin
user.has_role("agent")  # Check specific role
user.has_permission("tickets:read")  # Check permission

FastAPI Dependencies

from herfy_auth import get_current_user, get_optional_user, require_auth, require_admin

# Basic auth required
user = Depends(get_current_user)

# Optional auth (returns None if not authenticated)
user = Depends(get_optional_user)

# Require specific roles
user = Depends(require_auth(roles=["admin"]))

# Require any of multiple roles
user = Depends(require_auth(roles=["admin", "manager"], any_role=True))

# Require specific permissions
user = Depends(require_auth(permissions=["tickets:write"]))

# Convenience admin check
user = Depends(require_admin())

Configuration

AuthConfig

from herfy_auth import AuthConfig

config = AuthConfig(
    control_center_url="https://control.herfy.com",
    client_id="app-id",
    client_secret="app-secret",
    jwt_secret="shared-secret",
    jwt_algorithm="HS256",
    token_validation_mode="local",  # "local" or "remote"
    cache_ttl_seconds=300,
)

# Or load from environment
config = AuthConfig.from_env()

Environment Variables

Variable Description Default
CONTROL_CENTER_URL Control Center API URL http://localhost:8001
AUTH_CLIENT_ID OAuth client ID -
AUTH_CLIENT_SECRET OAuth client secret -
SECRET_KEY / JWT_SECRET JWT signing secret -
JWT_ALGORITHM JWT algorithm HS256
TOKEN_VALIDATION_MODE local or remote local
TOKEN_CACHE_TTL Cache TTL in seconds 300

Token Validation Modes

Local Validation (Recommended)

Validates JWT tokens locally using a shared secret. Fast and doesn't require network calls.

TOKEN_VALIDATION_MODE=local
SECRET_KEY=same-key-as-control-center

Remote Validation

Validates tokens by calling the Control Center's /oauth/userinfo endpoint. Always up-to-date but requires network calls.

TOKEN_VALIDATION_MODE=remote
CONTROL_CENTER_URL=https://control.herfy.com

License

MIT

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

herfy_auth-1.0.1.tar.gz (13.2 kB view details)

Uploaded Source

Built Distribution

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

herfy_auth-1.0.1-py3-none-any.whl (12.5 kB view details)

Uploaded Python 3

File details

Details for the file herfy_auth-1.0.1.tar.gz.

File metadata

  • Download URL: herfy_auth-1.0.1.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for herfy_auth-1.0.1.tar.gz
Algorithm Hash digest
SHA256 f3cc011d57b935349f2982fd165ca7d6d5f8711557a71d1c3eae9317df56dd03
MD5 a909da9614f9d5ee6873c016bbf35043
BLAKE2b-256 6891c7bba2848916d8d3b2611d3053369caa400056891ce27c3f4d14074b742b

See more details on using hashes here.

Provenance

The following attestation bundles were made for herfy_auth-1.0.1.tar.gz:

Publisher: publish-auth-sdk.yml on Herfy-Food-Services/herfy-shared-library

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

File details

Details for the file herfy_auth-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: herfy_auth-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 12.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for herfy_auth-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3621d45a5a3f85db19e41cbcbf7f56c1ed80df30ce6df816228fcca953d5b47a
MD5 1179f7c8e5c5855b0673b7b1f73573dc
BLAKE2b-256 eb4cbc0ba979d553d84f4af5c14fac2270a1d0246e20605869ef401b35d430dd

See more details on using hashes here.

Provenance

The following attestation bundles were made for herfy_auth-1.0.1-py3-none-any.whl:

Publisher: publish-auth-sdk.yml on Herfy-Food-Services/herfy-shared-library

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

Release history Release notifications | RSS feed

This release

1.0.1 This release

2 files

1.0.0

2 files

Supported by

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