Approval Workflows for AI Agents

As AI agents gain the ability to take real-world actions — sending emails, modifying databases, calling external APIs, spending money — organizations need a way to keep humans in the loop for high-stakes decisions. Govyn's approval workflow system intercepts agent requests that match configurable rules and holds them for human review before they reach the LLM provider or downstream service.

This is not observability. Observability tells you what happened after the fact. Approval workflows prevent things from happening until a human says they should. The agent's request is physically held at the proxy layer. It does not reach the provider, does not trigger side effects, and does not cost money until an approver makes a decision.

The system is fully asynchronous. The agent sends a request, receives a polling URL, and waits. The approver reviews the request in the dashboard or through a webhook notification and approves or denies it. The proxy then forwards the approved request or returns a denial to the agent. The agent does not need to know about the approval system — it handles the async response like any other retry or wait pattern.


Why AI agents need approval gates

AI agents are increasingly autonomous. They compose emails, write code, query databases, call APIs, and make purchasing decisions. Most of the time, their actions are correct and beneficial. But the failure modes are severe: a misaddressed email, an incorrect database migration, a spend that exceeds the budget by an order of magnitude, or a data access that violates compliance requirements.

The challenge is that these high-risk actions are often indistinguishable from routine actions at the code level. An agent calling a "send email" function is the same code path whether the email goes to a colleague or to every customer in the database. A database write that updates one row uses the same API as one that drops a table. Without a governance layer that understands the difference, you are relying on the agent's judgment to know when to stop — and that judgment is only as good as the prompt and the model.

Approval gates address this by defining explicit boundaries. You specify which actions require human sign-off, and the proxy enforces those boundaries at the network layer. The agent cannot bypass the gate because it never has direct access to the downstream service. Every request must pass through the proxy, and the proxy will not forward requests that match an approval rule until a human approves them.

This architecture is particularly important for regulated industries — finance, healthcare, legal, government — where autonomous AI actions may need documented human oversight. Approval workflows provide the paper trail: who approved what, when, and why. This is not a feature you add later; it is a requirement you build in from the start.


How the approval system works

The approval system is built into the Govyn proxy. When a request arrives, the proxy evaluates it against all active policies in priority order. If a policy with approval_required: true matches the request, the proxy initiates the approval flow instead of forwarding the request to the provider.

The proxy generates a unique approval token with the gva_ prefix — 32 random bytes encoded as base64url. This token identifies the specific request in the approval queue and serves as the authentication mechanism for status polling. The proxy creates an approval item in the database with the full request details, the matching policy, the agent identity, and the timestamp.

The proxy returns a structured JSON response to the agent containing the approval token and a polling URL. The response follows the standard Govyn error contract with type, message, policy, and agent fields, plus a poll_url field specific to approval responses. The agent (or its framework) polls this URL to check whether the request has been approved, denied, or is still pending.

The polling endpoint at GET /api/v1/approvals/:token/status is publicly accessible — it does not require organization-level authentication because the token itself is the credential. This design allows the proxy to poll without needing Clerk JWT tokens, which simplifies the async flow. The token is unguessable (256 bits of entropy), making brute-force access infeasible.

When an approver makes a decision, the approval item's status is updated in the database. The next time the agent polls, it receives the decision. If approved, the proxy forwards the original request to the provider and returns the response to the agent. If denied, the proxy returns a denial response with the approver's optional note.


Common approval scenarios

Approval rules are most valuable when applied to actions with real-world consequences that are difficult or impossible to undo. Here are the scenarios where teams most commonly deploy approval gates:

The common thread is irreversibility. Approval gates are most valuable for actions where the cost of an error is high and the ability to undo the action is limited or nonexistent.


Configuring approval rules

Approval rules are defined as policies in YAML or through the dashboard policy editor. A policy with approval_required: true will intercept matching requests and route them to the approval queue. Here are examples of common configurations:

Require approval for all requests from a specific agent:

policies:
  - name: approve-deployment-agent
    type: approval
    priority: 10
    approval_required: true
    conditions:
      agent: deployment-bot
    message: "Deployment agent requests require human approval"

Require approval for requests exceeding a token threshold:

policies:
  - name: approve-large-requests
    type: approval
    priority: 20
    approval_required: true
    conditions:
      max_tokens_threshold: 50000
    message: "Requests over 50k tokens require approval"

Require approval for requests to premium models:

policies:
  - name: approve-premium-models
    type: approval
    priority: 15
    approval_required: true
    conditions:
      models:
        - gpt-4
        - gpt-4-turbo
        - claude-3-opus
    message: "Premium model usage requires approval"

