Skip to content

fix(providers): harden static credential placement - #4886

Open
johntmyers wants to merge 2 commits into
mainfrom
fix/4883-credential-placement/johntmyers
Open

johntmyers wants to merge 2 commits into
mainfrom
fix/4883-credential-placement/johntmyers

Conversation

@johntmyers

@johntmyers johntmyers commented Oct 23, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Enforce static credential placement in the supervisor using the provider profile's existing auth_style metadata. Block moving a header credential into an arbitrary query parameter, path, or unrelated header while preserving older gateway/supervisor interoperability and documented rewrite policies.

Related Issue

Closes #4883

Changes

  • Forward placement-only metadata for delivered static credentials through the existing credential snapshot map; bind metadata to the actual credential owner and exclude grants, refresh configuration, and secret values.
  • Infer header/query/path enforcement locally in the supervisor before substitution. Separate static metadata from actual token grants atomically; missing metadata retains legacy behavior.
  • Preserve existing RPCs, protobuf fields, credential delivery, identities, stable handles, signing, and explicit body/WebSocket rewrite policies. Older supervisors ignore metadata without a token grant; older gateways omit it.
  • Keep body/WebSocket rewriting explicitly policy-controlled, including preventing a disabled WebSocket rewrite flag from reacquiring a live resolver.
  • Add regression coverage and update provider/troubleshooting guidance. Proto changes are comments only; no new service, capability gate, configuration flag, or additional lookup is introduced.

Release Notes

Static credential placement is enforced automatically when a supporting gateway forwards usable existing profile auth metadata to a supporting supervisor. Components can upgrade in either order; missing metadata preserves legacy behavior. Credentials without metadata and older components retain the earlier substitution exposure. Explicit body/WebSocket policies and trusted signing keep their existing permissions.

Testing

  • Relevant Rust library suites: 4,965 passed, 23 ignored; one known TCP timeout test explicitly excluded.
  • Full provider Docker sandbox suite: 22 passed, including normal authentication, attach/detach, updates, GitHub HTTPS cloning, workspace isolation, placement enforcement, and metadata-free legacy behavior.
  • Mixed-version source harness: four checks passed using unchanged baseline credential runtime and grant-selection source alongside the new runtime. Legacy envelopes, stable placeholders, metadata tolerance, rotation, and detach remain compatible. This is module-level validation, not a full cross-version deployment.
  • Protobuf compatibility against main and unchanged public/durable schema inventories.
  • Documentation validation and independent implementation review.
  • Full repository pre-commit hooks.

Known limitation: proxy::tests::mediated_connect_keeps_workload_bytes_read_with_the_synthesized_header timed out on the final revision, then passed six consecutive exact reruns. Unchanged main (92434dcb2) passed seven exact runs in the same environment. The fixture is unchanged and exercises credential-free raw CONNECT, but the timeout's cause remains unresolved; no baseline failure was observed. The 4,965-test aggregate above excludes this test and does not claim an unfiltered suite pass.

Remote CI for 8531c4b4f: completed checks have passed; Linux ARM64 tests and the macOS jobs remain pending. Remote E2E suites were skipped; the 22 Docker cases above ran locally. The updated compatibility advisory flags the intended restriction on using header-declared credentials in URLs or unrelated headers; applications must use the profile's declared location.

Checklist

  • Follows Conventional Commits.
  • Commits are signed off (DCO).
  • Relevant implementation and user-facing documentation updated.

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
@johntmyers johntmyers added area:supervisor Proxy and routing-path work topic:security Security issues area:providers labels Oct 23, 2026
@github-actions

Copy link
Copy Markdown

@github-actions

Copy link
Copy Markdown

Compatibility review (advisory)

New or updated breaking changes; see the full report for all findings.

1. api-behavior — No explicit risk acceptance found

Static-credential delivery previously required endpoint-binding support; now polling and configuration push also require supports_static_credential_placement.

  • Impact: Baseline supervisors and existing GetSandboxProviderEnvironment callers lose static credentials after a gateway upgrade, while upgraded supervisors reject placement-free bindings from baseline gateways.
  • Action: Preserve baseline supervisor interoperability in v0.1.6 or defer mandatory placement negotiation to a minor release with a coordinated rollout procedure.
  • PR: fix(providers): harden static credential placement #4886

