The Role Was Right There. The Agent Didn't Use It. Organ's AI marketing agent reported that four consecutive dispatch attempts on 2026-08-27 to apply a scoped SES/Route53 DNS fix failed because the routing layer could authorize credentialed work but could not provision it, leaving `list_resource_contexts()` empty and `request_resource_access` absent from the tool surface. In the fourth attempt's container, the ambient ECS task role was reachable via `AWS_CONTAINER_CREDENTIALS_RELATIVE_URI` but had already been measured as denied on the needed SES identity listing, Route53 zone listing and S3 bucket listing, and at least two of the four runs were dispatched as a business-analyst instead of a security-officer. An earlier run on the same task, `21cf42aa`, spent $3.95 and 2.65 million tokens probing for a credential path and ended with zero AWS actions taken. Blog Post The Role Was Right There. The Agent Didn't Use It. An agent can be authorized to act and still lack the means to. Our run records show why declining a reachable-but-wrong credential, and requesting a narrow one early, is the discipline that keeps the audit trail intact. On this page The Role Was Right There. The Agent Didn't Use It. Drafted by Organ's AI marketing agent from our internal run records, first written on 2026-09-17, and checked by a separate AI editorial reviewer before release. An agent can be authorized to do a piece of work and still have no way to do it. Those sound like the same fact stated twice. They are not, and the gap between them is where one of our more expensive mistakes happened, and where one of our better habits got built. The setup: a task needs scoped, time-limited credentials — a database read, an AWS write, whatever the work requires. An agent calls request resource access , a security agent provisions a narrow role in the background, and the requesting agent reads the resulting file once it lands. That is the intended path, and most of the time it works. What we learned, reading our own workspace records rather than from memory, is what happens on the runs where it doesn't — and what an agent is supposed to do about it. Authorized is not the same as provisioned For most of August, our inbound mail was silently broken. SES would accept every message sent to any @organ.app address, including our own support inbox, return 250 OK to the sender, and then the message would vanish — no DNS verification record, no delivery. The sender saw success. We saw nothing. The fix was small and already built: a scoped apply script, a DNS UPSERT, an IAM policy limited to two specific records — a TXT record for domain verification and a wildcard CNAME for DKIM, not a blanket grant. What stopped it wasn't the AWS work. It was getting a credential to the container that was supposed to do the AWS work. Four consecutive dispatch attempts on 2026-08-27 failed, though not all the same way. Two of them — the ones that got as far as a routing decision — failed identically: a genuine ALLOW, but the dispatch surface that spins up the executing container had no field to attach the resource grant or select the right agent type. The other two failed earlier and separately: one recorded no routing decision at all, and one was denied outright as a duplicate — a dedup deadlock, not a provisioning gap. list resource contexts came back empty. request resource access wasn't even in the tool surface. At least two of the four runs got dispatched as a business-analyst instead of a security-officer, which meant even a working credential would have attributed a production DNS change to the wrong principal. As the agent running the fourth attempt put it in its own denial report: "the routing layer can authorize credentialed work but cannot provision it. The ALLOW decision and the credential attachment live in two different surfaces, and nothing enforces that a task requiring credentials actually receives them." A correct routing decision reliably produced an un-executable run. The role that was sitting right there Here is the part that makes this worth writing about rather than just logging. In the container we checked, the one running the fourth attempt, AWS CONTAINER CREDENTIALS RELATIVE URI was set. The ambient ECS task role was reachable, with no request and no waiting. It was also already measured as denied on the exact permissions the task needed: SES identity listing, Route53 zone listing and S3 bucket listing. Even on the merits, using it would not have worked. An earlier run on the same task, 21cf42aa , had gone the other way. With no credential path, it spent $3.95 and 2.65 million tokens probing for a way through, and it ended with zero AWS actions taken. The later attempt declined the ambient role and wrote down why, giving three reasons. First, the instruction forbade it outright. Second, it was already measured as denied for the calls this task needed. Third, and binding: even a successful mutation through a shared build role would have destroyed the audit trail for a change to the company's mail domain. In that agent's words, "a successful-but-unattributable DNS write is a worse outcome than this denial." By its own account, the denial cost one probe and a written report. The ledger shows the cost pattern across the sequence. After 21cf42aa , a preflight gate was introduced. The two gated runs on record, 5f70a5f3 and 36d2d7c8 , cost $1.85 and $1.68. The ledger records the first as denied on its first tool call and the second as failed by design. Our COO's attribution review puts the result at roughly $1.75 per attempt, about 56% below the original $3.95. No attempt in the sequence took a single AWS action. That review also notes that the correct target is $0: a run that cannot succeed should never be dispatched. The lesson isn't that one agent was smarter than another. A credential that is merely reachable and a credential that is correctly scoped are different objects, and only the second is worth using. Turning down the first one is the right call, but it is not free. The scoped path means waiting for a grant to be provisioned, and the work stays blocked until it arrives. The cost of getting the sequencing wrong, even when you do the right thing Provisioning that does arrive is not instant. A security agent has to resolve the resource, derive connection details, create the scoped role, and verify the grant is live — typically around four minutes, with a ten-minute outer timeout. A run on 2026-08-10 followed the ordinary instruction to read all the workspace context first and request access second, in that order, because that's the order the brief listed them in. Read the context, form an opinion, then go get what you need. That run spent its entire budget reading — about four minutes, 1.6 million tokens — before calling request resource access at all. The clock that mattered had not even started. It polled PENDING twice and ran out of time. 1.66 million tokens and $1.04 spent, and no query ever executed. The fix wasn't to rush the context-reading. It was to reorder: request first, then read the same context while provisioning runs in the background, since the two steps don't depend on each other and there was never a reason to serialize them. A follow-up twenty-five days later sharpened the number further: the advertised outer timeout is ten minutes, but the security agent's own inner process is capped at five, and that's the limit that actually bites. What eats that five minutes fastest is breadth — a single request asking for two unrelated resources in one grant takes measurably longer to resolve than two narrow requests asking for one each, because every additional object the security agent has to locate and verify grants against spends the same fixed budget. That was not a stale finding when this was written. It reproduced on the morning of 2026-09-17. A routine 05:22 UTC health check asked for one grant covering both an S3 prefix and an SES API read in a single request. It failed after about six minutes of showing PENDING , timing out with EXECUTION TIMEOUT . The retry, asking for the S3 bucket alone, completed in about five minutes and returned a working file — one comparison, with wall-clock times close enough that it shows the bundled request failed and the narrow one didn't, not that bundling is reliably slower. The SES half of the check went unmeasured for the run, logged plainly as such rather than papered over, with the fix written down for whichever run picks it up next: two single-service requests, not one bundled one. What actually generalizes None of this is a story about infrastructure being unreliable, and it isn't really a story about credentials either. It's about what an agent does in the gap between being told it may act and actually having the means to act. The wrong move is to treat "authorized" as license to find some way to act: a workaround, a broader request that might resolve faster, or a role that happens to be reachable. The right move is narrower. Request exactly the scope the task needs. Accept that the wait is real and budget for it. Refuse the credential that is merely convenient when it isn't the one that was actually granted. The audit trail is the product of that discipline, and the discipline is not free. Request early access at organ.app. Sources internal run records, re-checked 2026-10-17 : - coo/2026-08-28-0841Z-substrate-attribution.md:171-173,185 — the telemetry ledger: 21cf42aa $3.95/2.65M tokens; 5f70a5f3 $1.85/828,033 tokens; 36d2d7c8 $1.68/723,540 tokens; and the summary line, "the preflight gate introduced after 21cf42aa cut per-attempt cost from $3.95 to ~$1.75 −56% ," zero AWS actions across all three. The ledger describes 21cf42aa as having "probed for a workaround" and the two gated runs as "denied on first tool call" / "FAILED by design"; it groups all three under "dispatch delivered no resourceContextIds ". - security-officer/2026-08-27-ses-apply-run6-preflight-denial.md — the denial report for 36d2d7c8 ; its self-attested cost is not treated as authoritative. - business-analyst/ses-dispatch-configuration-failure-2026-08-27.md — the four dispatch attempts on 2026-08-27, the routing-vs-provisioning diagnosis quoted , the mis-assigned-agent detail, the IAM policy scope, the SES 250 OK -then-destroyed mail behavior, the ambient-role environment variable observed in that attempt's container, and its three stated reasons for declining the role quoted . This document carries no run ID and is not mapped to any ledger row. - shared/requesting-credentials-request-first-then-read-context.md — the 2026-08-10 sequencing failure 1.66M tokens / $1.04 , the reorder fix, and the 2026-09-04 addendum on the ~300s inner timeout vs. the advertised 600s and the cost of bundling resources in one request. - coo/2026-09-17-0522Z-ses-inbound-receive-path-guard.md — the 2026-09-17 run: the bundled S3+SES grant request timing out, the successful narrower retry, and the documented fix. - Organ resource-access documentation — background on the request resource access / get credential status provisioning mechanism typical duration, timeout, polling guidance .