AI Development

AI Agent Guardrails: How to Add Approvals and Budgets

Give your agent useful tools without giving it unlimited authority. A practical Lovable blueprint for approvals, audit logs, and spending limits.

Lovable AI Review Editorial Desk
Lovable AI Review Editorial Desk
Editorial
October 27, 2026 10 min read
AI Agent Guardrails: How to Add Approvals and Budgets
TL;DR

AI agent guardrails belong in your backend, not just your system prompt. Start with narrow tools, approvals tied to exact actions, append-only audit events, and atomic budget reservations before each model or tool call.

AI agent guardrails are backend controls that restrict what an agent can access, execute, and spend, even when its model produces unsafe instructions. For a Lovable app, start with narrow tool permissions, action-specific approvals, audit logs, and enforced spending limits. This guide turns those controls into a concrete support-agent architecture, with a copy-paste build prompt and launch tests.

What AI agent guardrails should control

A model proposes an action. Your application decides whether that action is allowed. Keep that boundary intact.

For an app shipping in October 2026, the useful question is not whether its model supports tool calling. It is whether a bad tool call can cross a customer boundary, move money, or run up a bill.

Consider a support agent that reads tickets, drafts replies, and proposes refunds. Reading an authorized ticket is low risk. Sending a reply has external consequences. Issuing a refund moves money. Those actions should not share one permission policy.

| Action | Default policy | Backend enforcement | | --- | --- | --- | | Read a ticket | Allow within tenant scope | Check authenticated membership and ticket ownership | | Draft a reply | Allow without sending | Store a draft, with no email credentials exposed | | Send a reply | Require approval initially | Approve exact recipient, body, and attachments | | Issue a refund | Require authorized approval | Validate original payment, amount, currency, and remaining refundable balance | | Delete records | Deny in the first release | Do not expose a deletion tool |

These are product policies, not universal thresholds. A medical workflow needs different rules from an internal meeting summarizer.

Use five distinct controls:

  1. Identity: Which user and tenant started this run?
  2. Scope: Which records and tools can it reach?
  3. Authority: Which actions require another person's approval?
  4. Budget: How many calls and dollars may it consume?
  5. Evidence: What happened, and can you reconstruct it?

Output validators and injection detectors can help. They do not replace these controls. A perfectly formatted refund request can still target somebody else's payment.

If you are still choosing a workflow, browse our AI agent guides. Start with one tool that creates value, not a general-purpose agent with unrestricted HTTP access.

Build an approval flow in Lovable

Use Lovable for the operator interface and application scaffolding. Put authorization, approval validation, and tool execution in server-side functions or a worker. A Supabase-backed implementation is one option; the same design works with another transactional database.

Allow roughly 6-12 engineering hours for a narrow prototype with one read tool and one approval-gated write tool. That is a planning estimate, not a promise that generated code is production-ready. Payment integration and security review need separate time.

1. Create the minimum data model

Create these tables:

  • `agent_runs`: tenant, initiating user, status, policy version, limits, and cost counters.
  • `agent_actions`: run, typed tool name, canonical arguments, argument hash, expiry, and execution state.
  • `agent_approvals`: action, approver, approved argument hash, decision, and expiry.
  • `agent_events`: run, action, timestamp, event type, actor, and redacted metadata.
  • `agent_usage`: reservation, provider request identifier, estimated cost, actual cost, and reconciliation state.

Put `tenant_id` on each relevant record. Enable row-level security for browser-accessible tables. The backend must still check tenant membership when using elevated credentials; those credentials can bypass row-level policies.

The browser may request a run or submit an approval decision. It must not directly edit execution state, budgets, or audit records.

2. Expose narrow tools

Prefer `get_ticket(ticket_id)` and `propose_refund(payment_id, amount_minor, currency, reason)` over `fetch_url(url)` or `execute_sql(query)`.

Validate arguments against a strict schema, reject unknown fields, and load the target resource inside the authenticated tenant. Obtain tenant identity from the authenticated request, never from model-generated arguments.

