Metadata-Version: 2.4
Name: kamiwaza-extensions-lib
Version: 0.6.2
Summary: Runtime library for Kamiwaza extensions: auth middleware, identity extraction, model client, session management
Author-email: Kamiwaza Team <eng@kamiwaza.ai>
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/kamiwaza-internal/kamiwaza-sdk
Project-URL: Changelog, https://github.com/kamiwaza-internal/kamiwaza-sdk/blob/main/kamiwaza_extensions_lib/CHANGELOG.md
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Framework :: FastAPI
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: httpx>=0.23
Requires-Dist: fastapi<1.0.0,>=0.136.3
Requires-Dist: starlette<2.0.0,>=1.3.1
Requires-Dist: idna<4,>=3.15
Requires-Dist: pydantic>=2.0
Provides-Extra: asgi
Requires-Dist: uvicorn>=0.30.0; extra == "asgi"
Dynamic: license-file

# kamiwaza-extensions-lib

Runtime library for Kamiwaza extensions. Provides FastAPI auth middleware,
identity extraction, a typed Kamiwaza model client, and session management
for extension backends.

This package is intentionally separate from `kamiwaza-sdk`: extension
backends need a lightweight async library, not the full SDK with its sync
HTTP client and 20+ service modules.

## Install

```bash
pip install 'kamiwaza-extensions-lib>=0.6,<0.7'
```

## Usage

```python
from kamiwaza_extensions_lib import (
    KamiwazaExtClient,
    platform_request,
    require_auth,
    extract_identity,
)
```

## Deployment-scoped ForwardAuth

On Envoy-routed extension deployments, the platform sets
`FORWARDAUTH_SIGNATURE_REQUIRED=true`, `FORWARDAUTH_SIGNATURE_AUDIENCE` to the
deployment UUID, and `FORWARDAUTH_SIGNATURE_SECRET` to that deployment's derived
verifier key. `extract_identity()` and `require_auth()` then verify Core's stable
signature before trusting user or workroom headers. Missing verifier settings,
an absent or modified signature, a different audience, or an expired timestamp
reject the request. A configured audience requires verification even if the
separate required flag is absent; a conflicting `false` flag is rejected.
`X-User-Marking-Level` is accepted only when Core's signature covers it; an
envelope from pre-ENG-8982 Core that signed the retired `X-User-System-High`
name still verifies (with no `marking_level` projected), and an unsigned claim
under either name, or non-empty values under both, is rejected. `identity_from_headers()` remains permissive in shape but
returns an anonymous identity when required verification fails. The platform
must supply the derived key; do not put its master signing secret in an extension.

## Calling platform APIs from an extension backend

Use `platform_request()` with the incoming FastAPI request and the exact,
canonical platform route. The path must be root-relative and include the
platform `/api` prefix; collection routes must include their canonical trailing
slash when the platform declares one:

```python
response = await platform_request(
    request,
    "GET",
    "/api/catalog/datasets/",
)
response.raise_for_status()
datasets = response.json()
```

The helper uses the container-routable platform URL, forwards the current
ForwardAuth envelope, and deliberately refuses to follow HTTP redirects. Set
the optional `timeout=` in seconds when the 30-second default is unsuitable.
Each call currently uses a short-lived client; connection pooling is tracked in
[GitHub issue #63](https://github.com/kamiwaza-internal/kamiwaza-sdk/issues/63). Do not
construct absolute platform URLs or use a raw `httpx.AsyncClient` for
request-bound platform calls. Caller headers cannot replace the envelope's
authentication, routing, framing, or `X-Request-Id` correlation fields.

User-bound clients ignore `HTTP_PROXY`, `HTTPS_PROXY`, `SSL_CERT_FILE`, and
`SSL_CERT_DIR`. For a private CA, mount its PEM bundle in the backend container
and set `KAMIWAZA_CA_BUNDLE` to that file path. Do not disable certificate
verification in production.

For untrusted content, set `max_response_bytes=` to a positive integer to limit
the returned body, including error responses. This option is unreleased; it
requires a runtime-library release containing the bounded-response change.
Bounded calls request identity encoding and reject compressed responses before
reading the body. They close the stream on overflow or cancellation. The limit
bounds the retained body, rather than total process memory or network buffers.
Calls without a limit keep their existing behavior.

The helper raises:

- `ValueError` for invalid paths, methods, headers, or caller overrides
- `MisboundAuthError` when the platform-provided ForwardAuth envelope is
  malformed or contains an ambiguous duplicate field
- `UnexpectedContextError` when `KAMIWAZA_API_URL` is missing or invalid, or a
  bounded response uses compressed encoding despite requesting identity encoding
- `PlatformRedirectError` (a specialized `UnexpectedContextError`) when the
  canonical route redirects
- `PlatformOutageError` for network, timeout, or upstream protocol failures
- `PlatformResponseTooLargeError` when a bounded response exceeds its byte limit

See `CHANGELOG.md` in this directory for release notes.
