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 noesis_auth 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 noesis_auth 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

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

OAuth2 Client (PKCE)

from noesis_auth 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 noesis_auth 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.2.0.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.2.0-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: noesis_auth-0.2.0.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.2.0.tar.gz
Algorithm Hash digest
SHA256 842ef89287c43bff2e0fc5e97b6123efd4cf2f9bc6e1f1721739b24028a88092
MD5 0bd167a62a5aff1ba87c38817f1c10f0
BLAKE2b-256 a6d160c7b4ee39f54b0d105a42399ba54c22b7d03c8fd10ea63bb38009151ded

See more details on using hashes here.

File details

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

File metadata

  • Download URL: noesis_auth-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 9.9 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e72ae46f29a7845a7a3857092b10250cc3ebf4df3f1c2c1c8467a6a635730dad
MD5 8449f4bf8cf9ede8231899052d51e12a
BLAKE2b-256 9092dfc14ad222bd96fa43ec04459d8f95f9ff59dfa7d30811f2bc30c2b5be9e

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