# Agent Identity and Durable Workflows: The Two Problems MCP Can't Solve

> Source: <https://dev.to/aws-builders/agent-identity-and-durable-workflows-the-two-problems-mcp-cant-solve-4llb>
> Published: 2026-08-13 09:52:38+00:00

MCP 2026-07-28 dropped sessions. The `initialize`

handshake is gone. The `Mcp-Session-Id`

header is gone from Streamable HTTP. Protocol version, client info, and capabilities now travel in a `_meta`

field on every request, so any instance can serve any call.

The protocol is cleaner for it. This is the largest revision since launch, and it leaves both of the questions that block enterprise agent deployments exactly where they were. MCP standardizes how a model reaches a tool. Neither question lives inside that scope, and no future revision is likely to put them there:

Who is the agent acting as, and what is it allowed to do?

What happens when a process takes three days and the model context is gone?

The spoiler: on AWS the parts already exist. Policy in AgentCore evaluates every Gateway call in Cedar against a principal, an action, and a resource, and writes the allow or deny to an audit log. Temporal policies, added in August 2026, extend that across an agent's trajectory, including human approval ahead of a privileged action. AgentCore Identity distributes the credentials. Step Functions holds anything measured in days. The remaining work is composition: deciding which principal each agent acts as, and what it may commit to. No service ships that decision.

The stateless redesign removes real pain. Long-held SSE connections forced sticky routing, which pushed teams into shared session stores and gateway packet inspection just to scale horizontally. The new model provisions for request rate instead of concurrent users. A round-robin load balancer is now enough. Lambda, Cloud Run, and Workers become viable backends.

Multi Round-Trip Requests (SEP-2322) handle elicitation without a held connection. The server returns an `InputRequiredResult`

carrying what it still needs plus an opaque `requestState`

blob. The client collects the answers and re-issues the same call with `inputResponses`

and the echoed state. Any instance picks up the retry, because the continuity rides in the payload. Mid-conversation failover stops being a data-loss event.

The release also hardened authorization: RFC 9207 issuer validation, RFC 8707 resource indicators against the confused-deputy problem, client metadata documents replacing dynamic client registration, and Enterprise Managed Authorization as a named extension. That work is real. It secures the channel between a client and a server, and it settles which server a token was minted for. The question enterprise platform teams keep raising sits one layer up: which principal the agent acts as inside that channel, and what that principal may commit to.

A pilot agent usually runs on one set of developer credentials. It can reach whatever the developer can reach. That works while prototyping. In production it is a standing incident.

An enterprise platform has to separate four things:

`alexey@example.com`

`production-planning-agent`

Permissions do not flow automatically from the first of these to the rest. A finance director can approve €50,000 payments. A meeting-summary agent running on that director's behalf has no business inheriting that authority.

The effective permission at any moment is the intersection:

*human permission ∩ agent permission ∩ task scope ∩ current policy*

Can-or-cannot access to a service is too coarse for an agent. Split it into levels:

| Level | Example |
|---|---|
| Read | View production schedule |
| Analyze | Run what-if scenarios |
| Recommend | Propose schedule changes |
| Simulate | Execute in sandbox |
| Create draft | Write proposal for review |
| Request approval | Trigger human decision |
| Execute | Commit the change |
| Approve | Authorize another's request |

An agent may simulate a production-plan change without publishing it. It may request approval for a change it has no authority to execute itself. Each level carries different risk, different audit requirements, and different authorization rules.

What decides where the approval line sits is consequence rather than technical risk: money, employment, legal rights, or access to a service. Anything that touches one of those belongs above "request approval."

AWS Identity and Access Management (IAM) and Amazon Bedrock AgentCore Identity each cover part of this: delegated access, OAuth flows, machine-to-machine auth, credential distribution, audit trails. The architectural principle outlives any single service. Agent identity is a first-class security principal and needs the same rigor you already apply to workloads and users: lifecycle management, credential rotation, permission reviews, anomaly detection, revocation. The controls that govern service accounts and assumed roles, extended to software that makes decisions.

Consider a schedule change that breaks a committed delivery date.

| Step | Needs |
|---|---|
| 1. Investigate the line deviation | Model reasoning |
| 2. Read order book and capacity | Model reasoning |
| 3. Interpret delivery commitments | Model reasoning |
| 4. Propose a revised sequence | Model reasoning |
| 5. Request plant manager approval | Durable execution |
| 6. Wait for approval (days) | Durable execution |
| 7. Publish the plan to the MES | Transaction |
| 8. Notify affected customers | Reliable delivery |
| 9. Record evidence | Audit |

