Replies: 2 comments
A.K., 14 July 2026: what stops a bad file upload
This is the right question to ask about any agentic file manager, so it gets a long answer with the code in it. The short answerThe model never executes anything. It emits a name and a JSON object, and that is the entire extent of its power. Execution happens in the Rust process, which does not trust the model's framing of its own call: it re-derives the classification from the tool name and from the arguments themselves, and for every write class tool it refuses to run unless a grant exists that a human created. So "valid-looking arguments" is precisely the case the design assumes. The arguments are always assumed to be plausible. Plausibility is never what authorises the call. Where the boundary physically issequenceDiagram
participant M as Model (cloud or local)
participant W as WebView (React)
participant R as Rust backend
participant H as Human
participant S as Server / filesystem
M->>W: tool_call: remote_upload {local_path, remote_path}
W->>R: prepare_ai_tool_approval(tool, args)
R->>R: whitelist, schema, path validation
R->>R: classify from tool AND args
R-->>W: approval_required, request_id
W->>R: grant_ai_tool_approval(request_id)
R->>H: native OS dialog, rendering the resolved args
H-->>R: OK or Cancel
R-->>W: grant_id bound to (session, tool, args, connection)
W->>R: execute_ai_tool(tool, args, grant_id)
R->>R: ensure_ai_tool_approval, else hard error
R->>S: only now, the upload happens
The important structural detail is what is missing from that diagram: The layers, in the order a wrong call meets themAll references are on commit
The autonomy modes, since "auto" is the obvious next questionAeroAgent has four modes, and one of them auto-approves everything. That sounds like the answer to your question is "nothing", so here is exactly what each mode moves.
What the modes actually trade is how many confirmations a gated call needs, not whether it needs one. Safe and Normal ask twice for the same call, in the panel and again in the OS dialog. Expert and Extreme ask once. No mode asks zero. The one path to zero confirmations is a session grant the human created earlier: approve a tool with "remember for this session" and matching calls run without asking for the next 8 hours. That is the point of the feature, it is stated in the dialog before you accept, the 11 tools in row 9 above are excluded from it entirely, and Safe mode does not offer it at all. Why "valid-looking" does not buy the model anythingA one shot grant is bound to the arguments, not to the intention. The scope key is the serialised argument set together with the connection identity, so an approval of that kind is not a capability. Approving an upload of A session grant is bound to the tool, not to the arguments, and that is a real widening. The confirmation dialog says which one you are giving ("approve this exact tool plus argument set once" versus "remember this tool for the current chat session"), so it is a disclosed choice rather than a hidden one, but I would rather write it plainly here than let the previous paragraph read as if it covered both cases. It does not. The deny list runs at execution time, after approval, not before it. This is the part people usually get backwards. // src-tauri/src/ai_core/remote_tools.rs, upload_file
if let Some(local_path) = get_str_opt(args, "local_path") {
validate_local_path(&local_path, "local_path")?;
backend.upload(&local_path, &remote_path).awaitThe deny list is:
So for the canonical version of your scenario, an agent talked into exfiltrating an SSH private key, there are two independent stops: the human sees the literal path before anything runs, and even if the human approves it the upload still fails in the tool body. That second stop is the one that survives an inattentive click, an Extreme mode session, and a session grant. The CLI is a separate path, and it carries its own gate
Strict mode exists for the adjacent version of your question: not "what if the model calls the wrong tool", but "what if the model writes the command line". A generated command that smuggles in The MCP surface, where the answer is genuinely differentAeroFTP can also run as an MCP server ( The reason is that a confirmation there would be in the wrong process: the MCP host is the thing with a user in front of it, and asking twice in two different UIs trains people to click through both. So AeroFTP contributes the layers that do not need a human, and the host owns the one that does:
If you wire AeroFTP into an agent host that does not itself prompt for tool calls, you have an agent with unprompted write access to your servers. That is a real configuration and it is worth saying out loud. What this does not defend againstStating the limits, because a threat model without them is marketing. A human who approves without reading. The dialog is the boundary, and a boundary that is clicked through is not one. The design can only make the arguments literal and hard to misread; it cannot make them read. This is why the most dangerous tools cannot be remembered for a session at all: the cost of re-asking is deliberately paid on every occurrence. A compromised WebView. The gate defends against a wrong model, which is your question, and against a hostile one. It is not a defence against an attacker who already runs code inside the renderer: in Expert and Extreme mode the frontend tells the backend that its own approval panel was shown, which suppresses the second OS dialog, and a compromised renderer could lie about that. An attacker at that level already has the user's session, so the honest boundary claim is model versus process, not renderer versus process. The deny list is a deny list. It stops the well known secret locations, not everything a given user considers sensitive. Your own Modes and flags a user can choose. Extreme mode, a session grant, Related readingAeroAgent explained: setup, safety tiers, and free providers and models covers the approval tiers from the user side. The code above is the enforcement behind them. If you see a gap in any of this, I would genuinely like to hear it here rather than by email. Edited 1 September 2026: corrected the claim that grants are always bound to the exact arguments (session grants are bound to the tool), added the autonomy mode table, and added the MCP section, which the first version omitted entirely. |
N., 15 July 2026: does AeroFTP do model routing, fallback, rate limits and per request cost logs
This one arrived as vendor outreach rather than as a user question, and I am quoting only the question and none of the pitch. I am publishing it anyway because it is a fair description of what an AI feature inside a desktop app has to account for, and because the answer is the clearest way to describe how AeroAgent is wired. Point by point, with the honest gaps where there are any.
The part that matters more than the four answersThere is no AeroFTP operated endpoint anywhere in this path. The desktop app builds the request and sends it straight to the base URL configured for the provider. Your API key is stored in the encrypted vault as That is a deliberate design constraint rather than a missing feature. AeroFTP is a local desktop application with no account and no telemetry, and inserting an operator between the user and the model would break that on the one path where the user's file contents are already the payload. Structurally, an intermediary is the thing I am trying not to have. Note where that leaves the routing above: it selects among endpoints you configured, using a classifier that runs on your machine, and no part of the decision leaves it. If you do want a gateway in front of itYou can already put one there, and it needs no change from me. Configure a provider of type Custom with any OpenAI compatible base URL, whether that is a commercial gateway, a self hosted router, LiteLLM, or a local LM Studio or llama.cpp server. AeroAgent will talk to it exactly as it talks to any other provider, and cross provider routing, failover and pooled cost accounting then become properties of the endpoint you chose, under your control and not mine. For anyone reading this thread for the practical version: Ollama gives you the same thing with the cost set to zero and nothing leaving the machine, and discussion 383 lists the free tiers that are worth using. |
Uh oh!
There was an error while loading. Please reload this page.
Some people write to me by email instead of opening an issue or a discussion. The questions are often good ones, and the answer is useful to more than the person who asked, so an answer that lives only in my sent folder is wasted work.
From now on I publish selected email questions here, one comment per message, under these rules.
Answers here point at the actual code, by file and by function, on a named commit. Where a limit exists I state the limit rather than working around it with a reassuring sentence.
If you would rather skip the email step entirely: Q&A for questions, Ideas and Wishlist for suggestions, Issues for bugs. A public thread usually gets you a better answer, and faster, because other people can correct me in it.
This first batch answers two messages from mid-July 2026 that sat unread in a badly filtered inbox. That was my fault, not theirs, and it is fixed.
All reactions