Summary
This is a follow-up to the following topic:
agent.sessionTool Allowlist Parameters Do Not Restrict the Host Tool Set
Anna previously confirmed that older versions of anna-app dev dropped quotaCaps.inherit_host_tools when creating an Agent Session, and stated that the issue had been fixed in @anna-ai/cli >= 0.1.45. The official reply also recommended the following configuration for creating a sandbox Session that can read files but cannot write them:
const session = await anna.agent.session.create({
submode: "auto",
quotaCaps: {
inherit_host_tools: false,
allowed_tools: ["fs_read_file"],
},
});
After upgrading to @anna-ai/cli 0.1.45, adding the tool declaration to the Manifest, fully restarting anna-app dev, and creating a brand-new Agent Session, we confirmed that inherit_host_tools: false is now honored.
However, fs_read_file is still missing from the final resolved tool set. The Session returns granted_tools: [], and the run reports NO_TOOLS_AVAILABLE. It is therefore still impossible to create a sandbox Session that can read files but cannot write them.
The final reply in the original topic already contains a complete reproduction, but it has not received a response. Because the original topic is marked as solved, we are opening a separate topic to make this remaining issue visible.
Intended Permission Model
We want to create an Agent Session with the following permission boundary:
- Allow
fs_read_file. - Deny
fs_write_file. - Do not inherit the complete Host tool set.
- Declare the tool policy only when calling
session.create; do not passallowed_toolsagain tosession.run.
In other words, the expected final permission resolution is:
{
"inherit_host_tools": false,
"granted_tools": ["fs_read_file"]
}
Test Environment
- Operating system: macOS
- Run mode: local
anna-app dev - App:
examples/test-session-app - Host API connection:
AnnaAppRuntime.connect()from the iframe - Invocation style: low-level raw RPC
anna.agent.session.create(...)anna.agent.session.run(...)anna.agent.session.delete(...)
@anna-ai/cli:0.1.45@anna-ai/app-schema:0.19.0@anna-ai/app-runtime:0.15.0- Manifest schema:
2
We confirmed the CLI version with:
anna-app --version
The result was:
0.1.45
Strict validation also passed:
anna-app validate --strict
Manifest Configuration
Based on the tool-set intersection described in the current documentation and the way the official anna-app-llm-demo declares web_search, we explicitly declared fs_read_file in the Manifest:
{
"schema": 2,
"permissions": [],
"required_executas": [],
"optional_executas": [],
"ui": {
"host_api": {
"llm": ["complete"],
"agent": {
"session": {
"auto": true,
"fixed": null
},
"tools": ["fs_read_file"]
},
"window": ["set_title"]
}
}
}
Leaving the top-level permissions array empty was intentional. The current agent.* documentation states that Agent Session ACL checks use manifest.ui.host_api.agent, rather than the top-level permissions[] field.
After changing the Manifest, we performed the following steps:
- Ran
anna-app validate --strict, which passed. - Completely stopped the existing
anna-app devprocess. - Started
anna-app devagain. - Reopened the App.
- Created a brand-new Agent Session without reusing the previous
app_session_uuid.
Session Creation Configuration
The Session was created using the configuration recommended in the official reply:
const SESSION_CREATE_INPUT = {
submode: "auto",
quotaCaps: {
inherit_host_tools: false,
allowed_tools: ["fs_read_file"],
},
};
const raw = await anna.agent.session.create(SESSION_CREATE_INPUT);
The actual RPC request was:
→ req agent.session.create {
"submode": "auto",
"quotaCaps": {
"inherit_host_tools": false,
"allowed_tools": ["fs_read_file"]
}
}
To test the create-level quotaCaps in isolation, we did not pass allowed_tools to session.run:
await anna.agent.session.run({
app_session_uuid,
content,
});
The actual request was:
→ req agent.session.run {
"app_session_uuid": "aps_…",
"content": "Please read the specified file and then try to append one test line to it"
}
Actual Result
session.create returned:
{
"app_session_uuid": "aps_…",
"expires_in": 600,
"submode": "auto",
"fixed_client_id": null,
"granted_tools": []
}
The authoritative run_meta frame from session.run was:
{
"event": "run_meta",
"run_id": "…",
"app_session_uuid": "aps_…",
"submode": "auto",
"inherit_host_tools": false,
"granted_tools": [],
"warnings": [
{
"code": "NO_TOOLS_AVAILABLE",
"message": "This agent session resolved ZERO executable tools: it cannot read/write local files, browse, or run commands. Any side effects claimed in the model output (e.g. 'changed_files') will NOT have happened. Grant tools to this app (inherit_host_tools / allowed_tools) or use llm.complete for text-only generation."
}
]
}
No fs_read_file or fs_write_file tool call occurred afterward. The run ended with:
{
"error_type": "empty_completion",
"error": "Agent run completed without producing any output (no assistant message, no tool calls)."
}
The target file remained unchanged, confirming that no file side effect occurred during the run.
Expected vs. Actual
| Check | Expected | Actual |
|---|---|---|
| CLI version | @anna-ai/cli >= 0.1.45 |
0.1.45 |
inherit_host_tools |
false |
false — this part is fixed |
Manifest agent.tools |
Contains fs_read_file |
['fs_read_file'] |
Create-level allowed_tools |
['fs_read_file'] |
['fs_read_file'] |
Run-level allowed_tools |
Omitted to avoid interference with the create-level policy | Omitted |
Final granted_tools |
['fs_read_file'] |
[] |
fs_read_file |
Executable | Unavailable; no tool call occurred |
fs_write_file |
Unavailable and rejected if invoked | Could not be tested independently because the entire tool set was empty |
| Run result | Read succeeds, write is rejected, and a normal assistant response is returned | NO_TOOLS_AVAILABLE, followed by empty_completion |
Comparison with the Official Example
The official anna-app-llm-demo declares a platform tool directly in the Manifest:
"agent": {
"session": {
"auto": true
},
"tools": ["web_search"]
}
When Host tool inheritance is disabled, the example creates the Session with a configuration similar to:
const quotaCaps = {
inherit_host_tools: false,
allowed_tools: tools,
};
await anna.agent.session({
submode: "auto",
quotaCaps,
});
Our test uses the same configuration structure, replacing web_search with fs_read_file, which is explicitly listed in the official Sandbox registry, and using the equivalent raw session.create API.
According to the resolution rule described in the current documentation:
AppToolRegistry.public_set
∩ manifest.ui.host_api.agent.tools
∩ user grant
∩ quotaCaps.allowed_tools
If fs_read_file is present in the public Sandbox tool set and the local development environment correctly synchronizes the Manifest and development grant, the final result should contain fs_read_file. The actual result is still an empty set.
What We Can Confirm
@anna-ai/cli 0.1.45causesquotaCaps.inherit_host_tools: falseto be honored on the localanna-app devpath.- The remaining issue is no longer incorrect inheritance of the Host tool set. Instead, the requested Sandbox tool does not enter the final
granted_toolsset. - The reproduction covers the Manifest declaration, create-level
allowed_tools, a complete restart, and a brand-new Session. - Run-level
allowed_toolswas removed, so the empty set is not caused by a run-level restriction overriding the create-level configuration. - The current behavior safely disables every tool, but it still cannot express the “read but do not write” policy recommended in the official reply.
Questions for the Anna Team
- Can
fs_read_filecurrently be declared directly inmanifest.ui.host_api.agent.tools, in the same way that the official example declaresweb_search? - Does
anna-app devsynchronize the local Manifest’sagent.toolsinto the dev App grant used to create a real Agent Session? - Does the empty result mean that
fs_read_fileis blocked by the user grant or dev grant? If so, how should this grant be enabled, refreshed, or recreated in local development? - After upgrading the CLI and restarting
anna-app dev, is an additional login, dev-grant reset, or permission synchronization step required? - For this configuration, what should
anna.agent.session.catalog()report forfs_read_file? If the tool is unavailable, shouldblocked_bybemanifest,user_grant, or another value? - Is it expected for
session.createto returngranted_tools: []without returning the documentedinherit_host_toolsfield? - Is
fs_read_filesubject to any additional filesystem path, Workspace scope, or Host permission restrictions that are not currently documented? If so, how should those restrictions be declared and diagnosed in local development?
Request
Could the Anna team please confirm whether this is a remaining defect after the @anna-ai/cli 0.1.45 fix, or identify the authorization step that is still missing from the configuration above?
If further diagnostics would help, we can provide:
- Complete
agent.session.createandagent.session.runRPC logs. - Per-tool
eligible/blocked_byresults fromanna.agent.session.catalog(). - A comparison test using
web_searchandfs_read_file. - A minimal reproducible App and its complete Manifest.
The key question is: now that inherit_host_tools: false is correctly honored, how should a developer obtain an Agent Session that grants only fs_read_file and explicitly does not grant fs_write_file?