Skip to content

[SEC-A-09] Agent HTTP server defaults to TokenScope::Full with no CLI flag #311

@intendednull

Description

@intendednull

Audit finding from #300 (commit 679f9fe)

Severity: medium
Category: auth / authorization defaults
File: crates/agent/src/main.rs:155
Obvious fix: yes

Description

serve_http(client, &cli.bind, Default::default(), token) passes TokenScope::default() which is TokenScope::Full — every tool (kick_member, create_server, delete_message, …) is reachable from any client that holds the bearer token. There is no --scope flag exposed in Cli, so an operator deploying the HTTP transport has no way to restrict to e.g. Messaging or ReadOnly short of editing the binary.

Impact / Threat

Operators reasonably assume "default = least privilege"; in fact default = full admin. Combined with SEC-A-01 (timing-attackable token compare) and SEC-A-08 (world-readable identity), the blast radius of any one compromise is the entire agent identity's authority on the server.

Suggested fix

Add --scope readonly|messaging|full|admin (default messaging or readonly) to Cli, parse into TokenScope, pass through. Document the per-scope tool list.

Verify

rg -n "Default::default\(\)" crates/agent/src/main.rs

Resolved by #389 (merged 2026-04-26): adds --scope {messaging,read,full} clap flag, default Messaging, threaded into serve_http. Auto-close keyword chain (closes #301 #304 #305 #311) only fired for the first id, leaving this issue stuck open. Manually closing now.

admin CLI variant + regression test pinning the default were proposed in #412 but the maintainer chose to drop the increment. PR #412 closed.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions