Metadata-Version: 2.5
Name: sasy
Version: 0.5.0
Summary: Policy enforcement for LLM agent tool calls, decided from each call's message ancestry
Project-URL: Homepage, https://docs.sasy.ai
Project-URL: Documentation, https://docs.sasy.ai
Project-URL: Repository, https://github.com/sasy-labs/sasy
Project-URL: Issues, https://github.com/sasy-labs/sasy/issues
Author: Sasy, Inc.
License-Expression: Apache-2.0
License-File: LICENSE
License-File: NOTICE
Keywords: agents,authorization,datalog,google-adk,langchain,llm,policy,prompt-injection,provenance
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Requires-Dist: cryptography>=44.0.0
Requires-Dist: grpcio>=1.80.0
Requires-Dist: httpx>=0.28.1
Requires-Dist: networkx>=3.0
Requires-Dist: opentelemetry-api>=1.20.0
Requires-Dist: protobuf>=6.31.1
Requires-Dist: pydantic-settings>=2.0.0
Requires-Dist: pydantic>=2.0.0
Requires-Dist: pyjwt[crypto]>=2.8.0
Requires-Dist: pyyaml>=6.0
Requires-Dist: requests>=2.32.0
Requires-Dist: wrapt>=1.14.0
Provides-Extra: adk
Requires-Dist: google-adk==2.9.1; extra == 'adk'
Provides-Extra: all
Requires-Dist: google-adk==2.9.1; extra == 'all'
Requires-Dist: langchain-core==1.6.3; extra == 'all'
Requires-Dist: langchain==1.4.0; extra == 'all'
Requires-Dist: langgraph-prebuilt==1.1.0; extra == 'all'
Requires-Dist: langgraph==1.2.11; extra == 'all'
Requires-Dist: langroid<=0.67.8,>=0.67.1; extra == 'all'
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'all'
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == 'all'
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'all'
Provides-Extra: langchain
Requires-Dist: langchain-core==1.6.3; extra == 'langchain'
Requires-Dist: langchain==1.4.0; extra == 'langchain'
Requires-Dist: langgraph-prebuilt==1.1.0; extra == 'langchain'
Requires-Dist: langgraph==1.2.11; extra == 'langchain'
Provides-Extra: langroid
Requires-Dist: langroid<=0.67.8,>=0.67.1; extra == 'langroid'
Provides-Extra: otel
Requires-Dist: opentelemetry-api>=1.20.0; extra == 'otel'
Requires-Dist: opentelemetry-exporter-otlp>=1.20.0; extra == 'otel'
Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'otel'
Description-Content-Type: text/markdown

# sasy

Python client for [SASY](https://github.com/sasy-labs/sasy). It records the inputs
behind an agent's actions and asks the policy engine for a decision before each
protected tool runs.

The engine runs separately; follow [local engine setup](https://docs.sasy.ai/local-engine/)
before running an agent.

## Install

Install in a Python 3.11 or newer environment, then start the local engine with
Docker running:

```bash
pip install sasy
sasy engine start
```

For repository examples, use the
[checkout setup](https://docs.sasy.ai/local-engine/#repository-examples).

## Protect an agent

Local setup saves a selected connection profile in `~/.sasy`. The Python SDK
uses it from any project unless you configure another endpoint. Enable
instrumentation before building any agents:

```python
import sasy

sasy.configure()
sasy.instrument()
```

Run each task inside `with sasy.session(policy=...)`. The session records its
messages and binds the policy used to check tool calls. Cooperating agents share
the same session.

Supported frameworks: [LangChain](https://docs.sasy.ai/integrations/langchain/),
[Google ADK](https://docs.sasy.ai/integrations/google-adk/), and
[Langroid](https://docs.sasy.ai/integrations/langroid/).

For a complete runnable program, follow [framework examples](https://docs.sasy.ai/examples/)
or try the [LangChain examples](https://github.com/sasy-labs/sasy/tree/main/examples/langchain-information-flow).

Instrumentation enables supported installed frameworks. An unusable framework
is skipped with a warning; pass its flag as `True`, such as
`sasy.instrument(langchain=True)`, to require it. HTTP checks are off by default.
See [instrumentation options](https://docs.sasy.ai/instrumentation/)
for selection and HTTP behavior.

## Use the client directly

```python
import json
from pathlib import Path

import sasy

sasy.configure()
with sasy.session(policy=Path("read-only.dl")):
    decision = sasy.check_tool_call("Read", json.dumps({"file_path": "notes.txt"}))
    if decision.authorized:
        # Perform the protected action here.
        print(Path("notes.txt").read_text())
```

Supply your own policy file. For checks that depend on earlier messages, your
integration must also record those dependencies. See the
[adapter guide](https://docs.sasy.ai/instrumentation/).

See [configuration](https://docs.sasy.ai/configuration/),
[authentication](https://docs.sasy.ai/authentication/), and the
[security model](https://docs.sasy.ai/limits/) for setup and supported boundaries.
