Govern Agent Actions
guardrails routing For: platform & governance
Recording a decision tells you what did happen. Governing one means deciding what is allowed to happen — before the action runs. This guide adds two controls to the support-triage agent: a guardrail that authorizes the action, and a versioned policy that decides where it goes.
pip install briefcase-ai[guardrails,routing]-
Define a guardrail
A guardrail answers one question: may this agent perform this action on this resource? Subclass
BaseGuardrailEnvand implementevaluate, returning anEvalResultwith anEffect.from briefcase.guardrails import BaseGuardrailEnv, EvalRequest, EvalResult, Effectclass QueueGuardrail(BaseGuardrailEnv):@propertydef name(self) -> str:return "queue_access"@propertydef request_space(self):return {}def evaluate(self, request: EvalRequest) -> EvalResult:allowed = request.context.get("priority") == "high"return EvalResult(effect=Effect.ALLOW if allowed else Effect.DENY,guardrail_name=self.name,reason="priority check",) -
Evaluate before acting
Build the request that describes the action, evaluate it, and only proceed if it is allowed.
guardrail = QueueGuardrail()request = EvalRequest(agent="triage-bot",action="route",resource="queue:senior",context={"priority": "high"},)result = guardrail.evaluate(request)if result.is_allowed:... # perform the action -
Compose a pipeline and fail closed
Real systems chain several guardrails. A
GuardrailPipelineevaluates them in order and denies on the first denial (its default mode). Wrap the call so that any error becomes a denial — controls must fail closed, never open.from briefcase.guardrails import GuardrailPipelinepipeline = GuardrailPipeline(stages=[guardrail])def is_allowed(request: EvalRequest) -> bool:try:return pipeline.evaluate(request).is_allowedexcept Exception:return False # fail closed: an error never grants access -
Route the allowed action through a versioned policy
Once an action is permitted, decide where it goes — using a policy you can reconstruct later. Publishing a policy version is append-only, so the rule that fired is always recoverable.
from datetime import datetime, timezonefrom briefcase.routing import PolicyRegistry, PolicyVersion, PolicyRule, AgentRouterregistry = PolicyRegistry()registry.publish(PolicyVersion(policy_id="ticket-routing",version="1",rules=[PolicyRule(rule_id="high-priority",condition={"priority": "high"},choice="senior-queue",rationale="High-priority tickets go to the senior queue.",)],default_choice="standard-queue",),valid_from=datetime.now(timezone.utc),)router = AgentRouter(registry, use_case="ticket-routing", policy_id="ticket-routing")decision = router.route({"priority": "high"})print(decision.selected, decision.matched_rule_id, decision.policy_version)