Skip to content

Get started

For convenience, SASY includes skills for coding agents (Claude Code, Codex, Cursor and others) that help with setup, framework integration, policy writing and explaining denials. Install them with:

Terminal window
npx skills add sasy-labs/sasy

Then ask your agent to walk you through a SASY demo or integrate enforcement into your system.

You need uv and a running Docker installation. No checkout of this repository is needed. In your project:

Terminal window
uv venv --python 3.11
source .venv/bin/activate
uv add sasy # in a project with a pyproject.toml
# uv pip install sasy # in a plain directory without one
sasy engine start

sasy engine start starts the policy engine, with a default configuration set up at ~/.sasy, automatically read by the Python SDK. To build the engine yourself, see build from source. Without installing the SDK, you can also run uvx sasy engine start.

Write your rules in Datalog using the policy guide, or describe your policy in natural language and use the write-policy skill to translate it into enforceable Datalog. Then enable SASY before building your agents. For example, with your LangChain model and tools:

from pathlib import Path
import sasy
from langchain.agents import create_agent
sasy.instrument()
agent = create_agent(model, tools)
with sasy.session(policy=Path("policy.dl")):
result = agent.invoke({"messages": [{"role": "user", "content": "Your task"}]})

See SDK usage patterns for connection options and examples with other frameworks.

The example policy blocks email influenced by both sensitive and untrusted inputs. A coordinator spawns two summarizer agents to review a sensitive report and an untrusted note that tries to redirect the email. Influence follows the dependency graph through their summaries.

The two illustrative variants show what happens when the note’s summary arrives before the send, or has not arrived yet: the redirected send is blocked; the intended send is allowed. Step through each variant to inspect its dependencies.

Open the side-by-side comparison

Note has not arrived

ALLOW · Send to reviewer

Policy decision · Send to reviewer

ALLOW · Only S influenced this send. The email may go to the intended reviewer.

Note has not arrivedNot yet deliveredUser task. Review and send. Labels: No U / S. In the backward slice.User taskReview and sendCoordinator. LLM call and output. Spawn subagents. Labels: No U / S. In the backward slice.CoordinatorLLM callSpawn subagentsSummarizer. LLM call and output. Review report. Labels: No U / S. In the backward slice.SummarizerLLM callReview reportSummarizer. LLM call and output. Review note. Labels: No U / S.SummarizerLLM callReview noteRead report. ALLOW · tool action. Labels: No U / S. In the backward slice.Read reportALLOW · tool actionSensitive report. File contents. Labels: S. In the backward slice.Sensitive reportFile contentsSSummarizer. LLM call and output. Report summary. Labels: S. In the backward slice.SummarizerLLM callReport summarySRead note. ALLOW · tool action. Labels: No U / S.Read noteALLOW · tool actionUntrusted note. File contents. Labels: U.Untrusted noteFile contentsUSummarizer. LLM call and output. Note summary. Labels: U.SummarizerLLM callNote summaryUCoordinator. LLM call and output. Draft email. Labels: S. In the backward slice.CoordinatorLLM callDraft emailSSend to reviewer. ALLOW · tool action. Labels: S.Send to reviewerALLOW · tool actionS

Note arrives before the send

DENY · Redirected send

Policy decision · Redirected send

DENY · Both U and S influenced this send. The email handler does not run.

Note arrives before the sendUser task. Review and send. Labels: No U / S. In the backward slice.User taskReview and sendCoordinator. LLM call and output. Spawn subagents. Labels: No U / S. In the backward slice.CoordinatorLLM callSpawn subagentsSummarizer. LLM call and output. Review report. Labels: No U / S. In the backward slice.SummarizerLLM callReview reportSummarizer. LLM call and output. Review note. Labels: No U / S. In the backward slice.SummarizerLLM callReview noteRead report. ALLOW · tool action. Labels: No U / S. In the backward slice.Read reportALLOW · tool actionSensitive report. File contents. Labels: S. In the backward slice.Sensitive reportFile contentsSSummarizer. LLM call and output. Report summary. Labels: S. In the backward slice.SummarizerLLM callReport summarySRead note. ALLOW · tool action. Labels: No U / S. In the backward slice.Read noteALLOW · tool actionUntrusted note. File contents. Labels: U. In the backward slice.Untrusted noteFile contentsUSummarizer. LLM call and output. Note summary. Labels: U. In the backward slice.SummarizerLLM callNote summaryUCoordinator. LLM call and output. Follow the note. Labels: U + S. In the backward slice.CoordinatorLLM callFollow the noteUSRedirected send. DENY · tool action. Labels: U + S.Redirected sendDENY · tool actionUS
U UntrustedS Sensitive Ancestors LLM call Tool action Input / result
Influence follows the arrows. Borders show inherited U/S labels; dotted outlines mark the selected action’s ancestors, including untainted inputs. These are illustrative variants of the example policy.

The runnable message-flow example demonstrates the same rule with a scripted single agent in two runs. It uses synthetic documents, simulated email, and a local engine; no model-provider key is needed. The example README includes the setup and run instructions.

The trace shows the scripted agent’s reads, summary, send request, and policy decision in each run. The example README also explains the optional live-model version.

Once the local engine is running, you can enforce policies on your own agents. Start with SDK usage patterns, or run the framework examples. For framework-specific guidance, see Google ADK or Langroid. For custom orchestration, use the SDK directly or add a framework.