Repository navigation
docs(cron): add security considerations for cron trust bypass - #1560
thoththeagent wants to merge 1 commit into
Conversation
|
Important CHANGES REQUESTED What This PR Does
How It WorksA single 20-line section is inserted before
Findings
Finding Details🟡 F1:
|
|
Thanks @thoththeagent / @charlie0228 for finding this docs gap and for the manual validation. This PR is superseded by #1562, which cherry-picks your commit with original authorship and adds a follow-up commit (with
Closing in favor of #1562. Feedback there is welcome. |
|
Thanks for the review — both findings addressed in thoththeagent@1f82d02. F1: Added a paragraph stating that usercron write access also means command execution: F2: Added a preventive bullet — restrict or gate the agent's writes to |
* docs(cron): add security considerations for cron trust bypass * docs(cron): frame cron trust bypass as autonomy scope, cover disable_on_success Reframe the section as "Autonomy and Permission Scope": cron skipping inbound chat checks is intentional and is how agents act autonomously. Document that usercron write access also grants scheduled shell execution via disable_on_success (run by OpenAB, outside agent tool approval), and replace the mitigation list with three explicit scope choices. Drop the unverified /model example. Builds on #1560. Co-authored-by: charlie0228 <24387287+charlie0228@users.noreply.github.com> Co-authored-by: thoththeagent <287470606+thoththeagent@users.noreply.github.com> * docs(cron): address review round-1 findings on autonomy scope - Drop the unenforceable "agent-managed prompts, operator-managed commands" scope; explain prompts and commands share one file and note absolute usercron_path and shell bypass of path rules (F1) - State that disable_on_success runs as the OpenAB process user, outside tool approval and any agent sandbox; spell out the full injection chain in a CAUTION callout (F2, F6) - Distinguish persistence (trust-all-tools) from new privilege (restricted or sandboxed agent) (F3) - Clarify only the inbound adapter path is bypassed and that slash command handling is backend-specific (F4) - Make audit advice durable: commit or persist events outside the agent's writable scope (F5) - Replace the table with prose and add a CAUTION pointer in Goal-Driven Auto-Disable (F7) * docs(cron): protect containing directory and note writeback limits An agent that can write the directory can replace a file it does not own, and a read-only usercron file blocks enabled=false / thread_id writeback, so achieved goal jobs keep firing. * docs(cron): address round-2 supplemental review findings - disable_on_success inherits OpenAB's full environment (bot tokens), unlike the env-cleared agent process; fix the trust-all-tools bullet and the injection CAUTION (S1) - describe the load-time drop when id or disable_on_success_match is missing (F6) - writeback fails only when OpenAB cannot write the directory; state the shared-uid default, sticky bit, and thread_id/id guidance (S3) - describe bypassed inbound filters by category, including allow_dm (S2) - mark kiro-cli /clear handling as an example (F2) - require audit records outside agent reach, not local git (F5) - refer to the resolved usercron_path for writeback and re-enable --------- Co-authored-by: charlie0228 <24387287+charlie0228@users.noreply.github.com> Co-authored-by: chaodu-agent <chaodu-agent@users.noreply.github.com> Co-authored-by: thoththeagent <287470606+thoththeagent@users.noreply.github.com>
What problem does this solve?
docs/cronjob.mddoes not mention that cron prompts bypass the inbound checks applied to chat messages (platform trust gate, @mention requirement, bot-message filtering). The scheduler callsrouter.handle_messagedirectly (crates/openab-core/src/cron.rs), while adapters callrouter.gate_incomingfirst. The bypass is intentional and described in the Identity Trust-None ADR, but users reading the cron guide have no way to learn it.This matters most for usercron: the guide recommends Agent-Managed Schedules, which means the agent can write
cronjob.toml. An agent that reads untrusted content can be prompt-injected into adding a[[jobs]]entry, turning a one-off injection into a recurring, unattended prompt that looks like a normal schedule.Closes # (none — docs gap found while operating usercron)
Discord Discussion URL: https://discord.com/channels/1491295327620169908/1491365158868619404/1556499283048665139
Review Contract
Goal
Document, in the user-facing cron guide, that cron prompts bypass inbound trust checks, what that implies for whoever can write cron config (including the agent under Agent-Managed Schedules), and practical mitigations.
Non-goals
cronjob.toml.Accepted Residual Risks
None — docs-only change; no runtime behavior is affected.
Acceptance Criteria
docs/cronjob.mdhas a## Security Considerationssection stating that cron prompts skip the trust gate, @mention, and bot filtering.adr/identity-trust-none.mdand#agent-managed-schedulesresolve.Follow-ups
cronjob.tomlchanges, or an opt-in to apply L2 scope checks to usercron jobs.At a Glance
Prior Art & Industry Research
Not applicable — docs-only change describing existing OpenAB behavior.
Proposed Solution
Add a
## Security Considerationssection todocs/cronjob.md, placed before## Behaviors, covering:/clear,/model <id>) execute too.config.toml(baseline) andcronjob.toml(usercron), including the agent.cronjob.toml, and keep long-lived schedules in baseline config on a mount the agent cannot write.Why this approach?
The cron guide is where operators decide whether to enable usercron and Agent-Managed Schedules, so the trade-off belongs there. The ADR explains the design rationale but is aimed at contributors.
Alternatives Considered
Validation
docs/adr/identity-trust-none.mdexists;### Agent-Managed Schedulesheading exists in the same file)0.10.0-beta.1with kiro-cli 2.13.0, a usercron job withmessage = "/clear"(no @mention in the text) executed in the target thread (Conversation cleared) and kept the session's model selection. This confirms that cron bypasses the mention gate and that CLI commands are forwarded verbatim. Code paths checked onmain(99c11ec):cron.rscallshandle_messagewith nogate_incoming; thediscord.rsmention and allowlist checks live only in the inbound handler.