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

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

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.3.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.3-py3-none-any.whl (9.8 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: noesis_auth-0.1.3.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.3.tar.gz
Algorithm Hash digest
SHA256 ac1bee27c07aa9efb6231ec0fd8017ddf4c0ae7e3f4dbbea33f86d29b5eeef5c
MD5 94f7f0d03e5a39ee6f308b52746bca77
BLAKE2b-256 cb0d16253478101314d2d2d647e80795503945747d86fa5ebe46b3ec8c6382c0

See more details on using hashes here.

File details

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

File metadata

  • Download URL: noesis_auth-0.1.3-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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 98a5d19bf769d75a935d02a12d5fa7ffddd5db5d1bc764af34b693fba337559e
MD5 ebc5b5706d57b4bf6684c5c5534ea4a9
BLAKE2b-256 113a4038035e50b3467ab4f37a2d4d64909007995564bed288567c250729750a

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