fix(kanban): redact the card body in kanban_create before persisting - #92366
liuhao1024 wants to merge 2 commits into
Conversation
kanban_create was the only one of the five kanban write paths that skipped redact_sensitive_text: _handle_create passed the body straight into create_task, so a credential pasted into a card body persisted in plaintext in the board's SQLite (and board DBs are routinely snapshotted). Mirror the _handle_comment contract — force=True redaction at the tool boundary; secret-free text passes through unchanged. Fixes NousResearch#92354
|
The single e2e failure on this PR is a known flaky test, unrelated to this change: Failed test: Why it can't be this PR: the change touches only Known-flake evidence: this exact signature ( All checks relevant to this diff pass locally: |
Reviewed What's good
Suggestions
Correct, focused security fix. |
…n listings Review follow-up on NousResearch#92354: the body fix left titles persisting verbatim, and titles are the MORE visible free text (board listings, dispatcher logs, notifications). Same force=True contract; task dispatch keys off the task id, not the title, so matching heuristics are unaffected.
What does this PR do?
kanban_createwas the only one of the five kanban write paths that persisted free text verbatim:_handle_createpassedbodystraight intocreate_task(...), while_handle_comment,_handle_complete,_handle_block, and the review path all callredact_sensitive_text(..., force=True)first. A credential pasted into a card body (e.g. an API key a worker needs to complete the task) therefore landed in plaintext in the board'skanban.db— and board SQLite files are routinely snapshotted/backed up, widening exposure.This PR mirrors the
_handle_commentcontract at the_handle_createboundary: the body is run throughredact_sensitive_text(str(body), force=True)before the DB write. Secret-free text passes through unchanged, so normal task descriptions are unaffected.Related Issue
Fixes #92354
Type of Change
Changes Made
tools/kanban_tools.py—_handle_create: redact the cardbody(force=True) before persisting, closing the one write path that skippedredact_sensitive_text([Bug]: kanban_create body skips redact_sensitive_text — only write path of 5 that persists secrets in plaintext #92354).tests/tools/test_kanban_redaction.py— two regression tests: ansk-…key in a created body reads back masked (head/tail preserved) and a secret-free body passes through byte-for-byte.How to Test
pytest tests/tools/test_kanban_redaction.py -q— 7 passed (5 pre-existing + 2 new). Observed result:test_kanban_create_body_scrubbed_api_keyfails on unpatchedmain(the secret reads back verbatim) and passes with this change.pytest tests/tools/test_kanban_tools.py -q— 32 passed, no regressions on the rest of the create path (validation, parents, tenant, session stamping).Checklist
Code
fix(scope):,feat(scope):, etc.)create_taskbody path this PR fixes)pytest tests/ -qand all tests pass (relevant suites:tests/tools/test_kanban_redaction.py,tests/tools/test_kanban_tools.py)Documentation & Housekeeping
docs/, docstrings) — N/A (inline comment names the contract and the issue)cli-config.yaml.exampleif I added/changed config keys — N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows — N/AScreenshots / Logs
N/A — DB assertions in the regression tests cover the persisted shape.