For the prototype, cap proposed refunds at 5,000 minor units for USD, meaning $50. Do not assume every currency has two decimal places. A proposal above your configured cap should be rejected or routed to a separate manual workflow.

The agent should never receive payment-provider secrets. It should not be able to invent a new recipient for a refund either; the payment service determines where a refund goes.

3. Approve the exact action, not the conversation

An approval reading "Let the agent continue" is too broad.

Show the operator the customer, original payment, amount, currency, reason, and relevant ticket. Store approval against a hash of the canonical action payload, including the tool name, tenant, resource identifiers, and arguments.

For the first version, make proposals immutable. Editing an amount creates a new proposal and requires a fresh approval. Give approvals a 15-minute expiry as an initial product setting, then tune it to the workflow.

On execution, verify:

  • The approver has the required role in this tenant.
  • The approval is unexpired and matches the stored action hash.
  • The action is still pending and has not been consumed.
  • The current payment remains eligible for the proposed refund.
  • The run is not canceled and has enough budget.

Check authorization again at execution time. Someone can lose their finance role after approving an action.

4. Claim execution once

Use an atomic database transition to claim the approved action. Two workers must not both change it from `approved` to `executing` successfully.

Then call the provider with a stable idempotency key derived from the action ID, where the provider supports it. A retry must reuse that key.

The database and an external API do not share one transaction. If a payment request times out, its outcome is unknown, not necessarily failed. Query the provider or reconcile using its documented idempotency behavior before resubmitting. Never generate a fresh payment operation merely because the first response was lost.

The approval page should expose this uncertainty. "Checking provider outcome" is more honest than a green success badge or a misleading failure message.

Add budgets and audit logs

Budget controls need to stop the next call, not merely report yesterday's spending.

For the support-agent prototype, use these initial settings:

| Limit | Starting value | Purpose | | --- | --- | --- | | Model calls per run | 8 | Stop repetitive reasoning loops | | Tool calls per run | 12 | Bound external activity | | Active execution time | 120 seconds | Stop scheduling work after the deadline | | Model and tool budget | $0.25 per run | Bound estimated operating cost | | Tenant daily budget | $10 | Limit exposure from repeated runs | | Retry allowance | 2 retries per operation | Prevent unbounded recovery loops |

Human approval waiting time should not occupy a running worker. Persist the proposal, suspend the run, and resume through a new job after approval. Define separately how long a suspended run may remain valid.

A timeout also does not undo an external action already submitted. Cancel future work, then reconcile in-flight requests.

Reserve spending before dispatch

Suppose a call could cost at most $0.04 under its configured input and output limits. Reserve that amount before submitting it. After completion, settle actual usage and release any unused reservation.

The admission rule is:

```text settled_cost + active_reservations + next_reservation <= budget ```

Check and reserve atomically for both the run and the tenant's daily allowance. A read-then-write implementation can overspend when concurrent workers see the same remaining balance.

Use integer microdollars or a fixed-precision database type for accounting. Count retries, and include separately billed tools where applicable. Do not release a reservation just because a request timed out; first determine whether the provider processed it.

Reservation estimates only enforce a reliable ceiling if you can bound every charge. If a tool has unpredictable metered fees, constrain its usage, increase the reservation conservatively, or keep it out of the automatic path. Provider-side spending controls are useful backstops where available.

Here is illustrative arithmetic, not a current provider quote. At assumed rates of $1 per million input tokens and $5 per million output tokens, a call with 6,000 input tokens and 1,000 output tokens costs $0.011. Eight identical calls cost $0.088 before tools and infrastructure. Later calls often carry more context, so calculate reservations from each actual request rather than multiplying the first call's cost.

Lovable build credits are separate from your application's runtime AI spending. Use our Lovable pricing guide when budgeting the builder subscription, then price your chosen runtime services independently.

Log decisions without leaking customer data

Record the run and action IDs, tool name, policy version, authorization decision, approval reference, latency, retry count, cost, and provider request ID.

Do not dump access tokens, full payment details, or entire private tickets into a generic event stream. Store redacted summaries and references. If sensitive payload retention is necessary, give it separate access controls and a deletion policy.

