your agentic marketer fails on permissions, not prompts
researchers put people in front of AI agent commands and asked a simple question: approve, or deny?
across more than 40,000 runs and 409,000 individual decisions, the average person caught 66.3% of the threats. they missed one in three. only 35.2% of players caught every threat, and when the bar was raised to "catch every threat without blocking more than one in five safe commands," just 20.8% passed.
the single most-missed command was npm run analyze. people approved it 64.7% of the time, with the suspicious payload sitting visible in the logs.
that study is about coding agents. but it describes the exact thing every founder is building right now, and it explains why those builds stall.
TL;DR
- the blocker for agentic marketing is permission, not capability. founders say "this is amazing," then decline to hand over the account.
- the approval popup is not a control. 409,000 decisions, 66.3% accuracy, and scope violations were missed 35% of the time. attention decays as the session runs.
- scope beats approval. design so a rubber-stamped yes is still safe, because sooner or later every yes is rubber-stamped.
- five gates do the work: small credential, unreachable terminal action, frozen approval, fail-closed default, attributable output.
- this post was published by the agent it describes, as a pull request i had to merge myself.
the wall everyone hits
scroll the indie forums for two weeks, as i just did, and you find the same shape over and over. someone automates their reddit outreach. someone ships an SEO agent that writes in the background. someone builds agents that find buyers and warm them up.
then you find the honest one. a founder building an AI marketing agent described the conversation he kept having: a founder would say this is amazing, they would try it, and then he would say "great, we just need access to your ad account." and they would say absolutely not.
that is the whole industry in one exchange. the model is good enough. the demo works. and the thing that kills it is that nobody wants to hand a machine the keys to a system where mistakes are expensive and public.
so the standard fix is a human approval step. the agent proposes, you approve, everyone relaxes.
the data says that step does not work the way we think it does.
why the approval popup fails
go back to the numbers. it is not that people are careless. it is that reviewing is genuinely hard and gets harder the longer you do it.
three findings matter for anyone designing this:
| what people were shown | how often they missed it |
|---|---|
| obviously destructive commands | 11.7% |
| persistent mutations | 23.8% |
| exfiltration or code execution | 33.4% |
| scope violations | 35.0% |
look at the bottom row. scope violations were the most-missed category. those are the cases where the action itself looks fine, and the only problem is that it is happening somewhere it should not. that is precisely the failure mode of a marketing agent: the post is fine, it just went to the wrong account.
the study also found miss rates climbing back up toward the end of sessions as fatigue set in. the tenth approval gets less attention than the first. and the over-blocking is real too: 59% of people blocked a harmless npm config set registry.
so you get the worst of both. real threats waved through, safe work interrupted, and a human who is now trained to click yes.
if your safety model is "the human will catch it," your safety model is a coin flip that gets worse over time.
the reframe: make the yes cheap to be wrong about
here is the shift that unlocked this for me.
stop trying to make approval more reliable. assume the approval is wrong and make the blast radius survivable anyway.
that sounds defeatist. it is the opposite. it is what lets you give an agent real write access to a real system, because you have arranged things so the worst it can do is something you can undo in one click.
concretely, i built an agentic publisher for this blog this week. it drafts a post, renders it for this site, commits it, and opens a pull request. it published the post you are reading.
it is also incapable of putting anything live. here is how.
the 5 gates
gate 1: the credential is smaller than the job
the agent does not hold my github account. it holds a token minted per publish, scoped to one repository, carrying exactly two permissions, and it expires in an hour.
i tested the containment rather than assuming it. with that token in hand, reading my other repository returns 404. not "denied by policy." denied by construction, because the token was never issued for it.
the rule: the credential should expire before you finish reading the diff. if it lives longer than the task, it is not a credential, it is a liability.
gate 2: the terminal action is unreachable, not forbidden
the agent opens a pull request. it cannot merge one.
this is not a rule in the prompt. prompts are suggestions. the code path that merges does not exist in the tool the agent can call, so no amount of clever instruction reaches it. the difference between "the agent is told not to" and "the agent cannot" is the entire safety argument.
merging is a human action, in the github UI, by me.
gate 3: what you approved is what ships
this is the one that took the most thinking, and it is the one most builds get wrong.
the agent shows you a preview, you approve, and then it publishes. between those two moments, what stops the content from changing?
the naive version re-renders the post at publish time. that quietly reopens the gap: you approved one thing, a slightly different thing shipped. so the preview freezes the exact rendered bytes, and at publish time the system re-derives them and compares byte for byte. any mismatch and it refuses, with a message telling you to look at the change.
the rule: an approval is a claim about a specific artifact, not about a task. if you cannot prove the artifact is unchanged, you do not have an approval.
gate 4: unconfigured means off, loudly
with no credentials set, the publish path does not silently degrade or half-work. it returns a plain refusal naming what is missing.
this matters more than it sounds. the dangerous default is a system that appears to work while doing nothing, or worse, one that falls back to some broader credential lying around in the environment. there is no fallback. the token is passed in explicitly or nothing happens.
gate 5: the agent's work is attributable forever
every commit the agent makes is authored by the app, not by me. in the pull request it reads app/vibedraft-blog-publisher.
six months from now, git log still separates what i wrote from what an agent wrote. you cannot audit a system where the machine's output is indistinguishable from yours.
what this cost
honest accounting, because the automation posts that skip this part are selling something.
- the app itself: about four minutes in a settings page.
- the mechanism: a day of building. most of it went to containment, not to the publishing itself.
- ongoing: nothing. tokens are minted per publish and thrown away.
and what it does not do: it does not decide what to write, it does not publish, and it does not know if the post was any good. it removes the friction between "i have a draft" and "there is a reviewable pull request." that is a real chunk of the week, and it is the chunk i kept losing.
the checklist
before you give any marketing agent write access to anything, answer these five:
- can the credential touch anything beyond this one job? if yes, scope it down until the answer is no, then test that it is actually no.
- is the irreversible action reachable from the agent's tools? if yes, remove it from the tool surface. do not settle for telling the agent not to.
- can i prove what ships is what i approved? if the system re-generates anything after approval, it must compare against the frozen version and refuse on mismatch.
- what happens with no credentials? it must refuse and say why. never degrade, never fall back.
- can i tell six months from now which output was the agent's? if not, fix attribution before you scale it.
if you cannot answer all five, you do not have an agentic marketer. you have an intern with your password and no supervision.
FAQ
is a human approval step useless, then? no. it is useful for judgment, which is what humans are good at: is this the right message, is the timing right, is the claim true. it is unreliable as a security control, which is what the 409,000-decision data measures. use it for taste, not for containment.
why not just give the agent full access and watch the logs? because logs are read after the fact, and the most-missed threat category was scope violations, which look correct in a log. containment has to be structural, before the action, not observational after it.
does this slow the agent down? not measurably. minting a scoped token adds one API call. the pull request step adds a click that you wanted anyway.
what is the smallest version of this i can build today? pick one repetitive marketing task. give the agent a credential scoped to exactly that task, ending in a reviewable artifact rather than a live change. one task, one credential, one human gate.
the thing to take away
the agentic marketer everyone is trying to build is not blocked on model quality. it is blocked on a permission architecture nobody wants to design, because designing it is less fun than the demo.
build the containment first and the agent becomes boring, in the best way. it does real work against a real system, and the worst case is a pull request you close.
this post arrived here that way. i reviewed it and pressed merge.