Skip to Content
Zeotap AgentGuardrails

Guardrails

Guardrails are the rules that decide what the AI agent is allowed to do in your workspace on its own, what it has to ask a human about first, and what it may never do at all.

You configure them on the AI Policies page under Governance in the sidebar.

How Guardrails Work

A tool call is matched against enabled policy rules, which allow it, hold it for approval, or deny it — and every decision is recorded in the AI audit log

A policy is a named, switchable set of rules. Each rule has three parts:

PartWhat it does
TypeWhat the rule looks at — the tool being called, how often it is being called, the columns in a filter, or the destination being written to
ConditionThe specific values that make the rule match, such as which tools or which destination types
ActionWhat happens when it matches — Deny, Require Approval, or Warn

When the agent calls a tool, every enabled policy is checked, and every rule inside it, in order. The first rule that stops the call decides the outcome — whether it denies the call or holds it for approval, checking stops there and the remaining rules are not consulted. If no rule stops it, the call goes ahead.

What Guardrails Cover

Guardrails apply to tools that change something or start something — creating an audience, updating a model, triggering a sync, deleting an orchestration. Tools that only read data are never gated, so the agent can always look at your workspace and answer questions about it.

The rules apply to AI-initiated actions from any client: the agent chat inside Zeotap, and any external MCP client connected with an API key. They do not apply to changes you make yourself in the UI or through the REST API — those are governed by RBAC and recorded in the workspace audit log.

Guardrails constrain the agent, not your team. A person who can delete an audience in the UI can still do so while a policy stops the agent from doing it for them.

Actions

ActionEffect
DenyThe call is refused. The agent is told which rule stopped it and reports back rather than retrying.
Require ApprovalThe call is held, not run. A reviewer approves or rejects it — see Approval Workflow.
WarnThe call goes ahead and evaluation continues to the next rule — nothing is blocked and nobody is asked — but the match is recorded on the audit entry, which shows a warning count against the outcome and the reason for each one when you expand the row. Use it to watch a rule in the log before you let it bite.

Rule Types

Tool Guard

Matches on the name of the tool being called. This is the most direct rule type and the one the default policies use.

SettingDescription
Guarded ToolsOne or more tool names. Pick from the grouped list or type your own.

Names match exactly (trigger_sync), or you can end a pattern with * to match a family of tools (delete_* matches delete_journey, delete_identity_graph, and so on). Matching ignores case.

Example: hold every deletion for approval with the single pattern delete_*.

A Tool Guard rule can also be narrowed to the calls that set a particular argument, with when_args_set in its condition. The rule then matches only when the call gives at least one of the named arguments a value; an argument that is missing, null, or an empty string, list or object counts as not set. The default Irreversible Action Protection policy uses it to hold create_audience_sync only when the sync is created with a schedule. The editor has no control for this setting. It shows a note under any rule that carries it, and you set it through the API.

Rate Limit

Limits how many times a tool can be called within a rolling time window.

SettingDescription
Max CallsHow many calls are permitted inside the window
Window (seconds)The length of the window
ToolsWhich tools to count. Leave empty to apply to every tool the guardrails see.

The count is kept per tool, so a limit of 5 per hour on two tools allows 5 calls of each, not 5 between them. The rule matches once a call would take the tool past the limit.

Tool names in a Rate Limit rule are matched exactly — delete_* and other wildcards work only in Tool Guard. List the tools individually here.

Example: at most 5 trigger_audience_sync calls per hour.

Banned Filter

Matches when an audience filter references a column or an operator you have put off limits. The whole filter tree is inspected, including conditions nested inside event and relation conditions, so a banned column cannot be hidden a few levels down.

SettingDescription
Banned ColumnsColumns the agent may not filter on. Pick from your models’ columns or type a name.
Banned OperatorsOperators the agent may not use, such as contains on a sensitive field

Column and operator names are matched ignoring case.

Example: deny any agent-built filter that references ssn or date_of_birth.

Destination Guard

Matches on the destination type a call is writing to.

SettingDescription
Guarded TypesOne or more destination types, chosen from the destinations Zeotap supports

Types are matched ignoring case, and the rule only applies to calls that name a destination type.

Example: require approval before the agent creates anything pointed at your ad platforms.

Default Policies

Every new workspace starts with four policies, all enabled:

PolicyRuleAction
Delete ProtectionTool Guard on delete_*Require Approval
Sync ProtectionTool Guard on trigger_sync and trigger_audience_syncRequire Approval
Send ProtectionTool Guard on send_* and schedule_*Require Approval
Irreversible Action ProtectionTool Guard on write_warehouse, activate_journey, trigger_journey, resume_journey, publish_audience_canvas, apply_data_prep_blueprint and archive_store, plus create_audience_sync when the call sets a scheduleRequire Approval