Make events append-only for application roles. This improves traceability but does not make them tamper-proof against database administrators. Stronger compliance requirements may need separate immutable storage.

Log denials and reconciliation events as carefully as successes. Otherwise, your dashboard hides the exact cases you need to investigate.

Copy-paste prompt and launch checklist

Paste this into Lovable after connecting your backend. Ask it to explain the migration and server-side authorization design before applying changes. Our prompt library has more patterns for keeping generated changes narrow.

```text Build a guarded support-agent prototype with a Supabase backend.

Scope:

  • Read tenant-authorized tickets.
  • Draft replies without sending.
  • Propose USD refunds up to 5000 cents.
  • Use a mock payment adapter first. No live refunds.

Create agent_runs, agent_actions, agent_approvals, agent_events, and agent_usage tables with tenant isolation. Use integer microdollars for cost accounting.

Security:

  • Derive user and tenant authorization server-side.
  • Never expose provider or service-role secrets in browser code.
  • Reject unknown tool names and invalid argument fields.
  • Browser clients cannot modify execution state or cost counters.
  • Elevated backend credentials require explicit tenant checks.

Approvals:

  • Show the exact payment, amount, currency, and reason.
  • Store immutable proposals and hash canonical action payloads.
  • Require a finance-role approval with a 15-minute expiry.
  • Recheck role, hash, expiry, payment eligibility, and run state.
  • Atomically claim actions before execution.
  • Reuse one provider idempotency key per action.
  • Reconcile unknown provider outcomes before retrying.

Budgets:

  • Maximum 8 model calls and 12 tool calls per run.
  • $0.25 run budget and $10 tenant daily budget.
  • Atomically reserve bounded costs before dispatch.
  • Settle actual usage and retain unresolved reservations.
  • Suspend workers while awaiting approval.

UI:

  • Run list, approval inbox, action details, redacted event timeline.
  • Cancel control that blocks future dispatches.
  • Clearly label mock actions and unknown provider outcomes.

Add automated tests for cross-tenant access, expired approvals, changed payloads, concurrent execution, budget races, and timeouts. Explain deployment requirements and any unimplemented controls. ```

Before enabling a live write tool, verify:

  • [ ] A tenant A user cannot read or approve tenant B's action.
  • [ ] A malicious ticket cannot trigger an unlisted tool.
  • [ ] Changed arguments invalidate approval.
  • [ ] An expired or revoked approver cannot authorize execution.
  • [ ] Concurrent workers produce one external operation.
  • [ ] Concurrent reservations cannot exceed the configured allowance.
  • [ ] A timeout enters reconciliation instead of blindly retrying.
  • [ ] Canceling a run prevents new dispatches.
  • [ ] Logs contain no credentials or unnecessary sensitive payloads.

Ship in three stages: mocked actions, live reads with proposed writes, then one live write tool for internal operators. Expand only after reviewing actual denials, costs, and uncertain outcomes.

Can a system prompt stop prompt injection?

No. A system prompt can guide behavior, but untrusted tickets, documents, and web pages may still influence the model. Treat model-generated tool calls as untrusted requests. Backend permissions, strict schemas, scoped access, and approvals limit the damage when instructions fail.

Does every agent action need human approval?

No. Authorized reads and reversible drafts can usually run automatically. Start with approval for money movement, external messages, destructive actions, and permission changes. Any automatic exception should be narrow, measurable, and enforced outside the model.

How much do AI agent guardrails cost?

For planning, allow 6-12 engineering hours for the narrow mocked prototype described here, with additional time for live integrations and security review. A small development deployment might need $25-$75 monthly for backend and worker services, excluding Lovable, model usage, and paid tools. Check current provider plans; the largest early cost is usually implementation and testing, not the approval screen.

The Briefing

The best of Lovable, once a week.

Deep reviews, founder case studies, and growth tactics. No filler.

No spam. One-click unsubscribe.

Build something with us

Start Building with Lovable

Open Lovable, write your first prompt, and ship the thing you have been thinking about for too long.

Start Building with Lovable