2. configuration — No explicit risk acceptance found

Endpoint-bound profiles previously delivered sandbox credentials without placement metadata; now missing placement causes withholding, including Codex refresh and ID tokens.

  • Impact: Existing custom profiles and policy-only AWS signers lose credentials, and Codex launchers requiring CODEX_AUTH_REFRESH_TOKEN exit with a missing-environment error.
  • Action: Preserve legacy profile delivery in v0.1.6; a later breaking release needs profile-update instructions and a working migration for unsupported Codex token flows.
  • PR: fix(providers): harden static credential placement #4886

3. policy — No explicit risk acceptance found

Static placeholders previously resolved at supported endpoint-authorized locations; now profile placement restricts them and overrides request_body_credential_rewrite and websocket_credential_rewrite.

  • Impact: Previously supported body and WebSocket authentication fails with HTTP 403 credential_placement_mismatch or WebSocket close code 1008 despite unchanged opt-in policies.
  • Action: Retain documented rewriting in v0.1.6 or defer its removal to a minor release with supported replacements for body and WebSocket authentication.
  • PR: fix(providers): harden static credential placement #4886

4. rust-sdk — No explicit risk acceptance found

Generated GetSandboxProviderEnvironmentRequest, StaticCredentialBinding, and SupervisorHello gain public fields absent from their baseline shapes.

  • Impact: Consumers constructing exhaustive openshell_sdk::raw::proto struct literals or patterns no longer compile, although existing RPC method signatures remain unchanged.
  • Action: Keep existing raw struct shapes in v0.1.6 through separate message types or defer these additions to a minor release with literal and pattern migration guidance.
  • PR: fix(providers): harden static credential placement #4886

5. typescript-sdk — No explicit risk acceptance found

Generated raw GetSandboxProviderEnvironmentRequest and SupervisorHello types gain the required boolean property supportsStaticCredentialPlacement.

  • Impact: Existing complete message literals assigned to these exported types fail type checking, while partial RPC inputs and create(schema, init) callers remain source-compatible.
  • Action: Preserve existing raw message shapes in v0.1.6 or defer the additions to a minor release documenting migration from complete literals to create(schema, init).
  • PR: fix(providers): harden static credential placement #4886
Review details
  • Execution: complete
  • Candidate: PR #4886 (669772fae9cf11a7f5adaab44fa79468cd81c478)
  • Baseline: 92434dcb2b6248ac827df05c00551fe7a1fedf17 (92434dcb2b6248ac827df05c00551fe7a1fedf17)
  • Reviewed: rust-sdk, python-sdk, go-sdk, typescript-sdk, api-behavior, cli, configuration, policy, helm, state

Advisory review; publication gates are unchanged.

Branch check run

Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

Compatibility review (advisory)

New or updated breaking changes; see the full report for all findings.

1. policy — No explicit risk acceptance found

Static placeholders previously resolved in supported headers, query values, and paths at authorized endpoints; existing auth_style metadata now restricts those locations automatically.

  • Impact: Existing applications placing a header-declared credential in ?api_key=<placeholder>, a URL path, or another header now receive HTTP 403 credential_placement_mismatch after gateway and supervisor upgrades.
  • Action: Preserve legacy header/query/path substitution for existing profiles in v0.1.6, making enforcement explicitly opt-in or deferring automatic activation to a minor release with profile and client migration guidance.
  • PR: fix(providers): harden static credential placement #4886
Review details
  • Execution: complete
  • Candidate: PR #4886 (c1c7b00fa180d0de584020a06314a4cc30c74846)
  • Baseline: 92434dcb2b6248ac827df05c00551fe7a1fedf17 (92434dcb2b6248ac827df05c00551fe7a1fedf17)
  • Reviewed: rust-sdk, python-sdk, go-sdk, typescript-sdk, api-behavior, cli, configuration, policy, helm, state

Advisory review; publication gates are unchanged.

Branch check run

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:providers area:supervisor Proxy and routing-path work topic:security Security issues

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(providers): enforce declared static credential placement

1 participant