Six ways in. One contract.
Every surface reaches the same endpoint, returns the same three decisions and obeys the same enforcement contract. They differ in who writes the branch and where the seam sits. Only the surfaces on this page are supported.
Prefer the thinnest integration you can use.
If two apply, prefer the one further up the list. A framework adapter is a thinner integration than a hand-written SDK call, and an SDK is a safer integration than raw HTTP. Every row has the same approval behaviour: approval_required stops the call and nothing resumes it.
| Surface | Who writes the branch |
|---|---|
| CLI | Your shell, on the exit status. Exit 0 is ALLOW and nothing else; 3 blocked, 4 held, 5 configuration, 6 network. |
| REST | You, entirely. This is the surface where fail-open mistakes are easiest to make. |
| Python SDK | You, around a typed decision. Every failure is an AnubisError. |
| TypeScript SDK | You, around a typed decision. Node 20.10+, zero runtime dependencies. |
| Framework adapters | The adapter, at the tool seam. You write no call site. |
The same decision in front of every tool, without a call site to write.
from anubis import AnubisClient
from anubis.adapters.langchain import guard_tools
agent = create_react_agent(llm, guard_tools(AnubisClient(), [search, issue_refund]))| Framework | Entry point · what is guarded |
|---|---|
| LangChain, LangGraph | anubis.adapters.langchain: BaseTool.run and arun |
| CrewAI | anubis.adapters.crewai: BaseTool._run and _arun |
| AutoGen | anubis.adapters.autogen: the registered callable |
| OpenAI Agents SDK | anubis.adapters.openai_agents: FunctionTool.on_invoke_tool |
| LangChain.js, LangGraph.js | anubis-sdk/langchain: StructuredTool.call |
This is the complete list
Each entry has a real wrapper export and a test suite that runs against the real framework in CI, with skipped tests treated as failures. The control plane's integration catalog lists other platforms as inventory metadata - a catalog entry is not an enforcement integration.
The bypass boundary
Adapters wrap tool objects. They do not intercept your process. Keeping a reference to an unwrapped original and calling that instead is outside the protection - guard at construction and hand only the guarded objects to the agent.
When you write the branch yourself.
SDK
Python
Sync and async clients with an identical surface. Bounded retries that replay a POST only when the replay is deduplicated server-side. The credential appears in no repr, exception or log record.
SDK
TypeScript
HTTP is the platform's own fetch. ESM and CommonJS with declaration files. A parity test asserts the contract against the Python sources so the two cannot drift. No browser build.
HTTP
REST
Generated OpenAPI and a Postman collection, regenerated from the live application by a release gate. Anubis ships no platform-specific plugin, deliberately - the HTTP node your platform already has is the supported integration.
Shell
CLI
Onboarding and runtime from a terminal. It never executes your tool: it returns a decision and an exit status. Secrets come from the environment or stdin - there is deliberately no credential flag on any command.
Installed from source, not from a registry.
Nothing is published to PyPI or npm. You install from the checkout, or from a wheel or tarball built from it. Frameworks are optional extras: a plain Python install still brings httpx alone, and the LangChain.js adapter adds nothing to a Node install.
Private access
Not sure which surface fits?
Tell us what your agent is built on and we will tell you which one is thinnest - including when the answer is none of them yet.