Skip to content

fix(egress): name the refused field in an authority block - #3260

Merged
freeqaz merged 2 commits into
mainfrom
fix-2216
Oct 23, 2026
Merged

freeqaz merged 2 commits into
mainfrom
fix-2216

Conversation

@freeqaz

@freeqaz freeqaz commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

egressAuthorityConfiguration validates both drivers.credential_proxy.configuration.authority and repository.openShell.authority. It gave the same message for nine different faults:

  • an unknown key;
  • a missing or empty string;
  • a non-integer port;
  • a port out of range;
  • a relative certificate, private-key or issuer-key path;
  • a non-loopback development host.

The message read "Protected egress requires explicit TLS, issuer identity and a loopback development listener", even in production. Because it was a plain Error, the API and worker logs showed only STARTUP_FAILED/WORKER_STARTUP_FAILED, so an operator could not tell which key was wrong (finding 2216).

Change

  • The validator now takes the block's path and collects one detail per refused field, up to 32. Each detail has the field's JSON Pointer, a schema error code (REQUIRED, UNKNOWN_FIELD, INVALID_TYPE, INVALID_RANGE, INVALID_FORMAT or INVALID_VALUE) and a message that names the field but never its value.
  • Unknown keys get a single detail at the block's own pointer, so an operator's key name is never echoed. A key that was long, held a control character or looked like a credential could otherwise make the log filter drop the only detail.
  • It throws a new InstallationFieldError. startupConfigurationFailure maps it to DRIVER_CONFIGURATION_INVALID with those details, the same shape Driver configuration errors already use. The API and worker startup logs and the chart's upgrade check (formatStartupConfigurationFailure) therefore name the field.
  • The JSON Pointer helper is shared with ChartListenerMismatchError, which now escapes ~ and / too.
  • installation-fields.ts still imports only its reviewed dependencies. The repository-credentials source-boundary check passes.

Verification

  • New configuration-startup tests:

    • A table covers each fault class through loadInstallationConfiguration: an absent block, a non-object block, an unknown key, and three relative paths in one refusal. Each case checks the pointer and code as they appear after the log filter, and checks that no configured value appears.
    • A real API boot and a real worker boot each log DRIVER_CONFIGURATION_INVALID with the exact detail.
    • A unit check confirms that repository.openShell.authority names its own block.

    On main, both tests fail.

  • Locally (Node 24), these all pass, 327 of 328 with one existing skip: configuration-startup, sandbox-driver-startup, egress-connected-preflight, installation-change-preflight and the source-boundary conformance test.

  • The touched tests passed 20/20 at 2 CPUs on the final head.

  • Internal review: approve with nits. All applied:

    • unknown keys are reported at the block;
    • details are capped at 32;
    • an empty string is INVALID_VALUE;
    • the tests assert the filtered log output and cover absent and non-object blocks.

    The reviewer ran the old and new predicates on 394 inputs in both modes. Every input got the same accept or refuse result.

  • tsc --build, eslint and Prettier are clean.

Risks

  • The refusal text changes. No test, doc or script matched the old message.
  • The log code for these faults changes from STARTUP_FAILED/WORKER_STARTUP_FAILED to DRIVER_CONFIGURATION_INVALID. Validation itself is unchanged: the same inputs are refused.

egressAuthorityConfiguration answered nine faults (unknown key, missing or
empty string, port type or range, relative file path, non-loopback development
host) with one message about a loopback development listener, shared by
drivers.credential_proxy.configuration.authority and
repository.openShell.authority. As a plain Error it reached API and worker
logs only as STARTUP_FAILED (finding 2216).

The validator now takes the block's path and throws InstallationFieldError
with one detail per refused field: its JSON Pointer, a schema error code and
a message naming the field, never its value. startupConfigurationFailure maps
it to DRIVER_CONFIGURATION_INVALID with those details, so the API and worker
logs and the chart's upgrade check name the field. The shared-field module
still imports only its reviewed dependencies.
@freeqaz
freeqaz requested a review from a team as a code owner October 23, 2026 02:17
@clawsweeper

clawsweeper Bot commented Oct 23, 2026 •

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Pull request received. I will update this pull request when review starts.

ClawSweeper review complete

ClawSweeper finished reviewing this revision. The review result is being finalized.

View the workflow run.

Report an unknown key once, at the block's pointer, so a long, control or
credential-like key cannot make the log filter drop the only detail. Bound
the details at 32 like ConfigurationValidationError. Give an empty string
INVALID_VALUE. The tests now assert what the log filter keeps, cover an
absent and a non-object block, and check that no configured value appears.
@clawsweeper clawsweeper Bot added clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. clawsweeper:intake:needs-repro Preliminary submission classification; full source review pending. P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR. and removed clawsweeper:intake:bug Preliminary submission classification; full source review pending. clawsweeper:intake:needs-environment Preliminary submission classification; full source review pending. clawsweeper:intake:needs-repro Preliminary submission classification; full source review pending. labels Oct 23, 2026
@clawsweeper

clawsweeper Bot commented Oct 23, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge.

What this changes

This PR reports bounded, value-free field diagnostics when an Installation authority block is invalid.

