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.2.tar.gz (10.0 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.2-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: noesis_auth-0.1.2.tar.gz
  • Upload date:
  • Size: 10.0 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.2.tar.gz
Algorithm Hash digest
SHA256 bb6dc01a2164950617caf114a10b7f9b3d7b7cd2f0e36e68ae5db23fd0c5322e
MD5 eeed390cb7ee46a9caf803ed62726951
BLAKE2b-256 96cf852a3177cc407f08f7836e8a24acba7b9380b42703626366b283e527ba80

See more details on using hashes here.

File details

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

File metadata

  • Download URL: noesis_auth-0.1.2-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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 039d28405e1d184a9a9568e4189476343b8365e1538d0d68668b47bd6acb45fa
MD5 56941d549db2b1e8e6b460fd306bacf3
BLAKE2b-256 a0be8e0e7e5b1b800427894583248820da76c6422f6f0fe11854068771da3093

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