Repository navigation
Provide secure multi-target OpenShell providers for Switchyard routing #8887
Description
Parent Epic: #7937
Outcome
Switchyard judge, weak, and strong targets resolve to distinct OpenShell-managed provider identities without placing raw provider credentials in the sandbox or permitting direct-provider bypass.
Proposed V5 decision
Use three separately attached OpenShell providers for the first released-path integration:
- judge/classifier;
- weak/efficient; and
- strong/capable.
Keep inference.local as Hermes's ordinary bootstrap/default route. Do not use it for Switchyard targets: the current gateway-wide inference route selects one host model and cannot represent two simultaneous target models plus a judge.
Canonical NemoClaw scope was accepted in #7937 on 2026-08-13. This recommendation defines the initial provider boundary, but it does not authorize activation or a support claim before the remaining release and qualification gates pass.
Provider bundle contract
NemoClaw should provision the bundle against the final OpenShell gateway and attach all three providers to the sandbox create/rebuild plan as one activation unit.
For each provider, the gateway-authored receipt or attestation must identify:
- provider ID, resource version, type, workspace, and resolved profile revision;
- a versioned digest of canonical non-secret endpoint/configuration data;
- credential and configuration key names, never values; and
- the sandbox-local provider endpoint used by the generated Switchyard llm_client.
NemoClaw generates Switchyard llm_clients and targets only from that committed evidence. Each llm_client receives an endpoint-scoped raw-key placeholder through api_key_env; Switchyard constructs the provider Authorization header. Set forward_auth = false so caller authorization cannot reach the judge or selected target.
Provider names are labels, not security identities. Any partial create or attach leaves routing inactive and rolls back or quarantines the incomplete bundle. No provider request may occur until all three identities and bindings are attested.
Current OpenShell gate (2026-08-27)
OpenShell v0.0.113 is released, but NVIDIA/OpenShell#2722 remains open. The current CLI cannot bind an update atomically to a previously observed provider ID plus resource version, and the read surface does not expose a stable endpoint/profile attestation.
OpenShell PR #2962 now proposes making built-in or imported provider profiles authoritative while retiring legacy public provider workflows. That direction aligns with this issue's declarative judge/weak/strong profiles and means NemoClaw must not depend on the legacy generic creation path. The PR is still open with a non-green required gate and does not implement #2722's conditional mutation or attestation contract.
Therefore the initial milestone is deliberately narrow:
- qualify fresh creation of uniquely named judge, weak, and strong providers;
- do not claim safe reuse, update, credential rotation, or mutation of existing provider records;
- fail closed when a requested name already exists or its identity cannot be proven; and
- keep mutation/rotation blocked until docs: add Brev troubleshooting guide #2722 or an accepted equivalent contract is released and qualified.
This fresh-only boundary remains intentionally narrower than the final lifecycle contract and may be tightened by security review.
Scope
- Define stable semantic target identities for judge/classifier, weak/efficient, and strong/capable.
- Transactionally create and attach the three-provider bundle against the final gateway authority.
- Translate only attested OpenShell endpoint/model identities into Switchyard llm_clients, targets, and routes.
- Keep raw provider credentials behind OpenShell placeholder rewriting.
- Deny caller-auth forwarding, cross-provider placeholder use, and direct-provider bypass.
- Keep the Switchyard path inactive when any provider, receipt, route, or policy binding is missing or inconsistent.
- Validate two real target models and canonical routing evidence end to end.
Acceptance
- A fresh onboarding flow creates and attaches judge, weak, and strong as one bundle with no manual credentials-add loop.
- Two simultaneous real model targets return distinguishable, recorded responses.
- Classifier/judge traffic uses its separately declared provider when the router requires it.
- Switchyard target configuration contains no inference.local endpoint.
- Raw provider credentials are absent from sandbox environment, files, argv, logs, errors, telemetry, and captured artifacts.
- Caller-supplied authorization cannot reach or replace a gateway-owned credential; forward_auth remains false.
- Each placeholder resolves only at its approved provider endpoint; cross-endpoint use and direct-provider bypass are denied.
- Missing, partial, stale, duplicate-name, or unattestable provider state fails before routing activation or any provider request.
- Existing-provider mutation, reuse, and credential rotation remain rejected until identity-bound CAS and secret-free endpoint/profile attestation are available and qualified.
- Removing or losing one provider produces an explicit unavailable state rather than silent fallback to inference.local or another target.
Activity
cjagwani commentedon Aug 12, 2026
Maintainer design decision details are tracked in #8893; endpoint-bound OpenShell Providers v2 are the V1 boundary, not single-model inference.local.
cjagwani commentedon Aug 12, 2026
The OpenShell
0.0.103audit narrows the supported V1 provider boundary:host:port:pathselectors;modelfield, so two tiers sharing a normal/v1/chat/completionsendpoint cannot be claimed as model-isolated;header_envfrom exact attached-provider credential keys; callers cannot supply literal credential values.Therefore the direct-provider V1 will require distinct model-pinned endpoints. Same-endpoint multi-model routing remains dependent on named multi-target
inference.localsupport upstream. The public configure path should land with native activation and network/bypass enforcement, not as dormant provider scaffolding.cjagwani commentedon Aug 12, 2026
Provider transaction blocker discovered
A security review of the proposed provider-mutation receipt found that a client-side read → CLI update → read sequence is not sufficient for #8887.
OpenShell's gateway supports resource-version CAS internally, but the v0.0.104 CLI still sends provider updates with an empty ID and
resource_version: 0. The gateway therefore resolves the current provider by name at mutation time. A concurrent update or delete/recreate can receive the submitted credential/config before NemoClaw's post-read detects identity drift. The secret-free inventory also exposes config key names, not an endpoint/config digest or resolved provider-profile revision.I did not publish the local receipt implementation because it would have detected drift only after credential delivery and could have been mistaken for endpoint attestation.
The required upstream identity-bound transaction and attestation surface is now tracked in NVIDIA/OpenShell#2722: NVIDIA/OpenShell#2722
Implication for this issue:
cjagwani commentedon Aug 13, 2026
Selected V1 contract — direct endpoint-bound providers
The V1 choice is option 2: separately attached OpenShell providers, not multi-target
inference.local.The exact contract is:
judge,weak, andstronguse unique provider names, profile IDs, environment keys, and non-overlapping model-pinnedhost:port:pathendpoints;header_env;openshell:resolve:env:vN_*placeholders;Authorizationvalue;0.0.103resolves each placeholder only for its attached provider and bound endpoint, and missing/expired/mismatched placeholders fail before upstream bytes are sent;The first prototype can create fresh, uniquely named providers without mutating them. Canonical rotation/update remains blocked on NVIDIA/OpenShell#2722's exact provider-ID/resource-version mutation plus gateway-authored profile/config attestation. Until that exists, NemoClaw must not update a security-sensitive provider by mutable name and then treat a post-read as proof.
Remaining proof items here are two distinct real models, a separate judge call, no raw-secret/caller-auth leakage, exact endpoint denial, restart persistence, and defined removal/failure behavior. Runtime provider failure also needs the fail-closed versus trusted-fallback decision tracked in #8888.
cjagwani commentedon Aug 13, 2026
Draft integration slice security review
The first native Hermes Relay/Switchyard configuration slice is safe to publish only as a dormant draft, not merge as a supported integration.
What passes: secret-free durable profiles, fail-closed shape validation, same-revision OpenShell resolver checks, caller credential values excluded from durable files, exact generated TOML replay, root-owned read-only artifacts, stale configuration cleanup, and redacted errors.
Merge blockers:
nvidia.switchyardis active.The authorization chain required before merge remains:
attached provider -> approved endpoint/model -> injected credential key -> active plugin -> readinessThese blockers map to #8885, #8886, #8887, #8888, #8889, and NVIDIA/OpenShell#2722. The draft intentionally has no public onboarding producer or support documentation.
cjagwani commentedon Aug 13, 2026
Draft #9012 implements the secret-free profile/TOML/runtime-placeholder mechanics for judge, weak, and strong. It remains dormant and does not satisfy this issue: endpoint/model/credential keys still need to be derived from authoritative attached-provider identity/resource-version and gateway-authored attestation before merge or public activation.
chore(deps): trust OpenShell 0.0.106 manifests (#9224)
chore(deps): update OpenShell to 0.0.106 (#9192)
cjagwani commentedon Aug 24, 2026
2026-08-24 provider-boundary contract update
The final #528 contract supersedes the prototype header_env design. Switchyard deployment targets now use api_key_env containing the raw provider key; the Switchyard client constructs the Bearer header. NemoClaw should therefore provision an OpenShell resolver placeholder for the raw key, never a literal secret or prebuilt Authorization header.
NemoClaw main now deliberately pins OpenShell 0.0.106, and the prior 0.0.103 upgrade work in #8893 is complete. Fresh uniquely named provider creation and attachment can be qualified independently. Security-sensitive mutation/rotation still requires NVIDIA/OpenShell#2722 or an equivalent identity plus resource-version conditional update and gateway-authored attestation contract.
The production binding remains:
attached provider identity -> approved endpoint/model -> api_key_env placeholder -> selected target policy -> active plugin/readiness
#528 also still has an unresolved review concern around selected-target policy validation, so the supported path must not claim this boundary until both upstream target validation and NemoClaw endpoint/policy tests pass.
fix(example): stabilize Ask NemoClaw Brev and vision flows (#189)
cjagwani commentedon Oct 27, 2026
Superseded by #13863 under the replanned #7937 implementation. The replacement narrows the first slice to two freshly created OpenShell-managed targets.