Skip to main content

Authentication SDK for integrating with Herfy Control Center

Project description

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

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

herfy_auth-1.0.0.tar.gz (12.4 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.0-py3-none-any.whl (11.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: herfy_auth-1.0.0.tar.gz
  • Upload date:
  • Size: 12.4 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.0.tar.gz
Algorithm Hash digest
SHA256 768d058cc3084bbf8128c06f35e45f22161cd8d01c26344c4b7974697efb3541
MD5 c38e680211e03944ae052b90f8b07c77
BLAKE2b-256 aaf3a9cbb24b9b17d862c8d09ed2e67289761cd9e6468c2f79e54c6dfd32fefe

See more details on using hashes here.

Provenance

The following attestation bundles were made for herfy_auth-1.0.0.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.0-py3-none-any.whl.

File metadata

  • Download URL: herfy_auth-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 11.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.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c8c815b8b592c75c037a28a0fb5583a7adbae8e91d8933f3a47b925260850b06
MD5 ab25867d944dae3d01282a2582cdb928
BLAKE2b-256 556602514b4b0802e0088b3f279ff3fab56c03dbd4b20f52c8d8c76bc6dcd631

See more details on using hashes here.

Provenance

The following attestation bundles were made for herfy_auth-1.0.0-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.

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