Product

Runtime enforcementPolicy engineAgent governanceApprovalsEvidence

Developers

Developer guideIntegrationsArchitecture

Company

SecurityCompany
Request access

Runtime authorization for AI agents

Agents act.Humans decide.

Anubis puts a policy and authorization decision in front of every sensitive tool call an agent makes - before the call runs, and with a record written either way.

Agents
Research Agent/run
Research AgentResearch enterprise AI governance vendors
Task

Research enterprise AI governance vendors

Analyze requestCompare governance vendors0.3s
Inspect available toolsweb.search0.2s
Build the tool callSearch public vendor documentation0.2s
Wait for runtime decisionThe external system remains untouched until the evaluation returns
research_agent.pySearch
1request = {2    "agent": "research-agent",3    "tool": "web.search",4    "action": "Search public vendor documentation",5    "environment": "production",6}7 8decision = anubis.evaluate(**request)9decision.raise_for_decision()10 11# exact allow is the only executable path
ANUBISruntime/evaluate
Incoming callweb.searchSearch public vendor documentation
Runtime identityWaiting for the tool callwaiting
Agent standingNot evaluated yetwaiting
Policy matchNot evaluated yetwaiting
Risk thresholdNot evaluated yetwaiting
Decision
ALLOW

A read-only research tool on this agent's allow-list, well under the risk threshold.

Policyresearch-baseline v4Risk12 / 35EvidenceEVD-2C7B41

The model decides what to say.
The agent decides what to do.
Anubis sits between intent and action.

Access control already answers whether an identity may reach a system. It cannot tell reading an invoice apart from paying one - same identity, same credential, same system, and only the action is different.

  1. 01

    Identify

    Every governed call arrives with an agent-bound runtime credential. Anubis resolves the organisation, the agent, the environment and the granted scopes server-side - the caller cannot assert them.

  2. 02

    Evaluate

    Policy is data, not a prompt: allow-lists, deny rules and thresholds read by a deterministic engine, alongside a deterministic risk score. The same request against the same policy version produces the same answer.

  3. 03

    Enforce

    Anubis returns allow, block or approval_required, and the evidence is committed before the answer is. Your enforcement point branches on it. Anything that is not an exact allow does not run.

Three answers.
One of them runs your tool.

allow
Execute the tool exactly once.
Policy permits this call and the decision is already recorded. Nothing is queued, nothing waits.
approval_required
Stop the run. Escalate the approval id.
Held for a named reviewer. A hold is not a deferred allow: nothing resumes it, and the reviewer's judgement is recorded beside the hold, not over it.
block
Do not execute. Do not retry.
The answer is about this request and will be identical if you ask again. Surface the reason to whatever is driving the agent.

Anything that is not an exact allow does not run.

A timeout, a transport failure, an authentication failure, a validation error, an unparseable body, or a decision value outside the three-word vocabulary are all refusals. There is exactly one path on which a governed tool executes: HTTP 200, a JSON object, and decision == "allow". Anubis never runs your tool, holds your credentials for it, or proxies your traffic - every enforcement point is one you installed. How enforcement works

Two lines around
a tool call.

Anubis does not replace your agent framework and does not want to own your runtime. Every surface below ships a wrapper, a test suite that runs against the real framework, and a runnable example.

import { Anubis, AnubisError } from "anubis-sdk";

const anubis = new Anubis();

try {
  const decision = await anubis.evaluate({
    toolName: "billing.refund.create",
    action:   "Refund invoice INV-88213",
    input:    { amount: 12400 },
  });

  decision.throwIfNotAllowed();
  await issueRefund(12400);
} catch (err) {
  if (err instanceof AnubisError) return refuse(err);
  throw err;
}
from anubis import AnubisClient
from anubis.adapters.langchain import guard_tools

# Guard at construction, then hand only the guarded objects to the agent.
tools = guard_tools(AnubisClient(), [search, issue_refund])
agent = create_react_agent(llm, tools)

# The adapter owns the branch at BaseTool.run and arun.
# ALLOW lets the framework's own call proceed. BLOCK,
# APPROVAL_REQUIRED and every failure raise, and the
# tool does not run.
POST /api/runtime/evaluate
Authorization: Bearer anb_v1_live_<key_id>_<secret>
Content-Type: application/json
Idempotency-Key: wf-3081-step-4

