Skip to content

[RFC] Agent-facing scheduling API with non-forgeable provenance #71712

Description

@alonp99

Summary

Document and harden a path for agents (not just operators) to create/modify their own recurring cron jobs at runtime, with non-forgeable provenance captured by the gateway rather than self-reported by the agent.

Today, openclaw cron add is operator-facing and writes ~/.openclaw/cron/jobs.json directly. Agents on the same pod with shell access can also write to that file. There's no documented agent-facing API, no allowlist on what kind of jobs an agent can create, and no provenance system distinguishing "the operator added this" from "the agent added this in response to a prompt-injected email."

Why this matters

The dominant 2026 attack pattern against agentic systems is memory poisoning: prompt-injected content plants instructions that the agent treats as legitimate and recalls in future sessions. A writable, agent-modifiable schedule is the ideal substrate for memory poisoning — the attacker plants once, the agent fires the malicious task on a recurring schedule indefinitely.

References:

  • OWASP AI Agent Security cheat sheet — recommends pod-injected provenance, not self-reported.
  • ICSE'26 AgentSpec: Customizable Runtime Enforcement for Safe and Reliable LLM Agents — strict action allowlists for agent-modifiable surfaces.
  • The "Lethal Trifecta" pattern (private data + untrusted input + exfiltration vector) — schedule poisoning amplifies this from one-shot to persistent.

Operators today either (a) don't let agents schedule anything (loses operational utility) or (b) let them write jobs.json directly (security regression). A documented middle path would benefit the ecosystem.

Proposed surface

An agent-facing tool — exposed by the gateway, NOT by giving agents shell access — that wraps cron creation with the following invariants:

schedule_task({
  name: string,                  // human-readable, agent-controlled
  schedule: ScheduleSpec,        // existing 'every' | 'cron' | 'after' shapes
  playbook: string,              // MUST match a registered playbook (allowlist)
  params?: Record<string, json>, // agent-supplied params; validated against playbook schema
  activeUntil?: string,          // ISO-8601; required if recurring
})

Critical invariants enforced by the gateway, not the agent:

  1. playbook is an allowlisted identifier, not free-form message / steps.
    Playbooks live in operator-shipped config (e.g., ~/.openclaw/playbooks/<name>.md with a declared parameter schema). Agents reference them by name. If the playbook isn't registered, the call is rejected.
  2. createdBy is gateway-injected, not in the request payload. Source is the requesting session's identity (agent ID + session ID). Agents can't forge it.
  3. createdAt is gateway-injected.
  4. activeUntil is required for recurring schedules (matches the sister proposal [Feature] activeUntil / expiresAt for recurring cron jobs #71711). Agents can't create infinitely-recurring tasks.
  5. A configurable per-agent quota limits how many active jobs an agent can hold (e.g., default 5). Prevents an injected agent from grinding the scheduler.
  6. Audit ledger entry for every schedule_task call — the existing openclaw tasks audit surface is a good fit.

An optional enabled: false toggle would let humans disable an agent-scheduled task without removal, preserving the audit trail.

What this isn't

  • Not a full workflow engine — the chaining work in [RFC] Event-driven cron scheduling: job chaining and reactive triggers #28584 covered that direction.
  • Not a replacement for openclaw cron add — operators still get the full unrestricted CLI.
  • Not a permissions overhaul — the existing model (disk access = trust boundary) stays. This proposal is about a second, narrower path that's safe to expose to agents specifically.

Open questions

  1. Should playbooks be versioned (so an agent can't downgrade a playbook to a prior, less-restrictive version)?
  2. Should params be hash-signed by the playbook registration so agents can't tamper post-create?
  3. Where do playbooks live in the workspace hierarchy — alongside hooks, or as a new sibling? Suggest ~/.openclaw/playbooks/ to mirror ~/.openclaw/hooks/.
  4. Should this require a new permission gate (scheduler.write on top of existing tool gates)?

Why open this RFC now

OpenClaw's cron and tasks surfaces are mature; the gap is specifically agent-vs-operator capability separation. Multiple operators are already writing private wrappers around jobs.json to give their agents this capability. Standardizing prevents fragmentation and bakes in security defaults.

Happy to prototype if the maintainers point me at a preferred shape.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.clawsweeper:fix-shape-clearClawSweeper found a clear likely implementation shape for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.staleMarked as stale due to inactivity

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions