Skip to main content

Python Auth SDK for AI tool integration with the Noesis AIToolCenter platform

Project description

noesis-auth (Python)

Python Auth SDK for AI tool integration with the Noesis AIToolCenter platform.

Installation

pip install noesis-auth

# With FastAPI middleware support:
pip install noesis-auth[fastapi]

Quick Start

JWT Validation (Tool-side)

from auth_sdk import JWTValidator

validator = JWTValidator(
    jwks_url="https://your-platform.com/.well-known/jwks.json"
)

payload = await validator.validate(token)
print(payload["sub"])  # user ID

FastAPI Middleware

from fastapi import Depends, FastAPI
from auth_sdk import AuthMiddleware, TokenPayload

app = FastAPI()
auth = AuthMiddleware(jwks_url="https://your-platform.com/.well-known/jwks.json")

@app.get("/api/generate")
async def generate(payload: TokenPayload = Depends(auth.require_tool("your-tool-id"))):
    user_id = payload.sub
    # ... your tool logic

OAuth2 Client (PKCE)

from auth_sdk import AuthClient

client = AuthClient(base_url="https://your-platform.com")

# Generate PKCE pair
pkce = AuthClient.generate_pkce()

# Build authorization URL
url = client.build_authorize_url(
    client_id="your-client-id",
    redirect_uri="http://localhost:3000/callback",
    code_challenge=pkce.code_challenge,
)

# Exchange code for tokens
tokens = await client.exchange_code(
    code=auth_code,
    redirect_uri="http://localhost:3000/callback",
    client_id="your-client-id",
    code_verifier=pkce.code_verifier,
)

Activation Code Redemption

result = await client.redeem_code(user_token="...", code="AXKF-M3PQ-7RBN-W2YT")
print(result.tool_id)         # "uuid-xxx"
print(result.tool_name)       # "AI Translator"
print(result.duration_days)   # 30
print(result.expires_at)      # "2026-06-23T10:00:00+00:00" (ISO datetime)
print(result.token_refresh_required)  # True
print(result.new_access_token)        # new JWT if token_refresh_required

Token Introspection

result = await client.introspect(token, client_id="...", client_secret="...")
if result.active:
    print(result.sub, result.entitlements)

Token Refresh

new_tokens = await client.refresh_token(
    refresh_token="...",
    client_id="your-client-id",
    client_secret="your-secret",
)
print(new_tokens.access_token)

Features

  • JWT Validation — RS256 (JWKS) and HS256 (shared secret) with auto-detection from token header
  • FastAPI Middleware — Drop-in authentication and tool access verification
  • OAuth2 Client — Authorization URL builder, code exchange, token refresh
  • PKCE Support — S256 code challenge generation for public clients
  • Token Introspection — Remote token validation endpoint
  • Activation Codes — Redeem activation codes with full response (tool_name, duration, new_access_token)
  • JWKS Caching — 6-hour configurable cache with stale-while-revalidate and retry on failure
  • Robust Error Handling — Timeout, network errors, and malformed responses wrapped in AuthError

Error Handling

All HTTP methods raise AuthError with a specific error code:

from auth_sdk import AuthClient, AuthError

try:
    tokens = await client.exchange_code(...)
except AuthError as e:
    print(e.code)    # "TOKEN_INVALID", "NETWORK_ERROR", or "INVALID_RESPONSE"
    print(e.status)  # HTTP status code (0 for network errors)
    print(str(e))    # Human-readable message
Code Meaning
TOKEN_INVALID Server rejected the request (4xx/5xx)
NETWORK_ERROR Timeout or connection failure
INVALID_RESPONSE Server returned unparseable response

TokenPayload Fields

@dataclass
class TokenPayload:
    sub: str                           # User ID
    exp: int                           # Expiration (unix timestamp)
    iat: int                           # Issued at (unix timestamp)
    jti: str                           # Unique token ID
    entitlements: list[Entitlement]    # Tool access list
    role: str | None                   # "integrator", "distributor", or None
    is_admin: bool                     # True for admin users

has_tool_access(tool_id) accepts both str and int (auto-coerced to string).

Security Notes

  • No silent algorithm fallback: If JWKS returns empty keys, validation fails explicitly instead of silently falling back to HS256.
  • HS256 only when token declares it: The SDK uses HS256 only when the token's JWT header has alg: HS256 and hs256_secret is configured.
  • Timeout protection: All HTTP requests have a configurable timeout (default 10s). Hanging connections are terminated.

Requirements

  • Python >= 3.11
  • httpx >= 0.24
  • python-jose[cryptography] >= 3.3
  • fastapi >= 0.100 (optional, for middleware)

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

noesis_auth-0.1.1.tar.gz (9.9 kB view details)

Uploaded Source

Built Distribution

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

noesis_auth-0.1.1-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

Details for the file noesis_auth-0.1.1.tar.gz.

File metadata

  • Download URL: noesis_auth-0.1.1.tar.gz
  • Upload date:
  • Size: 9.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for noesis_auth-0.1.1.tar.gz
Algorithm Hash digest
SHA256 1c596dc94ba635bf1e17023f67ece4d39461e84aed7b2196caa4d64a62583898
MD5 548de3bf0a3ee09b1b3e583b524b0a9f
BLAKE2b-256 3895d9f56beab9c5c07214e0c2aeab1a514ea0fc24463e354bcb4c74869b9597

See more details on using hashes here.

File details

Details for the file noesis_auth-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: noesis_auth-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 9.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15

File hashes

Hashes for noesis_auth-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 6cb2ab31ad1fdc675d0c53bba44ee92744979882c5dfbe1909feea68009cdce3
MD5 3dfb5dc065fe9d419a9387d7220db3bc
BLAKE2b-256 3fffe7063ef50d8e079a53bba5ac41d6924583ad2464bee34cb1611801f10b4d

See more details on using hashes here.

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