Steps 1 to 4 benefit from model reasoning: ambiguous language, edge cases, policy interpretation. Steps 5 to 9 cannot live inside a model conversation. The context window will be gone. The session will have ended. The approval may take 72 hours.

Two mechanisms in 2026-07-28 look like answers here. Both deserve precision.

`requestState`

solves the protocol-level multi-round problem. The server returns a pending result with the questions it still needs answered, the client re-issues with answers, and any backend instance handles the continuation. This is progress for short-lived elicitation: clarifying ambiguous tool parameters, collecting missing inputs inside a single task. Its guarantee is scoped to one logical call. It has no concept of waiting days for a human decision, compensating a prior step when a later one fails, or producing an auditable record of what was authorized and when.

The Tasks extension (`io.modelcontextprotocol/tasks`

, SEP-2663) goes further. Promoted out of the experimental core after production feedback forced a redesign, it lets a server answer `tools/call`

with a task handle. The client then drives `tasks/get`

, `tasks/update`

, and `tasks/cancel`

, and can disconnect and come back later. For a CI run, a video render, or a data import, that is the right mechanism.

A durable task ID still does not make the underlying work durable. Tasks gives you a handle plus a small state machine pointing at a result. It does not give you compensation when step 7 fails after step 5 committed, an approval queue with delegation rules, per-step retry policy, or an evidence trail an auditor will accept. Two constraints matter for planning. Task creation is server-directed and requires the client to advertise the extension per request, so an unsupported client falls back to synchronous calls. And `tasks/list`

was removed outright, because listing tasks cannot be scoped safely once the protocol is stateless. Client and SDK support is still filling in.

So the division of labor holds. Interpretation belongs to the agent, reliability belongs to a workflow engine.

*start_schedule_change_workflow(plan_id, affected_orders, reason, evidence)*

Behind that call, AWS Step Functions, Temporal, or Conductor manages durable state, timeouts, retries, compensation, and auditability. The agent picks the workflow; the engine owns everything after that.

The principle is worth stating plainly: probabilistic systems decide, deterministic systems execute.

HTTP 200 tells you the tool call succeeded. It says nothing about whether the agent acted correctly. Was this the right tool? In the right order? Was the source data current? Was the proposed change within policy? Should the agent have refused?

| Layer | Question |
|---|---|
| Model | Did it understand the task? Did it flag its own uncertainty? |
| Retrieval | Were authoritative sources used, deprecated ones excluded? |
| Tool selection | Correct tool, valid parameters? |
| Execution | Expected operation performed? |
| Policy | Action permitted, approval requested where required? |
| Outcome | Business result correct, and how much human correction was needed? |

Every change to model, prompt, tool description, retrieval index, or policy can shift behavior. The platform needs representative task suites that run on a schedule as well as at release.

For AWS-heavy organizations, use the existing deterministic services as the backbone:

Four things decide whether this holds up.

**Credentials come from AgentCore Identity.** Permission is a separate question, answered by the target service.

**The policy engine sits at the Gateway, outside agent code.** Cedar rules read principal, action, and resource, and every decision lands in an audit log. Temporal policies add the sequence checks: where an argument came from, how old the data is, whether a human signed off.

**Consequential work runs in Step Functions.** The agent picks a workflow. Proceed, wait, retry, compensate: all of that belongs to the engine.

**The trace is the audit record.** It runs from user request through agent session, model decision, authorization check, tool call, workflow, human approval, system change, evidence. And it has a shelf life. Step Functions keeps the execution history of a standard workflow for 90 days after it completes, and the limit is hard. European deployers of high-risk systems are expected to hold logs for at least six months under Article 26 of the AI Act. Closing that gap means calling GetExecutionHistory when an execution finishes and shipping the result somewhere durable, in a form that later edits cannot touch.

Agents on developer or admin tokens. Each one is a production incident waiting for a trigger.

Permission sets that turn out identical. What the human can do, what the agent should do, what the task needs: when all three match, nothing has been scoped.

Work that outlives a model context. Human approval, multi-day execution, transaction guarantees. `requestState`

covers one call, Tasks covers the handle, and the process itself needs an engine.

Clients that stay silent about `io.modelcontextprotocol/tasks`

. A server can only create a task when the client asks for the extension on that request, so an unsupported client quietly gets synchronous calls.

Test suites that run at release and nowhere else. Ten to twenty representative scenarios, replayed after every prompt, tool, or model change, catch what a release gate misses.

The identity question has four fields: which principal, which permissions, which task scope, expiring when. An agent that has never had those fields written down still has them. They were set by whoever issued the token.
