Fibric. Docs fibric.io →
v0.9 ยท preview
Reference

Guardrails API

Guardrails are the trust policy the deterministic executor evaluates before any side effect runs. Rules can live in two places: embedded on an operator (the guardrails array in the Operators API) or as tenant-level policies managed here, which apply across every operator. This page documents policy CRUD, the rule schema, versioning, and the dry-run evaluator that answers "what would this policy do to this action?" without running anything.

Shared conventions are defined in the API overview. The conceptual model, fail-closed evaluation and the ALLOW/ALERT/BLOCK verdicts, is covered in Governance & trust and Trust tiers.

!
Default-closed, always

Evaluation composes tenant policies with the proposing operator's embedded guardrails: a side-effecting action must be allowed by at least one matching rule from either set, and any matching rule whose constraint fails blocks it. No matching rule at all means BLOCK. Deleting every policy does not open anything; it closes everything.

The guardrail policy object

idstring

Unique identifier, prefixed grd_.

objectstring

Always guardrail_policy.

namestring

Slug-style name, unique within the tenant, for example refund-ceiling. Immutable; the name is how receipts cite the policy.

descriptionstring or null

Free-text intent, for auditors and future maintainers.

statusstring

active or disabled. A disabled policy is skipped in evaluation. Because the model is default-closed, disabling an ALLOW policy narrows what can run; it never widens it.

versioninteger

Monotonic version number, starting at 1. Every change to rules increments it; prior versions remain readable. Receipts record the exact version that produced each verdict.

rulesobject[]

The rule documents, evaluated as a set. Schema below.

created_atstring

RFC 3339 timestamp of creation.

updated_atstring

RFC 3339 timestamp of the last version bump.

The rule document schema

Each rule matches a slice of proposed actions and contributes a decision. The fields mirror the kernel's TrustPolicy:

connectorstring, optional

Match only actions on this connector. Omitted means any connector.

toolstring, optional

Match only actions calling this tool, for example order.hold. Omitted means any tool.

max_valuenumber, optional

Ceiling compared against the action's value (a refund amount, an order total). A matching action whose value exceeds the ceiling is blocked, whatever the rule's decision says.

decisionrequiredstring

ALLOW or ALERT. ALERT means the action needs a human approval before it runs. BLOCK is not writable: blocking is what happens when nothing allows, or when a constraint fails.

Evaluation semantics, identical to the kernel's evaluate(): collect every rule whose connector and tool matchers fit the action, across active tenant policies and the operator's embedded guardrails. No matches: BLOCK. Any match whose max_value constraint fails: BLOCK. Otherwise, if any matching rule says ALERT: ALERT; else ALLOW. The most cautious matching rule always wins.

json · the guardrail policy object
{
  "id": "grd_3c90e1",
  "object": "guardrail_policy",
  "name": "refund-ceiling",
  "description": "Refunds auto-run to $250; larger refunds page a human.",
  "status": "active",
  "version": 3,
  "rules": [
    { "tool": "order.refund", "decision": "ALLOW", "max_value": 250 },
    { "tool": "order.refund", "decision": "ALERT" }
  ],
  "created_at": "2026-05-14T10:00:00Z",
  "updated_at": "2026-06-30T16:42:12Z"
}

Read the example carefully: a $180 refund matches both rules, the first allows it under its ceiling, the second says ALERT, and ALERT wins, so a human approves every refund. To auto-run small refunds, the second rule would need a min_value-style split, which v0.9 expresses by giving the ALERT rule to a different tool or by relying on the ceiling alone: one ALLOW rule with max_value: 250 blocks larger refunds outright rather than alerting. Test the composition you intend with the dry-run endpoint before activating it.

GET

List policies

GET/v1/guardrailsscope guardrails:read

Returns the tenant's guardrail policies, newest first, cursor-paginated with the standard limit and cursor parameters.

statusstring · query

Filter by active or disabled.

toolstring · query

Only policies with at least one rule matching this tool, including rules with no tool matcher.

curl
curl "https://api.fibric.io/v1/guardrails?status=active" \
  -H "Authorization: Bearer $FIBRIC_KEY"
POST

Create a policy

POST/v1/guardrailsscope guardrails:write

Creates a policy at version: 1. New policies take effect for the next evaluated plan; plans already disposed are never re-evaluated.

namerequiredstring · body

Slug-style name, unique within the tenant. Lowercase letters, digits, and hyphens; 3–40 characters.