Require approval for requests matching content patterns:

policies:
  - name: approve-email-sends
    type: approval
    priority: 5
    approval_required: true
    conditions:
      content_patterns:
        - "send.*email"
        - "send.*message"
        - "post.*slack"
    message: "External communication requires approval"

Policies are evaluated in ascending priority order — lower numbers are evaluated first. When multiple policies match a request, the first matching policy with approval_required: true takes effect. This lets you create broad approval rules with specific exceptions by adjusting priority levels.


The approval lifecycle

Every approval request follows the same lifecycle from interception to resolution. Understanding each step helps you design effective approval policies and troubleshoot issues.

  1. Request interception — the agent sends an LLM request to the Govyn proxy. The proxy evaluates the request against all active policies in priority order. A policy with approval_required: true matches the request.
  2. Queue creation — the proxy generates a gva_ approval token, stores the full request payload and metadata in the approval queue, and records which policy triggered the approval requirement.
  3. Response to agent — the proxy returns a structured JSON response to the agent with the approval token and a polling URL. The HTTP status code indicates that the request is pending, not failed.
  4. Notification dispatch — if webhook alert rules are configured for approval events, the proxy sends POST requests to the configured webhook URLs with the pending approval details. This is how approvers learn that something needs their attention.
  5. Agent polling — the agent (or its framework) polls the status endpoint at GET /api/v1/approvals/:token/status. The endpoint returns the current status: pending, approved, or denied. Polling is lightweight — the endpoint reads a single row by primary key.
  6. Human review — an approver opens the approval queue in the dashboard, reviews the request details including the agent name, the request payload, the matching policy, and the timestamp. The approver decides whether the request should proceed.
  7. Decision with note — the approver clicks Approve or Deny and optionally adds a note explaining their reasoning. The note is stored with the decision as part of the permanent audit trail.
  8. Resolution — the approval item's status is updated in the database. On the next poll, the agent receives the decision. If approved, the proxy forwards the original request to the LLM provider and returns the response to the agent. If denied, the proxy returns a denial response.

The entire lifecycle is recorded in the database. Every state transition is timestamped. The full request payload, the decision, the approver identity, and the note are all stored and queryable through the API and the dashboard history tab.


Approval notifications

The approval system integrates with Govyn's alert and notification infrastructure. When a new item enters the approval queue, the system checks for alert rules configured for approval events and dispatches webhook notifications to the configured endpoints.

Webhook notifications contain the full approval item details: the agent name, the request summary, the policy that triggered the approval, the approval token, and a direct link to the dashboard approval queue. This gives approvers enough context to make a decision without needing to open the dashboard first.

Common notification destinations include:

Webhook URLs are validated against SSRF protections. Private IP ranges (RFC 1918), localhost addresses, and cloud metadata endpoints are blocked to prevent server-side request forgery attacks through the notification system. The notification history in the dashboard shows delivery status for every webhook dispatch, including success/failure indicators and response codes.


Dashboard approval queue

The approval queue in the Govyn Cloud Dashboard is the primary interface for managing approval requests. It has two tabs: Pending and History.

The Pending tab shows all approval items awaiting a decision. Each item displays the agent name, a summary of the request, the policy that triggered the approval requirement, and the time elapsed since the request was queued. The tab polls every 5 seconds for new items, so approvers see requests within seconds of them being queued. Items are ordered by creation time, with the oldest pending items at the top.

Clicking a pending item opens a detail drawer with the full request payload. The approver can review the exact content of the agent's request — the model, the messages, the parameters — and understand what the agent is trying to do. Two action buttons at the bottom of the drawer — Approve and Deny — each accept an optional note. The note field is a free-text input where the approver explains their reasoning. Notes like "Verified recipient list is correct" or "Denied: budget for this project is exhausted" become part of the permanent record.

The History tab shows every past approval decision. Each entry includes the original request, the decision (approved, denied, or timed out), the approver's identity, any notes, and the exact timestamps for when the request was queued and when the decision was made. History is paginated with cursor-based pagination and can be filtered by status. This tab serves as the compliance log — it answers the questions auditors ask: who authorized this action, when, and why.

The approval queue is organization-scoped. Approvers can only see and act on items from their own organization. Cross-organization access is prevented at both the API and database layers. The approve and deny endpoints verify that the approval item belongs to the authenticated user's organization before processing the action.


Audit trail

Every approval decision creates a permanent, immutable audit record. The audit trail captures:

