gait-sdk
The official Python SDK for Gait, an identity and security platform. Drop it into a Django REST Framework or FastAPI service to verify who is calling you, using identities Gait issues. It never issues tokens, stores passwords, or makes authorization decisions.
Gait authenticates — who are you? (login, 2FA, sessions, signed tokens)
gait-sdk verifies — is this token genuine, and whose is it?
your application authorizes — what may this person do here?
That boundary is the core design rule. The SDK hands your code a verified identity (subject, email, session, token id, issuer). Roles, organizations and permissions belong to your application. See Architecture.
Install
pip install "gait-sdk[django]" # Django REST Framework services
pip install "gait-sdk[fastapi]" # FastAPI services
pip install gait-sdk # core only (verification, sessions, app identity)
Requires Python 3.10+. Pin exact versions in production (gait-sdk==0.5.0). See Supply chain.
Quick start: Django REST Framework
# settings.py
INSTALLED_APPS = [..., "gait_sdk"] # validates configuration at startup
REST_FRAMEWORK = {
"DEFAULT_AUTHENTICATION_CLASSES": ["gait_sdk.authentication.ExternalJWTAuthentication"],
}
GAIT_TOKEN_VERIFIER = "jwks" # verify locally (recommended)
GAIT_JWKS_URL = "https://auth.example.com/.well-known/jwks.json"
GAIT_ISSUER = "https://auth.example.com"
GAIT_AUDIENCE = "urn:gait:your-app"
GAIT_AUTH_URL = "https://auth.example.com/api" # used for live session checks
# views.py
from gait_sdk.django.authentication import require_live_session
class FinalizeReport(APIView):
def post(self, request, pk):
identity = request.verified_identity # subject, email, session_id, token_id, issuer
... # YOUR authorization check first
require_live_session(request) # sensitive action: confirm the session live
... # then mutate
Quick start: FastAPI
from fastapi import Depends, FastAPI
from gait_sdk.fastapi.dependencies import require_live_session, validate_configuration, verify_token
app = FastAPI()
validate_configuration() # fail at startup, not on the first request
@app.get("/me")
async def me(claims: dict = Depends(verify_token)):
return {"subject": claims["id"], "email": claims["email"]} # "id" works in both verifier modes
@app.post("/danger")
async def danger(claims: dict = Depends(require_live_session)):
...
Configuration
| Setting | Default | Purpose |
|---|---|---|
GAIT_TOKEN_VERIFIER |
introspection |
jwks = verify tokens locally against Gait's published keys (recommended). introspection = ask Gait /whoami/ on every request (legacy). Chosen explicitly, with no automatic fallback. |
GAIT_JWKS_URL |
— | Required for jwks. Must be https (plain http only for localhost). |
GAIT_ISSUER |
— | Required for jwks. Must equal Gait's JWT_ISSUER exactly. |
GAIT_AUDIENCE |
— | Required for jwks. Must equal Gait's JWT_AUDIENCE. |
GAIT_AUTH_URL |
— | Gait's API base (…/api), used by live session checks, introspection, application identity and signals. https required (http only for localhost). |
GAIT_TIMEOUT |
5 |
Seconds for calls to Gait. |
GAIT_APPLICATION_CREDENTIAL |
— | Only for application identity / security signals. A secret: keep it in the environment. |
GAIT_ALLOW_COOKIE_AUTH |
False |
Deprecated legacy cookie mode (introspection only). Leave off. See Security. |
Settings come from Django settings first, then environment variables / .env. An invalid or incomplete configuration stops the service at startup.
What you get
| Module | For |
|---|---|
gait_sdk.verification |
Token verification (JwksVerifier, IntrospectionVerifier) → VerifiedIdentity |
gait_sdk.session |
check_session_live(): live revocation check for sensitive actions |
gait_sdk.authentication / gait_sdk.django |
DRF authentication class, require_live_session(request) |
gait_sdk.fastapi.dependencies |
verify_token, require_live_session, validate_configuration |
gait_sdk.application |
Verify your service's own Gait credential (machine identity) |
gait_sdk.context |
SecurityContext: human identity + application identity together |
gait_sdk.security |
Send tenant security signals to Gait |
Security, in one screen
- RS256 only.
alg=none, HS256 key-confusion and unknown algorithms are rejected.iss,aud,exp,iat,sub,sid,jtiandtoken_use="access"are all required. - The SDK holds no secrets for verification. It only ever has Gait's public keys, so it cannot mint tokens even if compromised.
- Fails closed: an invalid token → 401; Gait unreachable → 503. It never falls back to a weaker check.
- Real 401s (not DRF's silent 403), so clients' refresh-on-401 logic works.
- Revocation: local verification sees a revoked session only when its token expires (≤15 min). Protect sensitive actions with
require_live_session. - No token, cookie or credential value is ever logged.
Full threat model, guarantees, limits and audit history: docs/SECURITY.md. To report a vulnerability, see the same file.
Upgrading from auth_integration
The package was renamed in 0.5.0. The old import name still works as a deprecated alias until 0.6.0, returning the same modules, so nothing breaks while you migrate:
pip install gait-sdk(replacing the old git URL pin).- Replace
auth_integrationwithgait_sdkin imports,INSTALLED_APPS, and DRF settings strings.
Details: Integration guide.
Documentation
| Architecture | The boundary, components, verification & caching, trust model |
| Integration guide | Wiring into Django/FastAPI, JWKS cut-over runbook, sensitive actions, testing |
| Security | Threat model, guarantees, known limits, hardening checklist, audit log, reporting |
| Publishing | How releases reach PyPI (a step-by-step tutorial), and consuming safely |
| Changelog | Version history |
| Module references | gait_sdk/docs/ |
License
MIT, © Anthony Narine.
Release files for gait-sdk 0.5.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 | |
|---|---|---|---|
| gait_sdk-0.5.0.tar.gz | 72.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| gait_sdk-0.5.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 122.2 kB
Release files / gait_sdk-0.5.0.tar.gz
| Download URL | gait_sdk-0.5.0.tar.gz |
|---|---|
| Size | 72.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c37b92100187be740cf47444dce26c03a3ddb7cafe9a975046a514fa82fa3fe1
|
|
BLAKE2b-256 checksum How to use checksums |
1f14705ea37c0fbb4ed75357f2c68928dee944d2f75a899b280740562ec4b7f2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency logRelease files / gait_sdk-0.5.0-py3-none-any.whl
| Download URL | gait_sdk-0.5.0-py3-none-any.whl |
|---|---|
| Size | 49.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cbccd352aa7d8d3e50ab5aa567da9142eae145defd50bb72f17bd8fae3b23ad6
|
|
BLAKE2b-256 checksum How to use checksums |
c1d1465ad7c5d9ad5c7f09fadbbc7afb51fac315a7cbb254998c12fbad09a084
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 25, 2026.
Transparency log