rulesrequiredobject[] · body

One or more rule documents per the schema.

descriptionstring · body

Free-text intent. Defaults to null.

statusstring · body

active or disabled. Defaults to active.

curl
curl -X POST https://api.fibric.io/v1/guardrails \
  -H "Authorization: Bearer $FIBRIC_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: grd-create-refund-ceiling" \
  -d '{
    "name": "refund-ceiling",
    "description": "Refunds auto-run to $250; larger refunds are blocked by the ceiling.",
    "rules": [
      { "tool": "order.refund", "decision": "ALLOW", "max_value": 250 }
    ]
  }'

Error cases:

StatusCodeWhen
400missing_parametername or rules is absent, or rules is empty.
400invalid_parameterA rule's decision is not ALLOW or ALERT, or max_value is not a positive number.
409state_conflictA policy with this name already exists in the tenant.
GET

Retrieve a policy

GET/v1/guardrails/{guardrail_id}scope guardrails:read

Returns the current version of the policy. Pass version as a query parameter to read a historical version verbatim, which is how an auditor reconstructs the exact rules behind a verdict cited in a receipt.

guardrail_idrequiredstring · path

The policy id, for example grd_3c90e1.

versioninteger · query

A historical version number. Defaults to the current version.

curl · read version 2 as it was
curl "https://api.fibric.io/v1/guardrails/grd_3c90e1?version=2" \
  -H "Authorization: Bearer $FIBRIC_KEY"
PATCH

Update a policy

PATCH/v1/guardrails/{guardrail_id}scope guardrails:write

Updates rules, description, or status. A change to rules replaces the whole array and increments version; there is no per-rule patching. Versions are immutable once written: the history of what governed and when is part of the audit surface.

curl · raise the ceiling, minting version 4
curl -X PATCH https://api.fibric.io/v1/guardrails/grd_3c90e1 \
  -H "Authorization: Bearer $FIBRIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [
      { "tool": "order.refund", "decision": "ALLOW", "max_value": 400 }
    ]
  }'

Error cases:

StatusCodeWhen
400invalid_parameterA rule fails schema validation, or the body attempts to set version or name.
404not_foundNo policy with this id exists for the authenticated tenant.
DELETE

Delete a policy

DELETE/v1/guardrails/{guardrail_id}scope guardrails:write

Removes the policy from evaluation. Historical versions remain readable for audit; receipts citing the policy keep resolving. Because evaluation is default-closed, deletion can only narrow what runs. Prefer status: "disabled" when the removal may be temporary.

curl
curl -X DELETE https://api.fibric.io/v1/guardrails/grd_3c90e1 \
  -H "Authorization: Bearer $FIBRIC_KEY"
POST

Evaluate (dry run)

POST/v1/guardrails/evaluatescope guardrails:read

Runs the real evaluator against a hypothetical action and returns the verdict and the matched rules. Nothing executes, nothing is receipted; the endpoint is a read in POST clothing, which is why it needs only the read scope. Use it in CI to pin policy behavior before a change ships.

actionrequiredobject · body

A hypothetical action: connector, tool, optional value, optional args. The same fields a PlannedAction carries.

operator_idstring · body

Include this operator's embedded guardrails in the evaluation, exactly as a real plan from it would. Omit to evaluate tenant policies alone.

policiesobject[] · body

Hypothetical policy documents to evaluate instead of the tenant's stored policies. For testing an edit before saving it.

curl
curl -X POST https://api.fibric.io/v1/guardrails/evaluate \
  -H "Authorization: Bearer $FIBRIC_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "operator_id": "op_8f2a1c",
    "action": { "connector": "cn_7d2f4a", "tool": "order.refund", "value": 300 }
  }'
200 OK Response
json
{
  "object": "guardrail_evaluation",
  "decision": "BLOCK",
  "matched": [
    {
      "policy_id": "grd_3c90e1",
      "policy_version": 3,
      "rule": { "tool": "order.refund", "decision": "ALLOW", "max_value": 250 },
      "constraint_failed": "max_value"
    }
  ],
  "explanation": "value 300 exceeds max_value 250 on refund-ceiling v3; no other rule allows order.refund."
}

Error cases:

StatusCodeWhen
400missing_parameteraction is absent or lacks connector or tool.
400invalid_parameterA hypothetical policy in policies fails schema validation.
404not_foundoperator_id names no operator in the tenant.