Product

Runtime enforcementPolicy engineAgent governanceApprovalsEvidence

Developers

Developer guideIntegrationsArchitecture

Company

SecurityCompany
Request access

    One decision, before the tool call.

    Your agent runtime asks Anubis whether a proposed tool call may run. Anubis answers, records the answer, and returns it. That is the entire runtime product - and the reason it is worth trusting is what it does when something goes wrong.

    endpointPOST /api/runtime/evaluate
    momentpre-execution, and only pre-execution
    vocabularyallow · block · approval_required
    posturefail closed

    The boundary sits between intention and execution.

    Yours

    intention

    The model has decided it wants to call a tool.

    Anubis

    evaluate

    One synchronous call. One of three answers, recorded before it returns.

    Yours

    execution

    The side effect exists, or it never does.

    Before, not during

    Enforcement happens at one moment: after the model has decided and before the side effect exists. Anubis does not sandbox, contain or monitor a running tool, and after an allow it observes nothing.

    You own the branch

    Anubis returns a decision; your code acts on it. An integration that receives a decision and executes anyway is not governed - Anubis cannot detect that and cannot prevent it. Which is why the adapters write the branch for you.

    Three answers. The list is closed.

    Every governed call ends in one of three words. There is no fourth, no partial allow, and no severity scale to interpret.

    allow

    Execute the tool exactly once.

    Policy permits this call. The decision is already recorded.

    approval_required

    Do not execute. Stop and escalate.

    Held for a human reviewer. It has not been authorised, and nothing resumes it.

    block

    Do not execute. Do not retry.

    The answer is about this request and will be identical. Surface the reason.

    block and approval_required are returned as HTTP 200. A 200 means a decision was produced and durably recorded. It does not mean permission. The vocabulary is closed: Anubis will not return a fourth value, and a client that sees one must treat it as a refusal rather than guess.

    Everything else is a refusal.

    There is exactly one path on which a governed tool runs. Every error, every timeout and every value the contract does not name stops the call.

    The branch : every integration makes this one
    POST /api/runtime/evaluate | +-- HTTP 200 AND body is a JSON object AND body.decision == "allow" | | | +-- execute the tool exactly once | +-- anything else | +-- do not execute

    Refusals : none of these is a decision

    Conditions that are refusals rather than decisions
    Request timeoutAn enforcement gate that did not answer has not authorised anything.
    Transport, DNS, connection refusedAnubis being unreachable stops the agent. That is the design, not a degradation.
    401 authentication failureThe caller is not a known agent.
    403 scope failureThe caller is known but this call is outside its scope.
    400 or 422 validation, 413 too largeAnubis was never asked a question it could answer.
    409 idempotency conflictThe key was reused for a different request.
    503 persistence unavailableThe decision could not be recorded. An unrecorded allow is not an allow.
    503 policy or configuration unavailableNo decision was reached.
    A 2xx body that is not a JSON objectUnusable response.
    A decision value outside the threeNever coerced to the nearest known outcome, and never to allow.
    Retry budget exhaustedA retry budget is not a fallback.

    The backend cooperates with clients that only read the body: a 401, 403 or 503 carries "decision": "block" at the top level, so an integration that never inspects the status code still refuses. The SDKs go further and raise, so an authentication failure can never be pattern-matched as a policy outcome.

    Retries that cannot multiply evidence.

    Retry matrixPOST /api/runtime/evaluate
    When a retry of the decision call is safe
    Connect, DNS, or pool failureRetry - the request was never dispatched.
    Read timeout, write error, protocol errorOnly with an Idempotency-Key.
    429 · 502 · 503 · 504Only with an Idempotency-Key.
    400 · 401 · 403 · 409 · 413 · 422 · 500Do not retry.

    One allow, one execution

    An allow authorises the call that was evaluated, once. Do not cache it for a later call, and do not let a downstream step re-derive permission - the side effect is gated once, on the decision.

    Retries that cannot multiply evidence

    Every accepted evaluation writes an evidence row, so a blind retry after a timeout turns one tool call into several audit entries. Both SDKs send an Idempotency-Key per call; derive your own from <run id>-<step id> when a retry must survive a process restart.

    What runtime enforcement is not.

    Stated plainly, so nobody has to infer the boundary from what is missing.

    It does not execute, cancel or undo your tool call. It never touches your tool, your credentials for that tool, or its side effect.

    It does not intercept traffic. There is no transparent, process-wide or network-level interception. Every enforcement point is one you installed.

    It does not resume held work. No callback, no resume token, no consume endpoint, no poll API.

    It does not rate-limit. A valid credential may be used at any rate.

    It does not authenticate your end user. context.user is recorded, not verified.

    It does not guarantee a tool ran. Anubis records the decision it made, not the outcome of your execution.

    Private access

    See it in front of your agent.

    Bring one tool call you would not want made twice. We will put a decision in front of it.

    Runtime enforcement - Anubis