Metadata-Version: 2.4
Name: authsec-langgraph-sdk
Version: 0.1.0
Summary: AuthSec identity and delegation for LangGraph stateful agent workflows
Author-email: AuthSec <support@authsec.ai>
License: Apache-2.0
Project-URL: Homepage, https://authsec.ai
Project-URL: Documentation, https://docs.authsec.ai
Project-URL: Source, https://github.com/authsec-ai/authsec-langgraph
Keywords: langgraph,langchain,authsec,auth,spiffe,delegation,agents
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: authsec-langchain-sdk>=0.1.0
Requires-Dist: langgraph>=0.2
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: respx>=0.21; extra == "dev"
Requires-Dist: ruff>=0.5; extra == "dev"
Provides-Extra: examples
Requires-Dist: langchain>=0.2; extra == "examples"
Requires-Dist: langchain-openai>=0.1; extra == "examples"

# authsec-langgraph-sdk

**AuthSec identity and delegation for LangGraph stateful agent workflows.**

Give every node in your LangGraph state machine a scoped, short-lived, audited identity — without any node having to fetch credentials manually.

[![PyPI](https://img.shields.io/pypi/v/authsec-langgraph-sdk)](https://pypi.org/project/authsec-langgraph-sdk/)
[![Python](https://img.shields.io/pypi/pyversions/authsec-langgraph-sdk)](https://pypi.org/project/authsec-langgraph-sdk/)

Built on top of [`authsec-langchain-sdk`](https://pypi.org/project/authsec-langchain-sdk/). Same HTTP client; LangGraph-native bindings on top.

---

## Install

```bash
pip install authsec-langgraph-sdk
```

Pulls in `authsec-langchain-sdk` and `langgraph` automatically.

---

## What you get

Three integration shapes, pick whichever matches your graph:

| Helper | When to use it |
|---|---|
| `inject_authsec_state(state, client)` | Fine-grained: call from any node to refresh the JWT in state |
| `with_authsec_auth(node_fn, client)` | Decorator: wrap any node so it always sees a fresh `authsec_token` in state |
| `AuthsecNode(client)` | Standalone graph node: add it as the entry point or before any subgraph that needs auth |

Plus `AuthsecState` — a `TypedDict` you can compose into your graph's state schema so `authsec_token` is typed.

---

## Quick start

```python
from langgraph.graph import END, START, StateGraph
from authsec_langgraph import (
    AuthsecClient, AuthsecConfig, AuthsecNode, AuthsecState,
)

class MyState(AuthsecState):
    input: str
    result: str

authsec = AuthsecClient(AuthsecConfig(
    base_url="https://auth.example.com",
    client_id="a594430b-2bd4-4792-9666-63162ee858c5",
))

def call_downstream(state: MyState) -> dict:
    jwt = state["authsec_token"]    # populated by AuthsecNode
    # ... use jwt to call your API ...
    return {"result": "ok"}

graph = StateGraph(MyState)
graph.add_node("auth", AuthsecNode(client=authsec))
graph.add_node("work", call_downstream)
graph.add_edge(START, "auth")
graph.add_edge("auth", "work")
graph.add_edge("work", END)

app = graph.compile()
app.invoke({"input": "do the thing"})
```

`AuthsecNode` runs first, pulls a fresh delegation JWT, puts it in state. Every downstream node reads it from `state["authsec_token"]`. No node needs to know about HTTP, caching, or auth refresh.

---

## Why this exists

LangChain agents are mostly stateless — one prompt, one decision, one tool. LangGraph adds explicit state and routing for multi-step workflows. That means auth becomes a state-management problem too:

- Multiple nodes might need the same JWT — don't fetch N times
- Some subgraphs need elevated auth; others don't
- State persists across nodes; tokens have to be visible without leaking through unrelated nodes

This SDK gives you the primitives to handle that cleanly inside LangGraph's idioms.

---

## Examples in this repo

| File | What it does |
|---|---|
| [`examples/billing_lookup_graph.py`](examples/billing_lookup_graph.py) | 3-node graph: auth → classify → call downstream API. Mocked API so no cloud setup needed. |

Run:

```bash
$env:AUTHSEC_BASE_URL = "https://auth.example.com"
$env:AUTHSEC_AGENT_CLIENT_ID = "<agent UUID>"
python examples/billing_lookup_graph.py
```

---

## Relationship to `authsec-langchain-sdk`

This package **depends on** `authsec-langchain-sdk` and re-exports its core types:

```python
# These are all imported from authsec_langchain via authsec_langgraph:
AuthsecClient, AuthsecConfig
AuthsecError, DelegationError
CIBARequiredError, CIBADeniedError, CIBATimeoutError
```

So you don't need both packages installed separately. Install `authsec-langgraph-sdk` and you get the full surface.

If you have a LangChain agent that also uses LangGraph for some flows, install both — they coexist cleanly because the HTTP client is shared.

---

## What's in v0.1

| Feature | Status |
|---|---|
| `AuthsecNode` (callable graph node) | ✅ |
| `with_authsec_auth` (decorator wrapper) | ✅ |
| `inject_authsec_state` (pure function) | ✅ |
| `AuthsecState` typed dict | ✅ |
| Async node variants | ⏳ v0.2 |
| Conditional CIBA approval routing | ⏳ v0.2 |
| LangGraph checkpoint-aware token cache | ⏳ v0.3 |

---

## Development

```bash
git clone https://github.com/authsec-ai/authsec-langgraph
cd authsec-langgraph
pip install -e ".[dev]"
pytest
```

Tests are mocked; no live AuthSec needed for `pytest`.

---

## License

Apache 2.0
