Skip to content

Expose plugin approval APIs needed by external HITL plugins #82336

Description

@Guardiola31337

Summary

External HITL plugins need one narrow host-owned approval seam so they can gate a protected tool call on an external verification ceremony while OpenClaw retains ownership of approval identity, reviewer authorization, timeout, denial, cancellation, retry generations, run ownership, durable audit state, and the final allow/deny decision.

Kevin accepted RFC #15 as a design RFC with runtime behavior proof remaining an implementation requirement tracked here.

Accepted contract

  • A plugin requests external verification from before_tool_call, including the verifier id and allow decisions available for that exact invocation.
  • OpenClaw host-stamps and persists the approval, external attempt, retry generation, originating plugin/verifier/run, authenticated requester/reviewer, and selected decision.
  • A plugin-scoped verifier receives only its host-bound attempt capability and may complete only that attempt.
  • Generic approval resolution is deny-only while external verification is required.
  • Attempt setup and presentation are immutable within a generation; retry creates a fresh generation, and stale native actions return current state instead of replaying an obsolete challenge.
  • Terminal resolution is first-answer-wins. Timeout, denial, cancellation, restart recovery, and verifier completion cannot overwrite one another.
  • Durable history is proof-free. Verification proofs and RP signing secrets are not persisted.
  • Reusable grants are plugin-owned but narrowly bounded by declared tool/session scope and lifecycle.

Invocation-time policy

The plugin classifies each actual invocation from hook context. It can request no gate, expose only allow-once, or expose allow-once plus exact-session trust. This supports green/yellow/red policy and context-sensitive escalation such as forcing a fresh ceremony for the first message to a new external recipient. Core does not own those zones. After registration, the host-bound selected decision is fixed and the verifier cannot widen it during completion.

User experience

Rich clients use host-native actions:

  • Verify once
  • Verify and trust
  • Deny

The TUI focuses Deny by default, Escape dismisses without silently denying, failed setup permits a fresh retry, and QR/link presentation follows the selected action. Text-only clients retain canonical command fallbacks.

Explicit non-goals

  • No World-specific verification or signing logic in OpenClaw core.
  • No arbitrary plugin-defined native action framework.
  • No broad public resolver that allows a plugin to resolve another plugin's approval.
  • No generic allow path that bypasses the external verifier.
  • No persistence of World proofs or RP signing keys.

Acceptance criteria

  • OpenClaw owns pending approvals, host-bound attempts, reviewer authorization, timeout, denial, cancellation, and final resolution.
  • Generic allow decisions are rejected for approvals requiring external verification.
  • A verifier can complete only its exact originating plugin/run/attempt/generation and only with a declared decision.
  • Retry, replay, concurrent dispatch, late completion, and terminal races are deterministic and fail closed.
  • The rich TUI presents native Verify once / Verify and trust / Deny actions with a safe default; text-only clients degrade safely.
  • AgentKit demonstrates denial, one-shot verification, scoped grant reuse/revocation, retry, concurrency/isolation, cancellation, and signed delegation against the host API.
  • The actual TUI → Codex hook → AgentKit → Gateway protected-tool path is exercised without duplicate generic approval UI.
  • Complete a successful physical World App QR ceremony against production relying-party infrastructure.
  • Land the core and AgentKit implementation PRs.

Current proof status

Current heads:

  • Core: d0bb8a7b6a1866742dfc495ef653b45fbab73dfa
  • AgentKit: cd2ea14a1b38b780fa284bebccf13527f2d4c796

The successful physical run used core runtime e60c763df2d and AgentKit runtime 8a1e5c45b57; the current heads add only a core PTY test-helper split and AgentKit manual-proof documentation.

Redacted physical result:

prompt: use shell to run printf agentkit-rfc15-final-physical-ok
TUI: Deny-focused selector -> Verify once
World App: Agent Kit OpenClaw -> Human + Unique Human -> Continue -> Congratulations
TUI result: agentkit-rfc15-final-physical-ok
ledger: allow-once | succeeded | plugin-completion | completion_applied=1 | resolver_plugin_id=agentkit

The production ceremony used an isolated real OpenClaw Gateway/TUI, actual Codex PreToolUse path, source AgentKit plugin, local production RP signing, a connected Pixel 3, and production World App. No credential or proof was printed, committed, or pushed.

Stress proof covers stale/expired failure, fresh retry, Verify and trust, same-session reuse, cross-session isolation, Deny, Escape/reconnect, late completion, concurrent attempts, signed pinned-TLS delegation, unsigned rejection, graceful shutdown, and a stacked stale World sheet that never authorized the current attempt.

Automated proof includes a 96-test focused current-head core matrix, a 28-test real terminal PTY lane, the full build with 142 plugin SDK declaration paths, AgentKit human/delegation E2E, package validation, and clean final autoreviews. AgentKit CI 30175539070 passed. Exact-head core CI 30176145620 passed with 69 successful jobs, 5 intentional skips, and 0 failures, including lint, production/full-tree Knip, all compact test shards, Android, Windows, and iOS.

Keep this tracker open until both implementation PRs land.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.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.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🌊 off-meta tidepoolIssue quality rating does not apply to this item.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions