Metadata-Version: 2.4
Name: intflow-auth-sdk
Version: 0.2.0
Summary: Intflow Auth relying application SDK.
Author: Intflow
License: Proprietary
Requires-Python: >=3.12
Requires-Dist: httpx<1,>=0.28
Requires-Dist: pyjwt[crypto]<3,>=2.10
Provides-Extra: dev
Requires-Dist: build<2,>=1.2; extra == 'dev'
Requires-Dist: hatchling<2,>=1.27; extra == 'dev'
Requires-Dist: mypy<2,>=1.13; extra == 'dev'
Requires-Dist: pytest-asyncio<2,>=1.3; extra == 'dev'
Requires-Dist: pytest-cov<8,>=6; extra == 'dev'
Requires-Dist: pytest<9,>=8; extra == 'dev'
Requires-Dist: ruff<1,>=0.9; extra == 'dev'
Requires-Dist: twine<7,>=6; extra == 'dev'
Description-Content-Type: text/markdown

# Intflow Auth SDK

Python SDK for relying applications that integrate with Intflow Auth.

This package is for application backends that need to validate Intflow-issued
tokens and enforce application roles. It does not provide operator credential
storage, service runtime components, or Admin API automation.

## Install

```powershell
python -m pip install intflow-auth-sdk
```

## Current Status

This package provides PKCE helpers, nonce-aware authorization URL construction,
state-validating callback parsing, OIDC discovery/JWKS caching, strict Intflow
access/ID-token verification, application-role checks, and sync/async trusted
backend clients for authorization-code exchange, refresh rotation, and
revocation. Lifecycle clients return credentials but never persist them.

```python
from intflow_auth_sdk import create_token_verifier, require_app_role

with create_token_verifier(audience="your-oauth-client-id") as verifier:
    verified = verifier.verify_access_token(access_token)
    identity = verifier.verify_id_token(
        id_token,
        access_token=access_token,
        expected_nonce=stored_nonce,
    )
    require_app_role(verified.payload, "admin")

print(verified.payload["sub"])
```

```python
from intflow_auth_sdk import create_oauth_client

with create_oauth_client(
    client_id="your-oauth-client-id",
) as oauth:
    tokens = oauth.exchange_authorization_code(
        code=callback.code,
        redirect_uri="https://app.example.test/auth/callback",
        code_verifier=stored_code_verifier,
    )
    rotated = oauth.refresh_token(refresh_token=stored_refresh_token)
    oauth.revoke_token(token=rotated.refresh_token)
```

Confidential credentials use HTTP Basic authentication and are never sent in
query or form data. Credential-bearing redirects are refused. Replace the
stored refresh token only after a successful rotation. Confidential clients
must supply their optional client secret from server-only configuration.

Long-running services should create one `IntflowTokenVerifier` or
`AsyncIntflowTokenVerifier` during startup, reuse it for request handling, and
call `close()` or `aclose()` during shutdown. One-shot helper functions remain
available for scripts and tests. Concurrent cache misses share one discovery or
JWKS refresh per verifier, and cancelling one async waiter does not cancel the
refresh for other callers. Unknown key IDs refresh JWKS without refetching
still-fresh discovery metadata.

Long-running lifecycle integrations should likewise reuse one
`IntflowOAuthClient` or `AsyncIntflowOAuthClient`. Caller-supplied `httpx`
clients remain caller-owned.

For local fake-token examples, see `examples/python-sdk-consumer`.
