axowl-sdk (Python)
Backend SDK for Axowl: verify Axowl end-user access tokens on your server,
read the caller's permissions, and — when a decision must see revocations made after the token was
issued — ask Axowl directly. Mirrors @axowl/sdk-backend (Node) and Axowl.Sdk.Identity.Client (.NET).
pip install axowl-sdk # + "axowl-sdk[fastapi]" for the FastAPI dependency
Verify a token (no server round trip)
from axowl import AxowlConfig, verify_token, has_permission, AxowlAuthError
config = AxowlConfig(
org_slug="my-org", # your Axowl org
audience="client_xxxxx", # required: your application's client ID — tokens for another app are rejected
base_url="https://api.axowl.com", # default
)
try:
ctx = verify_token(bearer_token, config)
except AxowlAuthError as e:
... # e.reason ∈ missing_token | invalid_token | expired | signature | issuer | audience | jwks
ctx.user_id, ctx.email, ctx.org_slug, ctx.connected_id, ctx.is_employee
ctx.permissions # ["wallet.read", "report.*"] — decoded from the token
has_permission(ctx.permissions, "report.monthly") # True (wildcards honoured)
- Signature: RS256 against
{base_url}/api/public/orgs/{org_slug}/.well-known/jwks.json. Keys are cached for 10 minutes; an unknownkid(rotation) triggers a re-fetch. - Issuer must equal
{base_url}/api/public/orgs/{org_slug}— what Axowl writes into the token. - Audience must equal
audience, your application's client ID. Required since 0.2.0:verify_tokenandAxowlAuth(...)raiseValueErrorfor a config without it. Until 0.1.x the check was skipped whenaudiencewas unset, which accepted tokens issued for another application of the same organization. exp/nbfenforced (leeway_secondson the config if your clock drifts).
FastAPI
from fastapi import Depends, FastAPI
from axowl import AxowlConfig, AxowlContext
from axowl.fastapi import AxowlAuth
auth = AxowlAuth(AxowlConfig(org_slug="my-org", audience="client_xxxxx"))
app = FastAPI()
@app.get("/wallet")
def wallet(ctx: AxowlContext = Depends(auth)):
return {"user": ctx.email}
@app.post("/wallet/withdraw")
def withdraw(ctx: AxowlContext = Depends(auth.require("wallet.withdraw"))):
...
401 {"error": ..., "reason": ...} for a missing/invalid token, 403 {"error": ..., "required": [...]}
for a missing scope — the same shapes as the Express middleware.
Any other framework: call extract_bearer_token(request.headers["Authorization"]) then verify_token.
Server-authoritative checks
The JWT fast path cannot see a permission revoked after the token was issued. For those decisions
ask Axowl with your org API key (ah_live_…):
from axowl import AxowlIdentityClient
identity = AxowlIdentityClient(api_key="ah_live_...", base_url="https://api.axowl.com")
res = identity.introspect(bearer_token) # → IntrospectResult(active, principal, expires_at, issued_at)
res = identity.check_permission(bearer_token, "wallet.withdraw") # → PermissionCheckResult(granted, matched_scopes, reason)
Both are synchronous and stdlib-only (urllib); run them in a thread from async code.
Permission matching
Same rules as every other Axowl SDK and the server:
| pattern | scope | match |
|---|---|---|
sap.fi.document.post |
sap.fi.document.post |
yes |
sap.fi.* |
sap.fi.document.post |
yes |
* |
anything | yes |
sap.fi |
sap.fi.document.post |
no (a prefix without * is not a wildcard) |
Tests
pip install -e ".[test]" && pytest
Metadata
Release files for axowl-sdk 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| axowl_sdk-0.2.0.tar.gz | 13.7 kB | Without provenance | Details for axowl_sdk-0.2.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| axowl_sdk-0.2.0-py3-none-any.whl | Python 3 | none | any | Details for axowl_sdk-0.2.0-py3-none-any.whl |
Total release size: 26.3 kB
Release files / axowl_sdk-0.2.0.tar.gz
| Download URL | axowl_sdk-0.2.0.tar.gz |
|---|---|
| Size | 13.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
909fd3a4592d48aea5f2a2fafed67afbb9fcdc13d5b4ed8b645c003178f6ee09
|
|
BLAKE2b-256 checksum How to use checksums |
cd77def463c13faa968ba00d03e7f3559cca1c6372ae80d21562d721af1b1afa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.9
|
Release files / axowl_sdk-0.2.0-py3-none-any.whl
| Download URL | axowl_sdk-0.2.0-py3-none-any.whl |
|---|---|
| Size | 12.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d009cf6f517f9c61abf410db7bc5c47ec87c3cd0fe02eac1ea1c589f78442e4f
|
|
BLAKE2b-256 checksum How to use checksums |
a94d08e80c34ed504fcb5eb54db44ec09fc2fbfc2ba1ff9041f4921384002de2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.11.9
|
Security for axowl-sdk 0.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.