Irreversible Action Protection holds the actions that cannot be taken back once they run: a write into your warehouse, a journey that starts reaching people, a canvas going live, a blueprint creating tables, a store being archived, and a sync that will run on its own schedule. A sync created without a schedule runs only when someone triggers it, and that trigger is already held by Sync Protection.

The AI Policies page listing default policies, enabled

They are ordinary policies: edit them, switch them off, or delete them. Workspaces that existed before Send Protection and Irreversible Action Protection were introduced were given both, unless the workspace already had a policy with the same name, which was left as it was. Delete Protection and Sync Protection were never added back: a workspace without them had deleted them. Apart from that one-time addition, a default you delete does not come back.

A workspace with no enabled policies places no limits on the agent beyond the scopes on its API key. Deleting the defaults leaves deletions, sync triggers, sends and irreversible actions unguarded.

When a Policy Cannot Be Read

Guardrails fail closed. If a rule cannot be evaluated, it counts as matching and takes its own action: a Deny rule refuses the call, a Require Approval rule holds it, and a Warn rule still only warns. If a policy’s rules cannot be read at all, or Zeotap cannot load your workspace’s policies, the agent’s changes are refused until they can be. The refusal names the policy, so the agent can tell you which one to fix.

Policies are checked when you save them, so this should only happen to a policy that was stored before the check existed. A rule with an unknown type, an unknown action, a missing condition, or a condition that does not fit its type is rejected with a message naming the rule and the problem, and nothing is saved.

Creating a Policy

  1. Navigate to AI Policies under Governance in the sidebar
  2. On the Policies tab, click Create Policy
  3. Give the policy a Name — it has to be unique within the workspace
  4. Click Add Rule, then choose a Type and an Action
  5. Fill in the rule’s settings — the fields change with the type you picked
  6. Add further rules if you want them evaluated in the same policy, in the order you add them
  7. Click Create

The policy takes effect immediately, on the agent’s next tool call. Use the Enabled switch in the policies table to turn a policy off without deleting it, or Edit to change its rules.

Approval Workflow

When a call matches a Require Approval rule:

  1. The call is held — nothing is created, changed, or triggered yet. The agent is told the request is pending and carries on with the rest of the conversation. A call that names something outside your workspace — another workspace’s journey, audience or source — is never held: it is refused before any policy is checked, the way it would be refused if it ran, so it never reaches your approvers.
  2. The request appears on the Pending Approvals tab of the AI Policies page, and the count shows against AI Policies in the sidebar. Workspace Owners and Admins are also emailed.
  3. A reviewer clicks Review and sees which tool was called and the arguments it was called with, and can add a note explaining the decision. Personal data and anything that looks like a credential are masked in the arguments shown; everyone who can see the queue sees the same masked copy. The call itself is kept, encrypted, and runs with its original values if approved.
  4. Clicking Approve runs the held call. Clicking Reject discards it — the action never runs. Approving says yes; it does not mean the action succeeded. The request moves to the Recent Decisions tab, which shows what the action did: Running while it runs, then Done, or Failed with the reason. Zeotap Agent reads the same outcome, and tells you the action was done only once it is. The person whose agent made the call cannot approve it: another Owner or Admin has to. They can still Reject their own request, to withdraw it. A workspace with a single administrator therefore needs a second one before held calls can run.
  5. Requests that nobody reviews expire after 24 hours. They drop off the Pending Approvals tab and can no longer be approved — if the action is still wanted, ask the agent for it again.
  6. Before an approved call runs, it is checked again. If a policy added since the call was held now denies it, or the key the agent used has been revoked (for example because its user was removed from the workspace), the approval is refused and the request stays pending so it can be rejected.

Answered and expired requests are deleted after 90 days.

Ask the agent whether a request has been resolved and it will check for you; a rejected request comes back with the reviewer’s note, so telling it why you rejected something is worth the extra sentence.

Audit Log

Every guardrail decision is recorded, whichever way it went. Go to Governance → Audit Logs and open the AI Audit Logs tab.

ColumnWhat it holds
TimestampWhen the call was made
AgentWhich agent or session made it
ToolThe tool that was called
OutcomeAllowed, Denied, Pending approval, Approved, or Rejected
InputExpand to see the full arguments the tool was called with

Pending approval is written when a rule holds a call; a second entry with Approved is written if a reviewer later lets it run. Because guardrails only evaluate tools that change something, most read-only tool calls do not appear here. The exceptions are queries Zeotap Agent runs against your warehouse, which are recorded with a fingerprint of the query, the columns returned and the row count, never the query text or the rows.

