Short answer: Yes. Whoever runs the app or MCP server the agent is calling decides which actions are high-risk, sending a payment for example, and flags those actions in AgentAdmit as confirm each time. From then on, every time the agent tries one of those actions, the call is refused until the user confirms that exact action with a passkey on a page only the human can complete. The agent keeps its token and the rest of the grant works as before. It just cannot finish that one action on its own.
Why isn’t a valid grant enough for some actions?
A grant answers “what may this agent reach, for how long.” It does not answer “should this specific transfer go out right now.” An agent with a payments scope on a 30-day connection can send a payment on day one and on day twenty-nine, and both calls look identical to the server. That is fine for reading a workout log. It is not fine for moving money, deleting records, or emailing a customer list.
The usual fix is to make the agent ask. The agent shows a dialog, the user clicks yes, the agent proceeds. The problem is where that dialog lives. It runs inside the agent’s own process, so anything that can steer the agent can also produce the “yes”: a planning error, an injected instruction, a tool result that looks like a user reply. A confirmation the agent can satisfy by itself is not a confirmation.
How does confirm each time work?
The app or MCP server operator sets one flag on the scope when registering it with AgentAdmit: confirm_each_time: true. From then on, the check runs inside the same verification call the app already makes on every request. Four steps.
- The agent calls, verification refuses. The app passes the scope being used, the method, the endpoint, and a digest of the request body. AgentAdmit answers that the token is valid but this call needs confirmation, and it stages an action session bound to exactly those values.
- The app relays the link, and tells the user itself. The agent receives a 403 with a confirmation URL and shows it to the user. The URL is for the human, not for the agent. The app should not depend on the agent to pass it along. When the refusal comes back, the app can notify the user directly. TrainerTracer, the first app running AgentAdmit in production, does this: the refusal creates an in-app notification and a push, and its Agent Access page lists the pending action with a Review button, so the user learns about a waiting action even if the agent never mentions it.
- The human confirms. The hosted page shows the app’s name, the agent’s label, the scope, the method and endpoint, the request digest, and the app’s plain-language summary such as “Pay Alex $50”. The user confirms with a user-verified passkey (Face ID, Touch ID, or a security key). The signing challenge is a cryptographic commitment to that exact action, built only from the values the server stored when it refused the call. The session expires 15 minutes after it is staged.
- The agent retries. Same call, plus the attestation id from the refusal. Verification consumes it atomically, once. A second retry with the same id is refused again with a fresh session.
Nothing in that flow widens the grant. Only a scope the user already granted on an active connection can be staged. A confirmation is not a permission; it is permission to run one call the user already authorized in principle.
What does the user actually sign?
The passkey challenge is a SHA-256 commitment over the connection, the scope, the method, the endpoint, the request digest, and the summary. The claim this supports is narrow and worth stating precisely: a user-verified passkey ceremony signed a commitment to the exact action shown. It is not proof that the user read the screen, and on a phone passkey it is not hardware attestation, and the record says so honestly. Apps that need more set the trusted tier: the ceremony then requires a hardware security key with attestation checked against the FIDO Metadata Service, and an ordinary phone passkey does not qualify. Either way it is a record that a person, holding the credential they enrolled, approved these bytes.
That record lands in two places. The refusal and the retry are both rows in the per-call audit trail, which is hash-chained on the server. The ceremony itself appends a presence event to the consent ledger, with the tier the app required and an honest assurance record. On the consumer tier an export can answer “was a human present for this call” without trusting the agent’s own log. On the trusted tier it also answers what signed: a hardware security key, its attestation format, and its make and model as registered with the FIDO Metadata Service.
When should an app or MCP server operator use it, and when not?
Use it for actions that are irreversible or leave the building: money movement, deletions, anything the agent would send, post, or publish, production deploys, privilege changes. Those are the calls where a fresh human decision is worth 15 seconds.
Do not use it for bounded routine work. If the concern is “how many times” rather than “which one,” the right tool is a call ceiling the user sets at the ceremony. Reading a calendar 200 times a day should never fire 200 prompts. A gate that fires on everything trains people to click yes. Confirm each time is meant to be rare, specific, and out of band.
The app can also stage a confirmation before the agent attempts the call, so the human approves first and the agent’s request goes straight through. A pending session for the same action is reused rather than minted twice, so a retrying agent does not create one ceremony per attempt.
Where is it running today?
Confirm each time shipped on September 15, 2026, in the hosted service and in all six server SDKs. TrainerTracer, the first production integration of AgentAdmit, uses it on agent-initiated payments to trainers: the client’s own AI agent, whichever one they connected, can prepare the payment, but the client approves that exact payment on their phone before it goes out. The flow is identical under test keys, so an integration can run it end to end before go-live.
FAQ: confirm each time for AI agents
Does confirm each time replace scopes and durations?
No. It sits on top of them. The user still grants scopes for a duration with optional call ceilings. Confirm each time adds a per-call human decision to the scopes the operator flags, inside that grant.
Can the agent complete the confirmation itself?
No. The confirmation happens on AgentAdmit’s hosted page with a user-verified passkey. The agent can carry the link to the user and retry after the user confirms, but it has no way to produce the signature.
What happens if the agent changes the request after the user confirmed?
The retry is refused. The attestation is bound to the scope, method, endpoint, request digest, and summary the user saw. If any of those differ, verification reports an action mismatch and stages a fresh session.
Does a confirmation cover more than one call?
No. Each confirmation is consumed exactly once. The next call on the same scope needs a new confirmation.
Is this a per-call prompt on every action?
No. It applies only to scopes the operator flags, and only when the app declares which scope a call uses. Everything else runs on the standing grant and its ceilings.
Read the integration details in the App Owner Guide or the MCP Server Operator Guide, or start with test keys at agentadmit.com.
Related reading: Should an AI agent ever hold its own authority? | Can an AI agent approve its own permission request? | Prompt injection is an authorization problem, not just a model problem