Skip to content

Fail closed when an explicit agent harness is missing#71265

Merged
pashpashpash merged 2 commits intomainfrom
pash/harness-explicit-runtime-no-pi-fallback
Apr 24, 2026
Merged

Fail closed when an explicit agent harness is missing#71265
pashpashpash merged 2 commits intomainfrom
pash/harness-explicit-runtime-no-pi-fallback

Conversation

@pashpashpash
Copy link
Copy Markdown
Contributor

OpenClaw already stopped falling back to PI after a selected Codex harness fails. The remaining confusing case was earlier in the flow: if someone explicitly asked for a concrete harness like codex, but that harness was not registered, omitted fallback config still meant PI could silently take the turn.

This changes the default fallback based on intent. runtime: "auto" keeps the compatibility behavior and still defaults to PI when no plugin harness claims the run. An explicit plugin runtime now defaults to no PI fallback, so runtime: "codex" means Codex or a clear failure unless the user deliberately sets fallback: "pi".

The docs and generated config help now describe that split, and the harness selection tests cover env-forced and config-forced Codex selection both with omitted fallback and explicit PI fallback.

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation gateway Gateway runtime agents Agent runtime and tooling size: S maintainer Maintainer-authored PR labels Apr 24, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 24, 2026

Greptile Summary

This PR changes the default fallback behavior for the embedded agent harness: runtime: "auto" retains backwards-compatible PI fallback, while any explicit plugin runtime (e.g. runtime: "codex") now defaults to fallback: "none", failing clearly instead of silently routing to PI. The logic change is a single well-placed conditional in normalizeAgentHarnessFallback, the new tests cover env-forced and config-forced codex selection with both omitted and explicit fallback, and the docs/schema help text are updated consistently.

Confidence Score: 5/5

Safe to merge — the logic change is minimal, well-tested, and backwards compatible for auto mode.

All findings are P2 or lower. The core logic in normalizeAgentHarnessFallback is correct; existing tests still pass under the new semantics and four new tests cover the changed default. Documentation and schema help are consistent with the code.

No files require special attention.

Reviews (1): Last reviewed commit: "Fail closed for explicit agent harness s..." | Re-trigger Greptile

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ade8e4bde0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/agents/harness/selection.ts Outdated
@aisle-research-bot
Copy link
Copy Markdown

aisle-research-bot Bot commented Apr 24, 2026

🔒 Aisle Security Analysis

We found 2 potential security issue(s) in this PR:

# Severity Title
1 🔵 Low Log/CRLF injection via unvalidated OPENCLAW_AGENT_RUNTIME included in error message
2 🔵 Low Invalid OPENCLAW_AGENT_HARNESS_FALLBACK values are silently ignored, potentially re-enabling PI fallback
1. 🔵 Log/CRLF injection via unvalidated OPENCLAW_AGENT_RUNTIME included in error message
Property Value
Severity Low
CWE CWE-117
Location src/agents/harness/selection.ts:115-123

Description

The agent harness runtime can be sourced from process.env.OPENCLAW_AGENT_RUNTIME (or config) and is only .trim()’d in normalizeEmbeddedAgentRuntime, allowing arbitrary characters (including newlines/control characters).

When a non-registered runtime is forced and PI fallback is disabled, the runtime string is interpolated directly into a thrown error message:

  • Input: OPENCLAW_AGENT_RUNTIME (environment) or config embeddedHarness.runtime
  • No validation: normalizeEmbeddedAgentRuntime() returns the trimmed string as-is for plugin ids
  • Sink: throw new Error(Requested agent harness "${runtime}" ...)

If the resulting Error message is later logged or printed (common in CLI/server error handlers), an attacker who can influence environment/config could inject newlines/CRLF into logs/telemetry, spoofing log entries or obscuring the true source of messages.

Vulnerable code:

if (policy.fallback === "none") {
  throw new Error(
    `Requested agent harness "${runtime}" is not registered and PI fallback is disabled.`,
  );
}

Recommendation

Constrain plugin runtime ids to a safe character set/length at normalization time (or before use in logs/errors) and reject invalid values.

For example:

const RUNTIME_ID_RE = /^[a-z0-9][a-z0-9_-]{0,63}$/i;

export function normalizeEmbeddedAgentRuntime(raw: string | undefined): EmbeddedAgentRuntime {
  const value = raw?.trim();
  if (!value) return "auto";
  if (value === "pi" || value === "auto") return value;
  if (!RUNTIME_ID_RE.test(value)) {
    throw new Error("Invalid agent runtime id");
  }
  return value;
}

Additionally, when embedding identifiers into human-readable log/error strings, consider escaping control characters (e.g., replacing \r/\n with visible sequences) to prevent log forging if an invalid value slips through.

2. 🔵 Invalid OPENCLAW_AGENT_HARNESS_FALLBACK values are silently ignored, potentially re-enabling PI fallback
Property Value
Severity Low
CWE CWE-840
Location src/agents/pi-embedded-runner/runtime.ts:24-32

Description

OPENCLAW_AGENT_HARNESS_FALLBACK is intended to control whether the system may fall back from a plugin harness to the built-in PI harness. However, unrecognized values are silently treated as if the override was not set.

Impact:

  • If an operator attempts to disable PI fallback via OPENCLAW_AGENT_HARNESS_FALLBACK but provides an invalid value (typo, unexpected string), the override is ignored.
  • In runtime: "auto" (or when config fallback is otherwise "pi"/defaulted), this can lead to unexpected fallback to PI, weakening the intended deployment isolation/controls.

Vulnerable behavior:

const raw = env.OPENCLAW_AGENT_HARNESS_FALLBACK?.trim().toLowerCase();
if (raw === "pi" || raw === "none") {
  return raw;
}
return undefined; // invalid values are ignored

This is a fail-open behavior from a security-policy perspective: invalid policy input results in default behavior (which may allow PI fallback) rather than a hard failure or explicit warning.

Recommendation

Treat an explicitly-provided but invalid OPENCLAW_AGENT_HARNESS_FALLBACK as a configuration error.

Options:

  1. Fail fast (recommended for security-sensitive deployments):
export function resolveEmbeddedAgentHarnessFallback(
  env: NodeJS.ProcessEnv = process.env,
): EmbeddedAgentHarnessFallback | undefined {
  const raw = env.OPENCLAW_AGENT_HARNESS_FALLBACK;
  if (raw == null) return undefined;
  const normalized = raw.trim().toLowerCase();
  if (normalized === "pi" || normalized === "none") return normalized;
  throw new Error(
    `Invalid OPENCLAW_AGENT_HARNESS_FALLBACK=${JSON.stringify(raw)} (expected "pi" or "none")`,
  );
}
  1. If backward compatibility requires non-throwing behavior, emit a high-visibility warning and consider defaulting to the safer option ("none") when the variable is set but invalid.

Analyzed PR: #71265 at commit 71c576d

Last updated on: 2026-04-24T21:35:59Z

@pashpashpash pashpashpash merged commit 11804a4 into main Apr 24, 2026
65 checks passed
@pashpashpash pashpashpash deleted the pash/harness-explicit-runtime-no-pi-fallback branch April 24, 2026 21:40
Angfr95 pushed a commit to Angfr95/openclaw that referenced this pull request Apr 25, 2026
* Fail closed for explicit agent harness selection

* Scope explicit harness fallback opt in
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
* Fail closed for explicit agent harness selection

* Scope explicit harness fallback opt in
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
* Fail closed for explicit agent harness selection

* Scope explicit harness fallback opt in
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling docs Improvements or additions to documentation gateway Gateway runtime maintainer Maintainer-authored PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant