openclaw-scheduler
- runtime
- dispatcher loop
- SQLite state
- retries, approvals, delivery, recovery
- durable dispatch queue
agentcli
- manifest schema
- validation
- compile target adapters
- scheduler apply / upsert surface
- standalone planning surface
- scheduler inspection surface
- machine-readable CLI
- stdio JSON-RPC server
- local approval gate for direct
exec(single-use ssh-signed grants; no queue, no cron coupling, no multi-actor routing)
The local gate and the scheduler's durable gate coexist: both honor the same approval.policy and approval.risk_level declarations in the manifest. agentcli exec enforces the gate for single-machine invocations using ~/.agentcli/state/approvals.ndjson; openclaw-scheduler enforces the gate for cron-triggered durable execution using its own approval queue.
agentcli has two backend stories:
standalone: portable plan, validation, schema, describe, JSON-RPCopenclaw-scheduler: compile target, apply/upsert path, and runtime inspection
This makes the standalone control plane useful on its own while also giving openclaw-scheduler a clean authoring and integration surface.
Manifest spec 0.2 introduces a full execution identity model. The detailed specification lives in docs/execution-identity.md; this section provides an architectural overview.
The identity architecture separates concerns into six distinct layers:
- Subject Declaration -- the logical principal the task intends to act as (human delegate, autonomous service, enterprise agent, workload identity). Declarative and portable across backends.
- Manifest Authorization Proof -- pre-execution proof that the workflow declaration was authorized (CI-issued JWT, signed deployment token, certificate reference, detached signature). Static, travels with the manifest, distinct from runtime credentials and execution evidence.
- Authentication and Credential Acquisition -- runtime credential resolution through a provider plugin (auth mode, scopes, audiences, delegation chains, token exchange). Async and provider-backed.
- Credential Presentation -- how the wrapped tool receives credentials at execution time (environment variables, temporary files, stdin). Explicit because authentication and tool execution are decoupled.
- Contract Enforcement -- execution boundary evaluation (sandbox, allowed paths, network expectations, cost limits, required trust level). Consumes identity metadata but is architecturally separate from identity.
- Evidence and Audit -- post-execution proof and structured audit records (SSH signatures, KMS-backed signatures, Sigstore envelopes). Consumes identity; does not own it.
Four separate provider registries serve distinct concerns:
- Identity provider registry -- resolves credentials for declared identity profiles (
none,env-bearer,oidc-client-credentials,oidc-token-exchange, and future enterprise providers). - Authorization proof verifier registry -- validates manifest-time authorization proof (
jwt,certificate,signature). - Evidence provider registry -- generates and verifies post-execution attestation (
ssh,none). Conceptual successor to the v0.1 signing provider. - Authorization provider registry -- dispatches per-action authorization to external policy engines (
opa).
Each provider file auto-registers with its registry on import (side-effect registration). Providers expose machine-readable capabilities objects for discovery, and the runtime checks capabilities before calling optional methods. This allows capability-based provider discovery without a central configuration file.
agentcli exec runs the following pipeline for v0.2 manifests:
- Phase 1: Manifest Loading + Authorization Proof Verification -- load, expand shorthands, validate schema, verify manifest authorization proof when declared.
- Phase 2: Identity Resolution -- resolve profile references, merge workflow and task overrides (three-stage merge), validate delegation chains, resolve credential session, evaluate trust level. Async for providers that call external token endpoints.
- Phase 3: Presentation Materialization -- materialize credentials per declared bindings (env vars, temp files, stdin payload).
- Phase 3.5: Credential Handoff (optional) -- when the executing runtime exposes an explicit downstream handoff boundary, prepare a derived credential (downscoped or transaction-scoped). Fails closed if required but unsupported.
- Phase 4: Contract Evaluation + Trust Enforcement -- evaluate execution boundaries. When
required_trust_levelis declared, compare against the resolved trust level. Enforcement modes:none(log only),advisory(warn and continue),strict(escalate or fail closed). - Phase 4.5: Authorization (optional) -- invoke external policy engine (OPA, Cedar, Topaz) when an authorization block is configured. Decisions:
permit,deny,require-escalation. Skipped entirely when no authorization block resolves for the task. - Phase 5: Execution -- run the tool, capture stdout/stderr/exit code/duration, compute hashes.
- Phase 6: Evidence Generation -- build canonical evidence payload, attest execution, verify evidence if required.
- Phase 6.5: Post-exec Verify (optional) -- run
workflow.verify/task.verifyafter a successful command. This is an operator-local postcondition check recorded separately from evidence; verify failures can still fail the task or downgrade to warnings according toverify.on_failure. - Phase 7: Audit -- write structured append-only audit record with declared/resolved identity, authorization proof summary, delegation chain, trust level, authorization decision, and runtime instance attribution.
- Phase 8: Cleanup -- delete temporary files, destroy ephemeral materialization and derived handoff credentials.
exec.js detects the manifest version (manifest.version === '0.2' || Boolean(manifest.identity_profiles)) and dispatches to entirely separate code paths. The v0.1 path (executeTaskV1) is preserved unchanged -- synchronous, no identity providers, original signing flow. The v0.2 path (executeTaskV2) is async and runs the full lifecycle above.
This dual-path design guarantees zero behavioral change for v0.1 manifests. src/signing/ is preserved for v0.1; src/evidence/ exists alongside it for v0.2 without cross-coupling.
The architecture composes with emerging standards rather than inventing new protocols:
- IETF AIMS (
draft-klrc-aiagent-auth-00) -- the six-layer model maps to the AIMS reference layers (Identifier, Credentials, Attestation, Provisioning, Authentication, Authorization, Monitoring). Manifest authorization proof and credential presentation extend beyond AIMS scope. - SPIFFE/WIMSE -- identity profiles use URI-formatted principals (
agent://,spiffe://) for interoperability with workload identity infrastructure. - OAuth 2.0 -- auth modes map to standard grant types:
service(Client Credentials),delegated(Authorization Code),on-behalf-of(JWT Authorization Grant, RFC 7523),exchange(Token Exchange, RFC 8693).
The six-layer identity model enables a meaningful trust boundary between the scheduler and its child tasks, but only when the child is configured to be narrower than the parent.
The credential flow traces through four control surfaces:
- Operator provisions -- credentials enter the system via env vars,
Vault, managed identity, or files. The operator controls
SCHEDULER_PROVIDER_PATHand the scheduler's execution environment. - Scheduler resolves -- at dispatch time, the scheduler calls the identity provider to resolve a credential session. Trust evaluation and authorization gates run before any credential is materialized.
- Provider narrows -- when
child_credential_policyisdownscope, the provider mints a per-task restricted key via the credential issuer's API, scoped to exactly the permissions the child declared. Scope hierarchy validation ensures the child cannot escalate. The key is revoked in cleanup. - Child receives scoped creds -- the child task runs with only the narrowed credentials. For shell tasks, these are injected as env vars. For agent tasks, auth-profile forwarding directs the gateway to use the appropriate profile.
Trust boundary definition: the operator controls the scheduler env and provider directory. Everything downstream narrows only. A child MUST NOT receive broader credentials than its parent. If the provider directory or scheduler env is compromised, the trust model is broken -- these are root-of-trust assumptions, not runtime invariants.
Credential strategies: the current implementation supports both
precreated keys (operator creates restricted keys ahead of time, provider
resolves by scope name) and dynamic key minting (provider mints a
per-task restricted key via the credential issuer's API and revokes it on
cleanup). Both use the same manifest syntax; the provider's
key_strategy configuration determines which path runs.
For the full trust architecture with concrete guarantees and
non-guarantees, see openclaw-scheduler/docs/trust-architecture.md.
- Stabilize manifest and target outputs.
- Add an execution adapter boundary for optional local backends.
- Expand JSON-RPC into MCP if that integration surface proves better.
- Add more target adapters without weakening the manifest contract.