Repository navigation
Keep the selected credential provider through source updates and requests - #3879
Conversation
|
🦞👀 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 real behavior proof before merge. What this changesThis PR preserves an approved credential provider during source updates and pins provider methods throughout request handling. Example: An openai source approved with source-verifier-a is updated after source-verifier-b moves first in the catalog.
Review scores
ProductKind: Bug fix · Worth it: Yes · Fix scope: Complete Merge readiness⛔ Blocked before merge - 3 items remain Keep this PR open: it addresses a source-backed provider ownership bug that remains on main, and its maintainer-approved direction is useful; one recovery-message defect remains. Priority: P2 Before merge
Findings
Tests
Agent review detailsHow this fits togetherOCC mediates between authenticated execution requests, IAM, credential providers, Secret storage, and the enforcing transport, returning credential headers, send permits, or protected responses. flowchart TD
A[Authenticated execution] --> B[Credential Proxy]
B --> C[Captured provider methods]
B --> D[OCC and IAM checks]
D --> E[Secret or prepared material]
E --> B
B --> F[Enforcing transport]
F --> G[Upstream provider]
Technical reviewBest possible solution: Retain provider ownership through the existing OCC lifecycle, add actionable conflict recovery messages, and establish the changed handoffs with final-effect evidence. Do we have a high-confidence way to reproduce the issue? Main visibly reselects a provider by type during updates, and the added integration scenario supplies a concrete two-provider reorder; no target code was run during this read-only review. Is this the best way to solve the issue? Pinning the saved provider reference and captured methods in OCC addresses the ownership error at its existing owner without changing Driver contracts or adding configuration. Full review comments:
Overall correctness: patch is correct AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against f9f304cfa9c3. Merge-risk optionsMaintainer options:
Provenance checked
TestingProof path: in-process harness. SecurityNone. EvidenceWhat I checked:
Likely related people:
Review metrics
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 27, 2026, 12:55 PM ET / 16:55 UTC. |
freeqaz
left a comment
There was a problem hiding this comment.
Free's clanker here (an AI agent working on Free's behalf). Comment-only review of 7514893cce.
Summary: correct as far as I can tell. I found no Driver-contract or IAM change and nothing that blocks landing.
Checked
- Update keeps the approved provider:
staticEgressProvider(type, previous)resolves the savedEgressRefinstead of picking by type in catalog order. When the saved provider is no longer registered,admittedisundefined. The default parameter ofadmitStaticEgressSourcethen falls back to catalog order. That path is reachable only with explicitliveadoption andexecutionscope, the same as main'salreadyAdmittedgate.assertCurrent()runs around the Secret read andinject. The savedprovideris the copiedref. - Request path: every candidate is captured before any
classifyruns, so one classifier cannot swap a later route's provider.checkEgressUseInuses the exchange's captured provider. That still matches the source's admitted provider, becauseadmitted.keymust deep-equaluse.route.binding.source, and the route'ssource.provideris the key the provider was resolved from.isCurrent()is checked at the Secret read port (beforereadCredentialInput), after selection, after injection, inauthorizeSendinside the transaction, after the send receipt commits, at stream-lease renewal and before response release. - Fail closed: a classifier or response-policy callback that throws now becomes a refusal or
response_blockedinstead of an exception. Two registrations with the sameid+generationrefuse asstale_configuration. - Contracts:
CredentialProviderDefinition,CredentialSourceControland the Driver interfaces are unchanged.EgressAuthorityPorts/ExchangeProviderare internal to OCC, and authorization calls are the same as before. The duplicate-ref refusal checks provider identity, which the contract already assumes, so I don't think it needs an RFC. - Identity stability: the OpenShell Driver builds
sourceControl.providersonce in its constructor, soports.provider(route) === receiverholds for the Driver's lifetime and changes only on reselection. - Tests:
credential-proxy-provider-pin.test.tsandegress-prepared-github-metadata.test.mjspassed 20/20 at 2 CPUs (11 tests per run, 0 skipped). The new file is inchecks-baseline-1with all 9 names inexpectedTests. CI Required and First Agent Smoke are green on this head. The PR merges cleanly with main and with #3873, #3876 and #3880.
Non-blocking
index.tsupdate path: the fallback relies on JS default-parameter semantics (admittedisundefined, soselection = this.staticEgressProvider(type)). An explicitadmitted ?? this.staticEgressProvider(source.type)at the call site, or a one-line comment, would make the re-adoption fallback easier to see.- The provider-pin tests change the fixture Driver's
providersarray in place. In production the list is fixed per Driver instance and changes only through reselection or a restart. A one-line comment saying the in-place edit stands in for that would help future readers judge the scenario. - If a saved provider is registered but now has a different
sourceType.type, the update fails with the generic "cannot protect<type>sources" message. That is fail-closed, but the message doesn't say why.
Updating an existing static source selected a provider by type a second time. If the catalog order changed, provider B could receive the source’s Secret and be saved in place of the approved provider A. OCC now resolves the saved provider reference on update. First enrollment keeps its existing selection order.
During a request, OCC retains the provider and methods it used for classification. An ambiguous eligible registration stops the request before Secret access. If the registration or a captured method changes while authorization or Secret access is pending, OCC refuses the handoff. An explicit binding to an unambiguous provider still works.
The tests change the catalog during source updates and requests, count Secret reads and verifier calls, and inspect the saved source after refusal. These checks cover OCC’s handling of the material. A Secret Driver’s accepted network read and a supervisor’s eventual write remain separate operations.