The kata close substance-and-evidence gate (introduced in #32) has an
escape hatch for the TUI: when the close request carries
source: "tui" and reason: "done", the daemon skips
ValidateCloseInput and evidence validation. The intent is that
pressing x in kata tui doesn't force the user to type a 40-char
message and attach typed evidence for an interactive close.
The problem
source is just a string on the JSON request body. Any HTTP client
that can reach the daemon can POST
POST /api/v1/projects/{id}/issues/{ref}/actions/close
{"actor": "agent", "source": "tui", "reason": "done"}
and close the issue with no message and no evidence, bypassing the
anti-abuse policy that the rest of kata close enforces. In the
current no-auth model, the daemon has no trustworthy way to
distinguish a real interactive TUI caller from a forged one.
Options
- Transport gate. Refuse
source=tui when the connection arrives
over TCP; honor it only on the local Unix socket. Closes the spoof
vector against any remote attacker but breaks the keystroke bypass
for legitimate remote-TUI users (they would have to fall back to
kata close --done --message ... from the CLI).
- Drop the bypass. Require
--message and --evidence from every
close caller, including the TUI. The x key would prompt for a
one-line message. More friction for humans, no policy hole.
- Wait for auth/session identity. Derive "interactive UI session"
trust from an authenticated principal rather than a self-declared
JSON field. The proper long-term fix once kata grows real
authentication.
Interim mitigation
Persist source on the issue.closed event payload so
kata audit closes can flag and filter bypass closes. This isn't a
guard, but it makes abuse visible to reviewers.
Flagged by an automated security review on the PR that introduced the
gate (#32). Deferred from that PR.
The
kata closesubstance-and-evidence gate (introduced in #32) has anescape hatch for the TUI: when the close request carries
source: "tui"andreason: "done", the daemon skipsValidateCloseInputand evidence validation. The intent is thatpressing
xinkata tuidoesn't force the user to type a 40-charmessage and attach typed evidence for an interactive close.
The problem
sourceis just a string on the JSON request body. Any HTTP clientthat can reach the daemon can POST
and close the issue with no message and no evidence, bypassing the
anti-abuse policy that the rest of
kata closeenforces. In thecurrent no-auth model, the daemon has no trustworthy way to
distinguish a real interactive TUI caller from a forged one.
Options
source=tuiwhen the connection arrivesover TCP; honor it only on the local Unix socket. Closes the spoof
vector against any remote attacker but breaks the keystroke bypass
for legitimate remote-TUI users (they would have to fall back to
kata close --done --message ...from the CLI).--messageand--evidencefrom everyclose caller, including the TUI. The
xkey would prompt for aone-line message. More friction for humans, no policy hole.
trust from an authenticated principal rather than a self-declared
JSON field. The proper long-term fix once kata grows real
authentication.
Interim mitigation
Persist
sourceon theissue.closedevent payload sokata audit closescan flag and filter bypass closes. This isn't aguard, but it makes abuse visible to reviewers.
Flagged by an automated security review on the PR that introduced the
gate (#32). Deferred from that PR.