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: HS256andhs256_secretis configured. - Timeout protection: All HTTP requests have a configurable timeout (default 10s). Hanging connections are terminated.
Requirements
- Python >= 3.11
httpx>= 0.24python-jose[cryptography]>= 3.3fastapi>= 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)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c596dc94ba635bf1e17023f67ece4d39461e84aed7b2196caa4d64a62583898
|
|
| MD5 |
548de3bf0a3ee09b1b3e583b524b0a9f
|
|
| BLAKE2b-256 |
3895d9f56beab9c5c07214e0c2aeab1a514ea0fc24463e354bcb4c74869b9597
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cb2ab31ad1fdc675d0c53bba44ee92744979882c5dfbe1909feea68009cdce3
|
|
| MD5 |
3dfb5dc065fe9d419a9387d7220db3bc
|
|
| BLAKE2b-256 |
3fffe7063ef50d8e079a53bba5ac41d6924583ad2464bee34cb1611801f10b4d
|