Zeotap Agent also checks every change against the plan you approved before it sends the call. A change that check stops is recorded as Denied. Over the API (GET /api/v1/workspaces/{id}/ai-audit-log), the entry’s evaluation_result has source set to write_gate and a code saying why: for example no_plan (no plan had been approved), not_in_plan (the step was not in the approved plan), or args_mismatch (its arguments differ from what the plan showed you). A run of these in one conversation is worth a look: it can mean the agent is being steered towards changes you did not ask for.

When the model’s own safety checks stop a response, that is recorded too, as a Denied entry with the tool model_response. Its evaluation_result has source set to model_refusal and a code for how the turn went: retried (one response was stopped and the agent tried once more), ended (the turn ended on the refusal, and you were told so in the chat), or fallback. A category is included when the model provider gives one. The request itself is never stored in the entry.

If the stopped response had already shown some text, that text is removed from the chat and from the saved conversation. The entry then lists what was removed in retracted: for each removed message, its position (seq), its kind (text or tool_call), and for text a SHA-256 hash (sha256) and size in bytes (bytes) of exactly what was shown. Up to 20 are listed; retracted_frames gives the total. The removed text itself is not stored. To check whether a copy you have matches, hash it with SHA-256. A refusal is often a false positive on an ordinary request. Several in one conversation can mean something in your data is trying to give the agent instructions.

This log covers what the agent was asked to do. For configuration changes made by people, through the UI or the REST API, see the workspace audit log on the neighbouring tab.

Permissions

PermissionAllowsOwnerAdminMember
policies.readViewing policiesYesYesYes
policies.writeCreating, editing, and deleting policiesYesYes—
approvals.readViewing approval requestsYesYesYes
approvals.writeApproving and rejecting requestsYesYes—
audit_log.readViewing the AI audit logYesYesYes

Members can see what the guardrails are and what the agent has been doing, but cannot change the rules or resolve an approval. See RBAC for assigning these to custom roles.

API Reference

# Policies GET /api/v1/workspaces/{id}/policies POST /api/v1/workspaces/{id}/policies PUT /api/v1/workspaces/{id}/policies/{policyId} DELETE /api/v1/workspaces/{id}/policies/{policyId} # Approvals GET /api/v1/workspaces/{id}/approvals GET /api/v1/workspaces/{id}/approvals?status=reviewed&limit=50 POST /api/v1/workspaces/{id}/approvals/{approvalId}/review # AI audit log GET /api/v1/workspaces/{id}/ai-audit-log?limit=50&offset=0

A policy is created with a name and a rules array, where each rule carries a type, an action, and a condition shaped to the type:

{ "name": "Production Safety", "rules": [ { "type": "tool_guard", "action": "require_approval", "condition": { "tools": ["delete_*", "trigger_sync"] } }, { "type": "rate_limit", "action": "deny", "condition": { "max_calls": 5, "window_seconds": 3600, "tools": ["trigger_audience_sync"] } } ] }

The remaining condition shapes are banned_filter (banned_columns, banned_operators) and destination_guard (guarded_types).

A tool_guard condition may also carry when_args_set, a list of argument names, to match only the calls that set one of them — for example {"tools": ["create_audience_sync"], "when_args_set": ["schedule"]}.

A create or update whose rules fail the save-time check is answered 400 with an error naming the rule and the problem, for example a type that is not one of rate_limit, banned_filter, destination_guard or tool_guard.

To review a request, post {"status": "approved"} or {"status": "rejected"}, optionally with a note.

Listing approvals returns the requests waiting for a decision. With status=reviewed it returns the most recent approved and rejected requests instead, newest decision first; limit sets how many (default 50, at most 200). Any other status is answered 400. An approved request carries what its action did:

FieldDescription
execution_statusrunning while the approved action runs, then succeeded or failed
execution_errorWhy it failed, when execution_status is failed
executed_atWhen it finished

The fields are absent on rejected requests, and on requests approved before outcomes were recorded.

Reviewing is a person’s decision, so it needs a signed-in session. A REST API key is refused with 403 and "code": "api_key_not_allowed", even one holding approvals.write; the same key can still list requests. You can approve your own agent’s request; the audit log records it as a self-approval. A request that does not record who made it is refused with 403 and "code": "approval_requester_unknown".

Next Steps

  • AI Agent — what the agent can do inside those boundaries
  • MCP Server — the tools guardrails are evaluated against, and the scopes that gate them
  • Audit Log — the companion record of changes made by people
Last updated on