Your agent asked the manager to approve a wire of $5,000 to vendor Y. The manager clicked yes in Slack. The agent replanned, decided $50,000 was the right number, and pulled the trigger anyway. The approval was real. The binding to the parameters was not. This post shows the design pattern that fixes it: two side-by-side code paths and a verification step that survives a European Union (EU) AI Act audit request.
I'll call the fix an approval object. It's a first-class artifact your agent has to earn before any irreversible action runs. It's the pattern the community started naming out loud this summer, and UiPath Action Center ships the record it's built on.
An approval object is an immutable record of a specific proposed action. It carries the action type, exact params, risk level, human approver identity, approved results, and timestamp, all addressed by a task key that the tool can look up and validate before acting. The agent cannot run the action without the tool re-fetching that record and checking it against the params it's about to send. Replan the params after the human said yes, and the check fails. The tool refuses. The audit log records the attempt. In UiPath, Action Center gives you the trackable record out of the box; the verification check is what you build on top of it, and it's the piece most human-in-the-loop (HITL) implementations are missing.
What is approval theatre?
Here's the loose pattern most agent frameworks default to. A tool call goes out to a HITL step, the human sees a summary, the human replies "approve," and the agent takes it from there.
Two things are broken here, and both are the same bug.
An approval value is a string, not an artifact. There's no record of what was approved beyond a Slack message the agent itself composed. And agent.state is mutable between the ask and the call. A replan, a prompt injection, a tool that mutates working memory, and the number the human saw is not the number that hits the bank API.
This is the frustration surfacing in the developer community through mid-2026. Threads on r/AI_Agents and r/LangChain keep landing on the same diagnosis: most HITL implementations are theatre because the approval is disconnected from the action. The fix that keeps appearing in those threads is to treat approvals as a first-class artifact.
Prompt injection is the wedge that makes this urgent. It has held the #1 spot on the OWASP Top 10 for LLM Applications in both published editions (2023 and 2025), and the exploit pattern against agentic systems is exactly the replan-after-yes shape above. If the params can drift after approval, injection wins by default.
How to stop an agent from changing parameters after approval
The fix is an approval object.
It carries:
- action type (e.g. bank.wire)
action type (e.g. bank.wire)
- exact params (amount, vendor, account)
exact params (amount, vendor, account)
- risk level
risk level
- a diff or preview the human saw
a diff or preview the human saw
- approver identity
approver identity
- timestamp
timestamp
- a task key the tool can look up and validate before acting
a task key the tool can look up and validate before acting
The tool rechecks that record against the exact params it’s about to send, every time. That's what "params-bound approvals" means in practice.
For example, you can implement the UiPath HITL pattern in your LangGraph-style agent - pausing on a durable LangGraph interrupt() call and calling out to the Action Center using CreateEscalation(). The ability for the agent to checkpoint here lets the wait survive hours, days, or a process restart. And, when needed, your autonomous agent can use the tasks.retrieve() API to retrieve the full Task object to explicitly validate what the human approved, and this validation can happen anywhere in your workflow provided the same key is used – in a later agent, in a Maestro Flow script node, or in a step within an RPA or API workflow. What matters is that the HITL decision is captured and retrievable.
The two code paths differ in one thing only: what the tool trusts at the moment it acts. If your Action Center app lets the approver edit values, verify against and execute with the edited values from task.data, not the agent's originals.
What’s the difference between a regular approval and an approval object?
Approval theatre (loose)
Approval object (params-bound)
The approval
A string in a chat reply
A first-class artifact the agent has to earn
What's recorded
A Slack message the agent composed
Action type, exact params, risk level, approver identity, timestamp, task key
Source of truth at execution
agent.state: mutable in-process memory
Orchestrator's own record, re-fetched by task key
Agent replans after "yes"
Call proceeds with the new params
Check fails, tool refuses, attempt is logged
Failure direction
Fails open
Fails closed by construction
Prompt injection
Wins by default - the replan-after-yes shape is the exploit
Drifted params never reach the tool
Where verification lives
The agent framework, if anywhere - bypassable on a runtime swap
The tool, at the point of irreversible action
Audit artifact
Logs the agent wrote about itself, reconstructed after the fact
The approval object itself, captured at the moment of decision
Durable wait
Request-response; breaks on restart
Survives hours, days, a process restart
Move that trust boundary and three things follow:
- The check runs against the params the human saw, held in Orchestrator, not against anything that the agent could have replanned in memory. Replanning post-approval fails the check, so the tool call fails closed, not open.
The check runs against the params the human saw, held in Orchestrator, not against anything that the agent could have replanned in memory. Replanning post-approval fails the check, so the tool call fails closed, not open.
- The approval object is the audit record. Article 12 of the European Union (EU) AI Act requires high-risk AI systems to maintain automatic logs sufficient to reconstruct decisions and identify risks. For remote biometric identification systems (defined in Annex III, point 1(a)), it goes further and mandates a specific field list: the period of each use, the reference database checked, the input data, and the identity of the persons verifying results. Even if your system isn't one of those, the broader point holds - the fields you need for a defensible audit trail are the same fields an approval object captures at the moment of decision, not reconstructed later from logs the agent wrote about itself. Enforcement for high-risk AI systems under Annex III was originally slated for August 2026. The Digital Omnibus regulation extended the core high-risk deadlines to December 2027, but the deadline is coming and compliance teams are already asking for these records.
The approval object is the audit record. requires high-risk AI systems to maintain automatic logs sufficient to reconstruct decisions and identify risks. For remote biometric identification systems (), it goes further and mandates a specific field list: the period of each use, the reference database checked, the input data, and the identity of the persons verifying results. Even if your system isn't one of those, the broader point holds - the fields you need for a defensible audit trail are the same fields an approval object captures at the moment of decision, not reconstructed later from logs the agent wrote about itself. Enforcement for high-risk AI systems under Annex III was originally slated for August 2026. The Digital Omnibus regulation extended the core high-risk deadlines to December 2027, but the deadline is coming and compliance teams are already asking for these records.
- As a result, the routing is decoupled from the enforcement. Slack, Teams, Outlook, a custom inbox: it doesn't matter where the human clicks. The record lands in the same place and the tool runs the same check.
As a result, the routing is decoupled from the enforcement. Slack, Teams, Outlook, a custom inbox: it doesn't matter where the human clicks. The record lands in the same place and the tool runs the same check.
Why UiPath Action Center for the reference implementation
Action Center is the reference implementation because it gives you the trackable record out of the box; the escalation, the resolved data, and the audit trail. Your context will vary. If you already have a verification layer that checks params before acting, keep it and skip ahead.
The approvals land in a single place regardless of channel, and Orchestrator holds the audit trail, outside of anything the agent can rewrite or tamper with. Since 2025, UiPath has been rolling out unified audit logging across its platform, with export capabilities to your SIEM of choice via API and CSV export.
Whether you’re using Microsoft Sentinel, IBM QRadar, Splunk, or another SIEM, your approval events will still come from the same audit log APIs. That's the artifact your compliance team is asking for.
When you pick where your approval records live, look for two certifications:
- ISO/IEC 42001:2023 is the international standard for AI management systems; UiPath received ISO/IEC 42001:2023 certification in October 2025.
is the international standard for AI management systems; UiPath received ISO/IEC 42001:2023 certification in October 2025.
- AIUC-1 is a comprehensive security, safety, and reliability standard for AI agents. It tests AI systems and agents against real-world risks like prompt injection and tool misuse, the same risks behind the replan-after-yes pattern.
is a comprehensive security, safety, and reliability standard for AI agents. It tests AI systems and agents against real-world risks like prompt injection and tool misuse, the same risks behind the replan-after-yes pattern.
UiPath holds both ISO/IEC 42001 (the AI governance system) and AIUC-1 – one of the only enterprise automation platforms to combine a general AI-management-system standard with an agent-specific safety certification.
Agents, robots, and humans run on the same orchestration substrate. The same approval object that gates an autonomous AI agent also gates a classical automation, and the audit log doesn't care which one asked. That matters when your Slack-triggered Okta provisioning workflow has an agent step, a robot step, and a manager step in the same run.
One practical default: HITL on first use. New action type, new tool, new risk tier; route through an approval object until you have the evals to trust it unattended. This ladders up to the empirical picture Anthropic published in "Measuring AI agent autonomy in practice": 80% of tool calls come from agents with at least one safeguard, but that study also observes it can't assess the quality or tamper-resistance of those safeguards from the outside. Params-bound is how you start to measure it.
How do I build a long-running approval workflow for an AI agent?
Short answer: put an approval object between the agent's proposed action and the tool that executes it, and make the tool refuse to run without re-checking that record against the exact params. The agent proposes, the human decides, and the tool verifies against Orchestrator’s own record. Anything else is approval theatre.
The five moving parts, in order:
- A trigger that turns a natural-language request (Slack, email, a form) into a structured proposed action with typed params
A trigger that turns a natural-language request (Slack, email, a form) into a structured proposed action with typed params
- An approval object created at the moment of proposal, carrying action type, params, risk level, preview, and approver group, with an editable scope where the approver can adjust the params before the record is finalized
An approval object created at the moment of proposal, carrying action type, params, risk level, preview, and approver group, with an editable scope where the approver can adjust the params before the record is finalized
- A durable wait that survives process restarts and human latency measured in hours or days, not seconds. This is the "long-running" part; a request-response HTTP call won't cut it
A durable wait that survives process restarts and human latency measured in hours or days, not seconds. This is the "long-running" part; a request-response HTTP call won't cut it
- A trackable record returned on approval, holding the final (possibly edited) params for the tool to check against
A trackable record returned on approval, holding the final (possibly edited) params for the tool to check against
- Tool-side verification at the point of irreversible action, plus an audit stream that captures every field: proposed params, edited params, approver, timestamp, and outcome
Tool-side verification at the point of irreversible action, plus an audit stream that captures every field: proposed params, edited params, approver, timestamp, and outcome
That's the pattern. The stack question is next.
Example: Slack-to-Okta approval workflow with an editable scope, time-boxed access, and a full audit trail
The UiPath stack I’d use for this shape: UiPath Orchestrator + Action Center + the UiPath Okta connector, triggered from Slack via the UiPath Slack integration, with unified audit exporting to your SIEM.
How this combination maps to our requirements:
- Slack request in. UiPath Slack integration fires an Orchestrator process with the requester, target system, and requested scope as typed params.
Slack request in. UiPath Slack integration fires an Orchestrator process with the requester, target system, and requested scope as typed params.
- Manager approval with editable scope. Action Center creates the approval object. The manager can edit the scope inline; the edit becomes part of the trackable record, not a side channel. Verification checks against the final scope, not the original request.
Manager approval with editable scope. Action Center creates the approval object. The manager can edit the scope inline; the edit becomes part of the trackable record, not a side channel. Verification checks against the final scope, not the original request.
- Okta provisioning. The UiPath Okta connector runs the provisioning call, behind your verification step: re-fetch Orchestrator’s record and check the final scope before the call goes out. Re-plan the scope after approval and the call fails closed.
Okta provisioning. The UiPath Okta connector runs the provisioning call, behind your verification step: re-fetch Orchestrator’s record and check the final scope before the call goes out. Re-plan the scope after approval and the call fails closed.
- Auto-expiring access. Store an expiry in the approval’s data, and a scheduled deprovision job runs against it. No orphaned access, no manual cleanup.
Auto-expiring access. Store an expiry in the approval’s data, and a scheduled deprovision job runs against it. No orphaned access, no manual cleanup.
- Full audit trail. Orchestrator holds the audit record. UiPath's unified audit logging exports the chain to your SIEM. ISO/IEC 42001:2023 certification (confirmed October 2025) covers the AI management system itself, and AIUC-1 covers UiPath AI products, including agents. That's the artifact your compliance team asks for when a regulator shows up.
Full audit trail. Orchestrator holds the audit record. UiPath's unified audit logging exports the chain to your SIEM. ISO/IEC 42001:2023 certification (confirmed October 2025) covers the AI management system itself, and AIUC-1 covers UiPath AI products, including agents. That's the artifact your compliance team asks for when a regulator shows up.
If you're rolling your own approval system on top of a queue instead of Action Center, know what you're signing up for: durable waits, editable-scope UI, multi-channel routing, tamper-resistant audit, verification that checks the approval record instead of memory, and the eval work to trust unattended runs. Each is its own project.
One tip and one caveat
Put the verification in the tool, not in the agent framework. Framework-level checks are able to be bypassed the moment someone swaps runtimes or wires in a new tool. Tool-level checks fail closed by construction.
One caveat: params-bound approvals add latency and, on the first pass, friction with your product team. You will be asked why the agent can't "just" retry with new params after a rejection. The answer is that the retry is a new proposed action, needing a new approval object. That's the feature, not the bug.
Give it a spin
The pattern is the point. Approval object, trackable record, tool-side verification, audit trail that survives a regulator. UiPath Action Center is the reference implementation I'd reach for, and the Action Center docs are the entry point.
If you're building this on a different stack, I'd like to see it; ping me on LinkedIn. And if you hit a shape of approval object that doesn't fit the fields I listed (risk tier, diff, expiry), tell me what you added. That's the spec nobody wrote yet, and it's going to get written in public.