Example: An operator sets drivers.credential_proxy.configuration.authority.privateKeyPath to tls.key.

  • Before: API and worker startup report a generic failure without identifying the invalid field.
  • After: Startup reports DRIVER_CONFIGURATION_INVALID with /drivers/credential_proxy/configuration/authority/privateKeyPath, INVALID_FORMAT, and the requirement for an absolute mounted-file path.

Review scores

Measure Result What it means
Overall readiness 🦐 gold shrimp (3/6) A focused, source-supported repair with meaningful startup integration coverage; reviewed execution evidence is limited to test reports and CI rather than a standalone behavior artifact.
Proof confidence 🦐 gold shrimp (3/6) This collaborator-authored diagnostic repair is outside the ordinary contributor-proof gate; supplied verification describes real API and worker startup tests, but no standalone runtime artifact was supplied or independently executed.
Patch quality 🐚 platinum hermit (4/6) No actionable review findings were identified.

Product

Kind: Bug fix · Worth it: Yes · Fix scope: Complete
User problem: Operators receive a generic startup failure when an authority setting is invalid and cannot identify the field to correct.
Reason: This collaborator-authored repair provides actionable diagnostics for both supported authority blocks without changing their configuration contract or acceptance rules.

Merge readiness

✅ Ready for maintainer review

Keep this PR open: it fixes actionable startup diagnostics still missing on current main, and review found no introduced correctness defect.

Priority: P2
Reviewed head: be0b3fc4862cc1464d6130597cac1a20b0b4fa23

Before merge

None.

Findings

None.

Agent review details

How this fits together

Installation composition validates operator-supplied authority settings before startup; the API, worker, and Helm pre-upgrade check turn refusals into filtered diagnostics.

flowchart TB
  A[Installation configuration] --> B[Shared authority validator]
  B --> C[Installation field error]
  C --> D[Startup failure mapping]
  D --> E[Diagnostic filter]
  E --> F[API and worker logs]
  E --> G[Helm upgrade check]
Loading

Technical review

Best possible solution:

Retain the shared validator and existing startup diagnostic pipeline while reporting each refused authority field without exposing its value.

Do we have a high-confidence way to reproduce the issue?

Current-main source directly shows that a relative privateKeyPath throws the generic authority Error and bypasses typed configuration diagnostics; no target code was run during this review.

Is this the best way to solve the issue?

The patch fixes the diagnostic owner shared by both authority blocks, preserves validation, and uses the existing filtered startup-error path.

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning medium; reviewed against a651091ac5c4.

Provenance checked

Testing

Proof path: in-process harness.

Security

None.

Evidence

What I checked:

  • Current main still has the reported diagnostic gap: The authority validator throws one generic Error for missing fields, invalid ports, relative paths, and development listener violations. (apps/controller/src/composition/installation-fields.ts:69, a651091ac5c4)
  • Pinned introduced change: The patch retains the existing acceptance conditions, supplies constant field paths at both callers, and collects diagnostics without interpolating configuration values or unknown key names. (apps/controller/src/composition/installation-fields.ts:96, be0b3fc4862c)
  • Existing diagnostic owner reused: InstallationFieldError joins the existing DRIVER_CONFIGURATION_INVALID mapping, and configurationLogDetails still applies schema validation, credential filtering, control-character rejection, and the 32-detail bound. (apps/controller/src/startup-failure.ts:49, be0b3fc4862c)
  • Target-native integration coverage: Added coverage loads real Installation files, checks filtered diagnostics across fault classes, and boots the shipped API and worker processes to assert their structured startup errors; the repository authority path has a separate focused assertion. (tests/integration/configuration-startup.test.mjs:2026, be0b3fc4862c)
  • Helm check consumes the changed mapping: The shipped pre-upgrade script loads Installation composition and formats its error through formatStartupConfigurationFailure before exiting unsuccessfully. (deploy/helm/openclaw-enterprise/files/check-installation.mjs:18, be0b3fc4862c)
  • Direction and discussion: The author is a collaborator and explicitly documents the diagnostic-code change while preserving validation; both discussion comments are bot status updates, with no additional approval, hold, or behavior artifact. (be0b3fc4862c)

Labels

Label changes:

  • add P2: Invalid authority settings already stop startup; identifying their fields reduces operator diagnosis effort without changing runtime authorization or accepted configuration.
  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • add status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR.

Label justifications:

  • P2: Invalid authority settings already stop startup; identifying their fields reduces operator diagnosis effort without changing runtime authorization or accepted configuration.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦐 gold shrimp and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR.

Rating scale

6/6 🦀 challenger crab · 5/6 🦞 diamond lobster · 4/6 🐚 platinum hermit · 3/6 🦐 gold shrimp · 2/6 🦪 silver shellfish · 1/6 🧂 unranked krab. Overall follows the weaker of proof and patch quality; ✨ marks media proof (a screenshot, video, or linked artifact) that directly shows the changed behavior.

Workflow

ClawSweeper edits this one comment on every review. Comment @clawsweeper re-review for a fresh review only. Repair and merge execution lanes are retired.

Reviewed October 22, 2026, 10:34 PM ET / October 23, 2026, 02:34 UTC.

@freeqaz
freeqaz merged commit 6f6a955 into main Oct 23, 2026
79 checks passed
@freeqaz
freeqaz deleted the fix-2216 branch October 23, 2026 02:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

P2 Normal priority bug or improvement with limited blast radius. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant