Repository navigation
fix(credential-gateway): check only selected native model endpoints and name the setting - #4071
Conversation
…nd name the setting The deploy-time check that a Dedicated OpenClaw catalog uses the bound credential source endpoint checked every catalog entry, so an unselected entry for another endpoint failed the deployment, and its generic message named no setting. It now checks the models the Agents select (the shared selection that Compute uses to render the native worker catalog) and names the baseUrl setting and both hosts. Shapes Compute refuses earlier stay refused with the generic text.
…endency-free endpoint module The installation profile renderer imports openai-endpoint.ts from a checkout without node_modules, so the helper's @openclaw-enterprise/utils import broke profile-renderer's no-dependencies test. Move it to native-openai-catalog.ts.
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: needs maintainer review before merge. What this changesThe PR checks only selected native model endpoints against the credential source and names the configuration setting when they differ. Example: Select openai/model at https://models.example.test/v1 while retaining an unused catalog entry at https://other.example.test/v1.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness✅ Ready for maintainer review Keep open: this collaborator-authored PR fixes a source-confirmed deployment refusal still present on main; no discrete introduced defect was found. Priority: P2 Before mergeNone. FindingsNone. Tests
Agent review detailsHow this fits togetherKubernetes Compute projects selected models into the native worker configuration, while the OpenShell Credential Gateway checks their endpoints before attaching a source-owned credential profile. flowchart TB
A[Agent configuration] --> B[Shared model selection]
B --> C[Compute worker catalog]
B --> D[Gateway endpoint check]
E[Credential source endpoint] --> D
E --> F[OpenShell endpoint profile]
D --> F
C --> G[Native worker]
F --> G
Technical reviewBest possible solution: Use the shared selection rule for both worker rendering and gateway validation while retaining exact source-endpoint equality. Do we have a high-confidence way to reproduce the issue? Main's all-entry comparison rejects an unused mismatched endpoint even though Compute excludes it from the worker catalog; this was verified from source without executing target code. Is this the best way to solve the issue? The shared selector removes selection drift between existing owners, preserves Compute's validation behavior, and avoids expanding the Driver contract for earlier admission. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 6caa633640ac. Provenance checked
TestingProof path: in-process harness. SecurityNone. EvidenceWhat I checked:
LabelsLabel changes:
Label justifications:
Rank-up movesOptional improvements that raise the rating; they are not merge blockers.
Rating scale6/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. WorkflowClawSweeper edits this one comment on every review. Comment Reviewed October 29, 2026, 1:27 PM ET / 17:27 UTC. |
…ly the primary entry OpenClaw trims catalog ids and merges entries whose trimmed ids collide, so an unselected entry such as " model" could give the selected model its endpoint while the selection check skipped it. The shared selection now matches trimmed ids, so such an entry is a second match that Compute and the Credential Gateway refuse. On Dedicated OpenClaw the startup model probe now gets only the primary model's catalog entry instead of the whole authored catalog. Also: Compute admission uses the shared selection walk, the endpoint refusal shows the host with its port, and tests cover a differently spelled but equal endpoint and a port mismatch.
…ed Dedicated OpenClaw key OpenClaw merges catalog entries whose ids match after trimming, so an unselected padded entry with its own endpoint would give the selected model that endpoint. Kubernetes admission now counts it as a second match.
…ary's entry is probed
Problem
Dedicated native OpenClaw with a
credential_sourceHarness binding sends each model's requests to that model's catalogbaseUrl. The source's OpenShell profile admits only the source endpoint, so the Credential Gateway refuses a mismatch inattachForRevision. The check had two defects:nativeRuntimeConfiguration). An unselected entry for another endpoint gets no traffic, but it still failed the deployment.Change
apps/controller/src/drivers/native-openai-catalog.tsholdsnativeOpenAiModelSelections, beside the sharedopenai-endpoint.ts, which stays free of package imports for the profile renderer. It returns the references inagents.defaults.modeland eachagents.entries.*.model(primary and fallbacks, once each) and themodels.providers.openai.modelsentries each one names. Compute'snativeRuntimeConfigurationnow uses it in place of its privateharnessModelsand inline matcher, with the same refusals in the same order.attachForRevisionchecks only the selected entries. A mismatch names thebaseUrlsetting that applies (models.providers.openai.models.N.baseUrl, ormodels.providers.openai.baseUrlwhen the entry inherits it) and the source and written hosts, with any explicit port, so a port mismatch shows. Hosts are shortened to fit the 256-character message cap. It never shows the source ID, the key or a model reference.openai/<model>, or a selection without exactly one catalog entry, the check keeps the generic refusal. Compute refuses all of these at admission, so a real revision does not reach the gateway in that state.nativeOpenAiModelSelectionsnow compares trimmed ids, so such an entry is a second match: Compute admission and preparation refuse it ("must hold exactly one entry for each selected openai model"), and the gateway keeps its generic refusal.harnessProbeConfigurationused to pass the whole authoredmodels.providers.openaiblock, unselected entries included, to the startup model check. It now keeps only the primary model's catalog entry (as written), as the native worker gets only the selected entries. Admission checks are unchanged; embedded OpenClaw still gets the whole block, as its Gateway uses it.validateHarnessAuthno longer has its own copy of the selection walk; the refusals are the same.Not in this PR (finding follow-up): an earlier refusal at Agent save or the Create Agent preflight. When an Agent is saved or preflighted, no Driver sees both the Configuration and the bound source's endpoint.
ComputeDriver.validateHarnessAuthgets only the source's catalog type, and the Credential Gateway contract has no admission hook. OCC would need to learn the gateway'sbase_urlconfig key. An earlier refusal needs a Driver contract change, so it needs an RFC first.Verification
tests/integration/credential-source-api.test.mjs, "OpenShell custom and default credential profiles keep independent ownership and lifecycle". The test drives the real OpenShell Credential Gateway Driver against the test's provider store, and its native revision now selects its model like a real one. New cases:baseUrl, the providerbaseUrlwith a path-only mismatch, nobaseUrlat all, a fallback, and a roster entry.https://MODELS.example.test:8443/api/v1/) attaches, and a port-only mismatch names both hosts with their ports.tests/conformance/kubernetes-compute.test.mjs:tsc --buildpasses;credential-source-apiandkubernetes-computepass 412/412; both files pinned 20/20 at 2 CPUs. Earlier head:tsc --build, thechecks-baseline-1lane (it runs this file andtests/conformance/kubernetes-compute.test.mjs, which covers everynativeRuntimeConfigurationrefusal) pass (3,447 tests), and the file pinned 20/20 at 2 CPUs.Risks