Skip to main content
Governance is a policy layer on an agent that blocks or gates tool calls and scans incoming messages for prompt injection, enforced by the platform regardless of what the model decides. It exists because a persona is guidance, not a control: a model can be argued into calling a tool, so a tool that must never run from a conversation needs a rule the model cannot override.

How a policy is enforced

You declare a governance object on LuaAgent. It travels with lua push agent and applies to every conversation the agent has, on every channel.
src/index.ts
The object has two modes. In SDK mode (mode: 'sdk') the platform evaluates the rules itself, in memory, on every request. Three parts layer in order:
  • preset: 'security' seeds a baseline rule set that blocks tools the policy classifies as dangerous.
  • injection scans each incoming message before any preprocessor runs. threshold is the score, from 0 to 1, at which the pattern-based scan blocks. ml: true also sends the message to the Governance Cloud classifier and blocks when its confidence crosses mlThreshold (default 0.95); when the classifier is unavailable the pattern scan still applies.
  • rules are your explicit lists. blockTools names tools that never run. requireToolApproval names tools that pause until a human approves; the entries are runtime tool names, matched on each tool call. tokenBudget builds a rule, but the runtime never supplies the token count that rule reads, so it never fires.
In API mode (mode: 'api') the platform asks your governance server at serverUrl for each decision. The bearer token is read at runtime from the GOVERNANCE_API_KEY variable in the agent’s environment (lua env production -k GOVERNANCE_API_KEY -v <value>), so it is never stored in the agent configuration. If the key or the URL is missing, the platform logs a warning and proceeds without enforcement. Enforcement happens at three points: before your preprocessors see a message, on each tool call, and on the response before your postprocessors run. A blocked message ends the turn, and the end user receives the policy message 🛑 Blocked by governance policy — <reason> as the reply. A tool that requires approval pauses the turn, and the end user receives ⏸️ Awaiting human approval — <reason> followed by the approval ID. The request is tracked by the Governance Cloud service; the approver gets an Inbox item or replies APPROVE <code> on a channel, and the turn resumes when the decision arrives. Approval gating needs approvals enabled for the organization. When the policy engine itself fails to load or throws, the turn proceeds. Governance fails open: it is a control on the model, not on platform availability. Two cases fail closed instead: a tool listed in requireToolApproval is blocked when the approval capability is unavailable, and a tool call whose pre-approval check fails is gated rather than allowed. An organization can set a baseline. When governance is enabled on the organization, every agent created in it starts with SDK mode, the security preset, and injection scanning at threshold: 0.8, ml: true, mlThreshold: 0.95. An explicit governance value at creation, including null, overrides the baseline, and lua sync pulls a server-set policy into src/governance.ts so the next push round-trips it. lua governance add scaffolds the file: it asks for the mode, lists the tools in your compiled manifest to pick what to block and what to gate (run lua compile first), writes src/governance.ts, and prints the import to add to LuaAgent. lua governance remove deletes the file and clears the policy on the server. Either way the policy reaches production with lua push agent followed by an agent version promote, like any other agent change.

Governance and processors

A preprocessor is your code and can also block a message, so the two overlap on inputs. They differ in three ways. Governance runs first, before any preprocessor. Governance is declarative policy and can be set by the organization; a preprocessor is a versioned primitive you write and deploy. And only governance sees tool calls: a preprocessor has finished by the time the model decides to call a tool. Governance also differs from a workflow approval step. requireToolApproval gates one tool call inside a conversation; .approval() is a durable step in a run, with approver routing, timeouts, and an editable payload.

When to use it

  • A tool must never run from a conversation, whatever the end user says: list it in blockTools.
  • A tool has consequences (refunds, deletions, payments) and a person should confirm each call: list it in requireToolApproval.
  • You need a named control against prompt injection for a security review: set injection.
  • Your organization runs a central policy service: use API mode with serverUrl.
  • Don’t use governance to rewrite or enrich messages; that is a preprocessor. Don’t use it to hide a tool under a business condition; that is the tool’s condition. Don’t use it for approvals inside workflows; use a workflow approval step.

Limits

Next steps

LuaAgent reference

The governance field and every other agent option.

lua governance

Scaffold, pull, and remove a policy from the CLI.

About security and data

Credentials, secrets, change control, and what is retained.

Approvals and signals

Human approval inside a durable run.