feat(proxy): bind static credentials to provider endpoints - #2510
feat(proxy): bind static credentials to provider endpoints#2510johntmyers wants to merge 14 commits into
Conversation
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
🌿 Preview your docs: https://nvidia-preview-pr-2510.docs.buildwithfern.com/openshell |
|
/ok to test 6d36f25 |
|
Label |
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
|
/ok to test e2b271a |
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
|
/ok to test 6231d64 |
Signed-off-by: John Myers <johntmyers@users.noreply.github.com>
|
/ok to test 94491fe |
johntmyers
left a comment
There was a problem hiding this comment.
gator-agent
PR Review Status
Validation: Project-valid security hardening authored by a maintainer, following RFC #2155 and stacked on proxy refactor #2373.
Head SHA: 94491febb429bc4bff1d801abdef2386239d96d8
Review findings:
- Four blocking authorization/lifecycle flaws are anchored inline.
- One high-severity dynamic-credential lifecycle flaw and one medium-severity adapter-parity flaw are anchored inline.
- General medium finding: forward-proxy telemetry still receives the original request path. Without L7 this can expose query strings, placeholder syntax, and environment-key names, contrary to the documented OCSF boundary. Construct a syntax-only redacted target before all forward telemetry, omit queries, and add allowed/denied/malformed-request log assertions.
Docs: Fern coverage is extensive and the affected pages are auto-indexed, so no navigation update is needed. The current text promises canonical path matching, immediate detach revocation, preserved dynamic credentials, and adapter-parity reporting; those claims are not accurate until the findings are resolved.
Checks: Required branch, Helm, DCO, and E2E gates are green. The required test:e2e label and current-head /ok to test are already present.
Next state: gator:in-review pending author changes.
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
|
Addressed the general forward-telemetry finding in 59b7c13. Allowed and denied events now receive a query-free, syntax-redacted canonical path, while malformed targets use a fixed sentinel. Regression coverage serializes allowed, denied, and malformed OCSF events and asserts that query values, placeholder syntax, and environment-key names are absent. |
johntmyers
left a comment
There was a problem hiding this comment.
gator-agent
PR Review Status
Validation: Project-valid security hardening authored by a maintainer, following RFC #2155 and stacked on proxy refactor #2373.
Head SHA: 59b7c13f00bbe696c71df6100d1ce281aa2a9f71
Thanks @johntmyers. I checked your current-head remediation notes against the full diff. The canonical target boundary, live-state authority, provider identity, dynamic-snapshot preservation, and typed body/SigV4 denial changes resolve six prior findings. The forward-telemetry finding remains incomplete for no-path absolute URIs, and the independent review found one additional WebSocket fail-closed edge plus two documentation inaccuracies.
Review findings:
- Four actionable findings are anchored inline.
- No unanchored general findings.
Docs: Fern pages and related skills were updated, and docs/index.yml navigation does not need a change. Two statements still need correction as noted inline.
Checks: Code-only review; no local tests were run. The required test:e2e label is already present. Pipeline progression remains gated on author changes.
Next state: gator:in-review pending author changes.
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
johntmyers
left a comment
There was a problem hiding this comment.
gator-agent
PR Review Status
Validation: Project-valid credential security hardening authored by a maintainer, following design #2155 and stacked on proxy refactor #2373.
Head SHA: 44ba6839f994dfe5855cfe9c2cc17cb3b3176a4b
Thanks @johntmyers. I checked your current-head replies against the full diff. The absolute-URI telemetry fix, fail-closed WebSocket relay selection, gateway dynamic-snapshot wording, and HTTP-versus-WebSocket failure documentation resolve all four findings from the prior head.
Review findings:
- Critical — CWE-284: Provider environment revisioning hashes the catalog's effective profile, while credential binding resolution selects a profile using
provider.profile_workspace. When a workspace override and platform fallback share an ID, narrowing the platform profile can leaveprovider_env_revisionunchanged and let a supervisor retain an obsolete broader binding. Hash the exact scoped profile selected byget_provider_type_profile_for_scope(), including its scope, and add a platform-scoped-provider regression beneath a same-ID workspace override. Relevant code:crates/openshell-server/src/grpc/policy.rs:1611andcrates/openshell-server/src/provider_profile_sources.rs:437,470. - Two actionable warnings are anchored inline.
- Warning — agent guidance: The
sync-agent-inframaintenance map routes provider and direct-inference behavior changes todebug-inference, but that skill still diagnoses direct external denials only as missing policy/provider attachment. Addcredential_endpoint_mismatchguidance that checks profile endpoints and warns against widening sandbox policy unless the profile intentionally authorizes the recipient.
Docs: Fern pages are updated and already navigated, so no navigation change is needed. One architecture statement remains inaccurate as noted inline.
Checks: Code-only review; no local tests were run. test:e2e is already applied and the current E2E run is pending. No additional /ok to test action is needed in this cycle.
Next state: gator:in-review pending author changes.
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
|
Addressed the two unanchored findings from review
Validation: 1,116 gateway tests and 1,074 network tests passed; pre-commit passed. |
johntmyers
left a comment
There was a problem hiding this comment.
gator-agent
PR Review Status
Validation: Project-valid credential security hardening authored by a maintainer, following design #2155 and stacked on proxy refactor #2373.
Head SHA: 42a454bb4143e672fa57f3daa0e0ee34eab11131
Thanks @johntmyers. I checked your current-head remediation notes against the full diff. The exact scoped-profile revision hash and its fallback/override regressions resolve the prior critical finding. The new credential_endpoint_mismatch guidance correctly warns against widening policy, but its inspection command is incomplete. The independent review also found two remaining single-route adapter-parity gaps after the request-admission ordering fix.
Review findings:
- Three actionable warnings are anchored inline.
- No unanchored general findings.
Docs: Fern coverage is extensive and the affected pages are already navigated, so no docs/index.yml change is needed. The documented HTTP 403 and OCSF behavior remains inaccurate for single-config JSON-RPC/MCP and GraphQL until the two relay findings are resolved.
Checks: Code-only review; no local tests were run. test:e2e is already applied and the current-head E2E run is pending. No additional /ok to test action is needed in this cycle.
Next state: gator:in-review pending author changes.
|
|
||
| let req = parsed.request; | ||
| let jsonrpc_info = parsed.info; | ||
| let scoped_ctx = scoped_context_for_request(ctx, &req.target); |
There was a problem hiding this comment.
gator-agent
Warning — CWE-532/CWE-778: This scopes credentials, but the single-config JSON-RPC/MCP branch still logs req.target without credential redaction and propagates resolver failures directly. Use redact_target_for_policy, then route the post-policy relay through relay_http_request_with_credential_rejection so mismatches return the typed 403 and emit both OCSF events. Please add single-config JSON-RPC/MCP regressions.
|
|
||
| let req = parsed.request; | ||
| let graphql_info = parsed.info; | ||
| let scoped_ctx = scoped_context_for_request(ctx, &req.target); |
There was a problem hiding this comment.
gator-agent
Warning — CWE-778: The single-config GraphQL relay still propagates scoped resolver failures directly, so endpoint mismatches close the connection without the documented 403 or OCSF finding. Use relay_http_request_with_credential_rejection after policy admission, matching REST and route-selected handling, and add a regression for this branch.
|
|
||
| If the response reports `credential_endpoint_mismatch`, the provider is attached | ||
| but its credential profile does not authorize that request recipient. Inspect | ||
| `openshell provider get <provider-name>` and compare the profile's endpoint host, |
There was a problem hiding this comment.
gator-agent
Warning — troubleshooting guidance: provider get does not display profile endpoints or the selected profile scope. Have the workflow use it to identify the provider type, then run openshell provider profile export <type> -o yaml with the appropriate workspace/platform scope before comparing host, port, and path.
Summary
Bind static provider credentials to profile-authorized host, port, and path selectors so placeholders cannot be resolved at other policy-allowed endpoints. This is a focused, stacked extension of the proxy refactor in #2373 and preserves dynamic credential behavior.
Related Issue
Design: #2155
Stacked on: #2373
Changes
Testing
mise run pre-commitpassesmise run testpassesmise run e2e:rustpassesmise run e2e:pythonpasses (87 passed)mise run e2e:mcppasses (3 scenarios)Checklist