fabric/policy
The action-authorization gate, one for agent and graph runs.
A Policy(context) is supplied by the application and runs before any
effect. It sees one Action at a time: its run, where it comes from
(step: a tool call of an agent’s model turn, or an attempt of a graph
node’s activation), what it calls (name), the exact arguments (already
validated against the input codec), and what it does once allowed
(target). It allows the action, denies it with a reason, or requires
an approval. An Error is a policy failure: an agent run stops as a
host failure, a graph run fails, and nothing is allowed by default.
fn policy(user: User, action: policy.Action) {
case action.target {
policy.RunOperation(kind: policy.Signal, ..) -> Ok(policy.Allow)
_ -> {
use refund <- result.try(tool.input(refund_definition, action))
case refund {
Some(Refund(amount:)) if amount > 100 ->
Ok(policy.RequireApproval(run.Requirement("manager", 1)))
_ -> Ok(policy.Allow)
}
}
}
}
Types
One action to authorize. Read it by label: Fabric may add fields.
name is what the action calls: the tool’s name for an agent’s tool
call or delegation, the operation’s name for a graph node. For a graph
node, arguments_json is the operation’s encoded input.
pub type Action {
Action(
run: run.RunId,
step: Step,
name: String,
arguments_json: String,
target: Target,
)
}
Constructors
pub type Decision {
Allow
Deny(reason: String)
RequireApproval(run.Requirement)
}
Constructors
-
Allow -
Deny(reason: String)An agent’s model sees
reasonand its run continues; a graph run fails withgraph.Denied(reason). -
RequireApproval(run.Requirement)The action waits for an approval. A run whose remaining work is only waiting approvals suspends as stored data.
The kind of a graph node’s operation (see fabric/graph/operation).
This union may grow: keep a catch-all.
pub type OperationKind {
Activity
Signal
Job
OwnedJob
Subgraph
Agent
Fork
}
Constructors
-
ActivityA body runs, bounded by the runtime’s operation timeout.
-
SignalThe run waits for a signal (
operation.await_signal). -
JobThe run waits for a job it observes (
operation.await_job). -
OwnedJobThe run waits for a job it owns and may stop (
operation.own_job). -
SubgraphA child graph run starts (
graph.as_subgraph). -
AgentA child agent run starts (
fabric/graph/agent). -
ForkChild graph runs start together (
graph.both,graph.map).
Where an action comes from.
pub type Step {
ToolCall(id: run.ActionId)
Activation(activation: Int, attempt: Int)
}
Constructors
-
ToolCall(id: run.ActionId)A call in an agent’s model reply;
idnames it within its run. -
Activation(activation: Int, attempt: Int)Attempt
attempt(from 1) of activationactivationof a graph run. A recovered activation that replays its operation is a new attempt.
What an action does when it is allowed.
pub type Target {
InvokeTool
StartAgent(name: String, version: Int)
RunOperation(
node: String,
operation: run.DefinitionId,
kind: OperationKind,
)
}
Constructors
-
InvokeToolAn agent’s tool runs.
-
StartAgent(name: String, version: Int)A sub-agent run starts: the agent definition named
nameandversion, reached through the delegationAction.name. -
RunOperation( node: String, operation: run.DefinitionId, kind: OperationKind, )The operation of the graph node
noderuns (an activity), or its wait starts: a signal, a job, a child run or a fork.