Audit data is stored in PostgreSQL via Prisma and is subject to your plan's log retention limits: 7 days on Starter, 30 days on Team, and 90 days on Enterprise. Full request and response payloads are stored in Cloudflare R2 object storage with the R2 key referenced in the database record. This separation keeps the database lean while preserving complete payloads for replay and investigation.

The audit trail is queryable through the API at GET /api/v1/approvals/history?limit=&cursor=. Organizations that need longer retention or integration with external compliance systems can export this data through the API before it ages out of the retention window.


Timeout and auto-deny

Not every approval request will receive a timely human response. Approvers may be unavailable, notifications may be missed, or the approval may arrive outside business hours. The timeout system ensures that unanswered requests do not hang indefinitely.

When an approval request is not acted on within the configured timeout period, the system automatically denies it. The approval item's status is updated to "timed out" (a variant of denial), and the next time the agent polls the status endpoint, it receives a denial response indicating that the request was not approved within the allowed window.

The timeout behavior is important for agent reliability. Without timeouts, an agent waiting for approval could block its entire execution pipeline indefinitely. With timeouts, agents can handle the denial gracefully — falling back to a safer action, retrying with a smaller request, or notifying a human through a different channel.

Timed-out items appear in the approval history with a distinct status. This lets you identify patterns — if a particular type of request is consistently timing out, you may need to adjust your notification routing, extend the timeout window, or reconsider whether approval is necessary for that action type.

For organizations that need 24/7 approval coverage, combining webhook notifications with an on-call rotation ensures that approval requests always reach a human within the timeout window. The PagerDuty integration is designed for this use case — it creates an incident for each pending approval and escalates through your on-call schedule.


Frequently asked questions

What are approval workflows in Govyn?
Approval workflows are human-in-the-loop governance gates that intercept AI agent requests requiring human sign-off before they reach the LLM provider. When an agent triggers an approval-required policy, the request is held in a queue until a human approver reviews it and makes an approve or deny decision.
How does the approval flow work technically?
When a request matches an approval-required policy, the proxy generates a unique gva_ token, creates a queue item, and returns a polling URL to the agent. The agent polls the status endpoint asynchronously. A human reviews the request in the dashboard or via webhook notification and approves or denies it. The proxy then forwards the request if approved or returns a denial response.
What actions can require approval?
Any action that passes through the Govyn proxy can require approval. Common scenarios include sending emails or Slack messages, modifying databases, making high-cost LLM requests above a token threshold, calling external APIs with side effects, and accessing sensitive data. You define approval conditions in YAML policies or through the dashboard policy editor.
Can I add notes when approving or denying?
Yes. Both approve and deny actions support an optional notes field. These notes are stored permanently as part of the audit trail and are visible in the approval history. Notes are useful for compliance documentation and explaining decisions to team members reviewing the audit log later.
How are approvers notified?
Govyn sends webhook notifications when new items enter the approval queue. Configure alert rules with webhook URLs pointing to Slack, email services, PagerDuty, or any HTTP endpoint. The dashboard approval queue also polls every 5 seconds, so approvers monitoring the dashboard see new items within seconds.
What happens if nobody responds in time?
Requests not acted on within the configured timeout period are automatically denied. The agent receives a timeout response indicating the request was not approved within the allowed window. This prevents requests from sitting in the queue indefinitely and ensures agents do not hang waiting for responses that never come.
Is there an audit trail?
Every approval decision is permanently recorded with the original request, the decision, the approver identity, notes, and exact timestamps. The history tab in the dashboard shows all past decisions with filtering and cursor-based pagination. This data is available through the API for export to compliance systems.
Can different agents have different approval rules?
Yes. Approval policies support agent-specific conditions. You can require approval for all requests from a specific agent, for requests exceeding a token threshold, or for requests matching content patterns. Policies are evaluated in priority order, so you can set broad rules with agent-specific overrides.
What plans support approval workflows?
Approval workflows are available on Team ($99/mo) and Enterprise plans. The Starter plan does not include approval functionality. All Team and Enterprise plans support unlimited approval rules and history retention within the plan's log retention limits.
Does the agent need code changes?
No. Approval workflows are transparent to the agent. The proxy manages the entire lifecycle — interception, queuing, notification, polling, and response delivery. The agent does not need to know about the approval system. When a request requires approval, the proxy handles the async flow without any agent-side changes.

Enable approval workflows on Team plan

Add human-in-the-loop governance to your AI agents. Define approval rules in minutes and start reviewing requests from the dashboard.

Get started See pricing