·7 min read·Ofir, Marshal Team

Who Approves When Nobody's Watching? Human-in-the-Loop for Headless AI Agents

Headless AI agent approval, done right: the prompt built for a human at the keyboard has nobody to ask. Pre-declared grants and escalation that fails closed.

A coding agent that runs on a schedule, triggered by an event, with nobody at the keyboard, is autonomy without a witness. OWASP's Top 10 for LLM Applications files the underlying risk under Excessive Agency: granting an agent capability, autonomy or permissions beyond what the job needs, then letting it act without a human confirming the consequential steps. A headless agent is that risk stripped to its essentials, because the person who would normally confirm the alarming step is gone by design.

Interactive agents come with a safety valve, even if nobody designed it as one: a person is watching the terminal. When the agent proposes something alarming, a human is there to say no. That person is the real approval mechanism, and the dialog box is just how they express it.

Headless agents remove the person. They are triggered by a ticket, a cron schedule, a chat message or an API call, and they run to completion with no one watching. The approval prompt that worked interactively now has nobody to ask. So in practice it does one of two things: it blocks forever, and the automation you built never finishes, or someone switches it off to make the automation work, and the control is gone.

Neither outcome is governance. Governing a headless agent means designing for the absent human from the start.

Four trigger sources (ticket, cron, chat, API) in purple feed an amber dashed pre-declared grants panel that escalates to a human for live takeover, then reaches destinations, with an audit strip tying every action back to the trigger that started the run

Headless agents are already running in your org

This is not a forward-looking scenario. Teams want headless agents because the work is real: an agent that picks up an on-call ticket and triages it, one that opens dependency-update pull requests overnight, one that works through a backlog of small, well-specified tasks while everyone sleeps.

The triggers are the giveaway. An agent wired to a ticket queue, a schedule, a chat command or a webhook is, by definition, running without a human watching each step. The value is exactly that nobody has to babysit it. That same property is what makes the interactive safety valve useless.

Interactive approvals do not translate to headless runs

An approval prompt assumes three things: that a person is present, that they have the context to decide, and that they will decide quickly. A headless run breaks all three.

There is no person present, so the prompt has no audience. Even if a notification is sent somewhere, the recipient usually lacks the live context the terminal gave an interactive user. And the run cannot wait indefinitely for an answer without defeating its purpose. The predictable result is the one every platform team has seen: approvals get disabled for headless jobs because leaving them on means the jobs hang. The control is removed precisely where the agent is least supervised.

Pre-declare what the run may do, before it starts

The move that works is to stop treating approval as something that happens during the run, and make it something that happens before it.

Before a headless run starts, declare what it is allowed to do: which credentials it may use, which destinations it may reach, which verbs it may run, scoped to the specific task and the specific targets that task needs. The grant is brokered and bounded, not a standing set of permissions the agent carries around. When the run executes, it operates inside that envelope, and anything outside it is denied by default rather than waved through because no one answered.

This is where Marshal's Deputies fit, at the level the public site describes: a Deputy is a governed headless agent that runs from a trigger with pre-declared, brokered grants scoped to its task, rather than inheriting a developer's full access.

Scope to the task, not to the role

The reason pre-declaration works is that a headless task is usually narrow and knowable in advance. A dependency-update run needs to read the repo, open a branch and a pull request, and nothing else. Declaring that envelope up front is both easy and tight. Contrast it with the interactive habit of running as the developer's full identity, which hands a narrow task the reach of an entire person.

Escalation has to fail closed

A pre-declared envelope raises an obvious question: what happens when the agent legitimately needs something it was not granted?

The wrong answer is to let it proceed, or to pop a prompt that nobody will answer and call it oversight. The right answer is that the run stops and asks, and stays stopped until a person responds. The agent does not improvise around the missing grant. It surfaces the request, with the context of what it was doing and why, to someone who can decide, and a human can step in and take over the live session if the situation warrants it.

Failing closed is the whole point. An interactive agent that hits a wall has a person right there to lower it. A headless agent that hits a wall must treat "no answer" as "no," not as "go ahead."

Audit has to tie every action back to the trigger

The last piece is reconstruction. When a headless run acted on a ticket at 3am, you need to be able to answer, later, exactly what it did and why.

That means every action the run took is recorded and traceable to the event that started it. A write to a repository links back to the ticket that triggered the run. An outbound request links back to the task that justified it. Without that thread, a headless agent's work is a set of changes with no author and no cause, which is unreviewable and, in a regulated environment, unacceptable. With it, an unattended run becomes as auditable as a reviewed pull request.

Where to start

Begin with the runs that are easy to reason about: low-risk, scheduled tasks on a fixed cadence, where the envelope is obvious and the blast radius is small. Learn what the agent actually reaches for. Widen from there. Save event-triggered runs that act on untrusted input, a public ticket, an inbound email, for last, because that is where a malicious instruction can ride in on the trigger itself, and where your pre-declared envelope and fail-closed escalation have to be tightest.


Headless agents are useful exactly because no one is watching them, which is also what makes the interactive approval prompt worthless for them. The answer is not a better prompt. It is to pre-declare what a run may do before it starts, deny anything outside that envelope, fail closed to a human when the agent needs more, and tie every action back to the trigger that caused it. Approval moves from a dialog during the run to a decision made before it.

For the containment side of the same problem, see the incident-response runbook for agent sessions →


Marshal runs headless agents with pre-declared, brokered grants, escalation to a live human when a run needs more, and every action traced back to its trigger. Book a demo →

securityai-agentsplatform-engineeringgovernance

Marshal runs AI agent sessions in isolated Kubernetes pods: credential isolation, audited egress, per-verb tool policy.

Book a demo →