Agent workflows: permissions, state and reliable execution
Practical guide
Updated:
Design AI workflows with tenant authorisation, durable state, plan approval, deduplication, result reconciliation and recovery.

An AI agent lets a model choose actions within a defined set of tools and data. Reliable business use requires enforceable authentication, authorisation, persistent state, approval, retries and confirmation of external results.
This guide covers operational reporting, stock alerts, review monitoring, customer-service assistance and multi-step collaboration. Prerequisites are data pipelines and RAG knowledge systems.
1. Choose an appropriate control model
| Requirement | Possible approach | What to verify |
|---|---|---|
| Clear rules and steps | Conventional code, scheduling or a fixed workflow | Rules, complete data, failures and reruns |
| Answers grounded in business documents | Add RAG within the process | Sources, document access, retrieval and answer quality |
| Steps that depend on intermediate findings | An agent with bounded tools | Tool choice, stopping conditions and cost |
| Different specialist contributions | Staged or multi-agent work | Responsibility, handoffs, evidence and shared errors |
These approaches can be combined. Use the actual task to determine where model judgement helps. Data anomalies may also be handled through explicit statistical or business rules.
Anthropic's architecture guidance distinguishes predefined code paths from model-directed tool use and recommends starting with simpler solutions. This guide uses that distinction; check tool interfaces against the versions actually adopted.
2. Separate reading, recommendations and execution
| Use case | Reading and analysis | Reviewable output | Controlled external action |
|---|---|---|---|
| Operational reporting | Authorised data, periods and metric definitions | Report with sources and flagged exceptions | Send to specified recipients or publish externally |
| Stock alerts | Inventory, demand, lead time and data freshness | Reorder recommendation with evidence and assumptions | Create an order or change purchasing/inventory |
| Review monitoring | Permitted review sources and sample period | Themes, supporting evidence and review items | Customer reply, public statement or ticket resolution |
| Customer-service assistance | Authorised orders and applicable policies | Reply draft and supporting clauses | Send a message, refund or modify an order |
| Competitor monitoring | Permitted sources and comparable price conditions | Change summary and explanations to confirm | Adjust prices, advertising budgets or channel settings |
Source material cannot authorise an action. Treat websites, files, reviews and tool outputs as data rather than permissions or approval.
3. Persist the work and its ownership
Record tenant and owner, run ID, scope, state and version, plan revision, source inputs, tools and parameters, required approval, execution receipts, errors and timestamps. Keep credentials outside model prompts, conversations and client code.
The server derives identity, tenant and roles from authenticated context. Recheck authorisation for reads, approvals, execution, retries and exports. A client-supplied account, tenant or role is not sufficient evidence of permission.
Save state before reporting success. Returning users and other devices should read the same server record. LangGraph's persistence documentation distinguishes checkpoints from other storage; its in-memory examples are not durable deployment storage across process restarts.
4. Model state, approval and stale actions explicitly
A controlled workflow can include draft, awaiting review, ready, running, succeeded, failed and reconciliation states. If a submitted action times out without a reliable result, reconcile it against external receipts before deciding whether it succeeded or failed.
This pure function demonstrates permitted transitions, version conflicts and approval of a specific plan revision. It consumes actual run state and generates no business result. A real service must also authorise requests, save transitions transactionally and connect its queue and execution receipts.
function advanceRun(run, event) {
const transitions = {
draft: {submit: "awaiting_review", cancel: "cancelled"},
awaiting_review: {approve: "ready", request_changes: "needs_changes", reject: "rejected", cancel: "cancelled"},
needs_changes: {revise: "draft", cancel: "cancelled"},
ready: {dispatch: "running", cancel: "cancelled"},
running: {succeed: "succeeded", known_failure: "failed", uncertain_result: "reconciling"},
reconciling: {confirmed_success: "succeeded", confirmed_failure: "failed"},
failed: {revise: "draft"},
succeeded: {}, rejected: {}, cancelled: {}
};
if (!run || !event || !Object.hasOwn(transitions, run.state)) {
throw new Error("Known run state and event required");
}
if (!Number.isSafeInteger(run.version) || run.version < 0 || run.version >= Number.MAX_SAFE_INTEGER ||
!Number.isSafeInteger(run.planRevision) || run.planRevision < 1 || run.planRevision >= Number.MAX_SAFE_INTEGER) {
throw new Error("Valid version counters required");
}
if (event.expectedVersion !== run.version) throw new Error("Stale run version");
if (!Object.hasOwn(transitions[run.state], event.type)) throw new Error("Transition not allowed");
if (event.type === "approve" && event.planRevision !== run.planRevision) {
throw new Error("Approval does not match the current plan");
}
if (event.type === "dispatch" && run.approvedRevision !== run.planRevision) {
throw new Error("Current plan approval required");
}
const revised = event.type === "revise";
return {
...run, state: transitions[run.state][event.type], version: run.version + 1,
planRevision: run.planRevision + (revised ? 1 : 0),
approvedRevision: revised ? null : event.type === "approve" ? run.planRevision : run.approvedRevision
};
}Every plan edit increments its revision and clears previous approval. Persistence must check run ID, tenant and expected version. Report a conflict clearly, reload the current record and let the user choose the next step. A successful function call does not establish a database save or an external action's success.
Approval screens should show the action, target, parameters, data scope, effect and expiry. Approval applies to the current proposal. Changed content, accounts, tenants or expiry require renewed checks. LangGraph's interrupt/resume documentation describes one framework implementation; the application remains responsible for identity and business approval.
5. Define tool contracts, retries and confirmation
| Situation | Handling |
|---|---|
| Missing permission or expired identity | Stop; explain how to sign in again or contact an authorised person |
| Invalid parameters, versions or required fields | Identify the specific issue and retain entered information |
| Read timeout or rate limit | Retry within defined limits and service rules; retain the final error |
| Confirmed write failure | Confirm that no side effect occurred before applying the approved retry policy |
| Unknown write result | Reconcile receipts and execution records using the same business request ID; avoid blind resubmission |
| Repeated clicks or reruns | Identify the same logical operation through durable request IDs and deduplication records |
| Partial completion | Show completed and outstanding work, with a workable recovery action |
Tools validate inputs, restrict targets and return classifiable results. Retain sources, necessary decision summaries and receipts. A model's description of success is not evidence that an external system completed the work.
Define limits, approval responsibility and recovery for prices, budgets, payments, publishing and deletion. Validate cross-system retry and deduplication behaviour against the provider's actual interfaces and receipts.
6. Bound continuing work, collaboration and memory
Set per-run limits for steps, time, cost, tools and failures. Save progress and the reason when a limit is reached, then offer a workable continuation path. Scheduled work needs an owner, expiry, failure notification and cancellation route.
Multiple agents can divide retrieval, analysis and writing. Shared incorrect evidence can still produce agreement around an error. Review must trace claims to original data, receipts or tests. Distinguish AI checking from a named person's actual review.
Apply tenant and run authorisation to memory and checkpoints. Revalidate identity and approval when resuming. An old conversation's identity, cache or approval must not carry over to another account.
7. Security, observation and cost
OWASP's prompt injection guidance includes indirect injection through external material. Limit impact through bounded tools, server authorisation, controlled data transfers and approval of consequential actions.
Measure actual task completion, tool failures, incorrect actions, human intervention, unresolved results, latency, cost and rework. Include model, retrieval, tool, compute and human costs. Keep missing usage or price data unknown rather than substituting fixed savings or cost estimates.
Retain enough protected operational evidence to diagnose failures while limiting private content and personal data. Publish only measurements cleared for disclosure.
8. Test branches before release
- Normal completion, no data, broken sources, unsupported tools and invalid inputs.
- Signed-out users, revoked access, cross-tenant requests and stale pages from another account.
- Leaving during approval, editing an approved plan, expired approval and concurrent users.
- Duplicate submission, network loss, process restarts, version conflicts and partial completion.
- Rate limits, spending limits, loops, prompt injection and invalid tool output.
- Successful writes with lost responses, unavailable receipts and recovery after human reconciliation.
Begin with reading and drafts, then test approved external actions. Separate test accounts, sandboxes and fixtures from production data. Real email delivery, payments and public publishing require authorisation for the relevant action.