{ "tool_name": "billing.refund.create",
  "action":    "Refund invoice INV-88213",
  "input":     { "amount": 12400 },
  "context":   { "correlation_id": "wf-3081" } }

# Execute only when the response is HTTP 200, the body is a
# JSON object, and decision == "allow". Everything else refuses.

Never write decision != "block". The vocabulary is closed, and only equality with allow fails closed against a value the contract does not name.

Supported integration surfaces

  • Python SDK3.11 · 3.12 · sync and async
  • TypeScript SDKNode 20.10+ · zero dependencies
  • RESTTwo endpoints, one header
  • LangChain · LangGraphPython · JS
  • CrewAIPython
  • AutoGenPython
  • OpenAI AgentsPython
  • CLIExit 0 is ALLOW, and nothing else
Every supported surfaceDeveloper guideInstalled from source - not published to PyPI or npm yet.

The decision was already written
before the answer came back.

Every accepted evaluation commits its runtime event, its approval and its audit entry in the same transaction that produces the answer. A decision that could not be recorded is returned as a refusal, not as an allow.

  1. 14:12:04EVD-8C1188ticket.reply.sendsupport-agentAllowed
  2. 14:16:55EVD-8C11A2crm.contacts.exportrevops-agentBlocked
  3. 14:19:02EVD-8C11B6netsuite.readfinance-agentAllowed
  4. 14:21:31EVD-8C11C7payments.create_transferfinance-agentApproval required
  5. 14:24:02EVD-8C11C7 / resolutionapproval.resolves.okafor · security_leadRejected

You watched this one happen.

The runtime event is immutable. The reviewer's judgement is written beside it, never over it - the record that policy held the action survives whatever a human later decides. Evidence and audit

Common questions

Still unclear on where Anubis fits? Ask us directly.

What is Anubis?

Anubis is a runtime authorization layer for AI agents: a control plane for agent identity, policy and governance, and a pre-execution authorization service for the tool calls those agents make. Your agent runtime asks Anubis before a governed tool call, and Anubis answers allow, block or approval_required. Every answer is recorded before it is returned.

What is AI agent runtime security?

It is the practice of controlling what an autonomous agent may actually do at the moment it tries to do it, rather than only controlling which systems it can reach. A model can be given a tool without being given permission to use that tool for every possible action. Runtime security places an authorization decision between the agent's intention and the execution of the action.

Does Anubis execute or block my tool?

No. Anubis returns a decision; your code branches on it. It has no ability to run, cancel or undo a tool call, it never holds your credentials for that tool, and it does not proxy your traffic. The framework adapters write that branch for you at the tool seam, which is why they are the thinnest integration.

What happens when Anubis is unreachable?

The tool does not run. A timeout, a transport failure, an authentication failure, a validation error, an unparseable body, or a decision value outside the three-word vocabulary are all refusals. There is exactly one path on which a governed tool executes: HTTP 200, a JSON object, and decision == "allow".

What happens when human approval is required?

The call is held and does not execute. Anubis returns an approval_id naming a review that a security lead resolves in the control plane. Resolution records a human judgement - it does not turn that decision into an allow, and nothing resumes the original call automatically. If the work should continue, your system re-enters it as a new run, which makes a fresh evaluation and may be held again.

Does Anubis use an LLM to decide?

No. Policy is data - allow-lists, deny rules and thresholds - evaluated by a deterministic engine. Risk is a deterministic score computed by Anubis, not a parameter the caller can send. The same request against the same policy version produces the same decision.

Does Anubis automatically find the agents already running in my company?

No. There is no discovery, no traffic interception and no process-wide hook. Every enforcement point is one you installed: an explicit call or a guarded tool object. A code path that never asks is not governed, and the kill switch cannot reach it either. Coverage is deliberate work.

How long does an integration take?

For a framework-built agent, guarding your tools at construction is a few lines. For a hand-written runtime, it is an evaluate call and a branch around each governed tool. The harder work is not the code - it is deciding which actions belong in each of the three answers.

Private access

Put a human boundary around agent action.

We are working with a small number of security, platform and AI teams putting real agents in front of real systems. If that is you, bring one agent and one action you would not want it taking unsupervised.

Anubis - Runtime authorization for AI agents