AI-382: keep hosted tool credentials out of workflow history - #1752
Draft
xumaple wants to merge 1 commit into
Draft
AI-382: keep hosted tool credentials out of workflow history#1752xumaple wants to merge 1 commit into
xumaple wants to merge 1 commit into
Conversation
A hosted tool's credential is sent from workflow code to the model, so writing it into the tool config puts the credential in the workflow itself, on every model turn. There was no alternative: these are fields on OpenAI's own API types and the real token has to reach the provider. secret_reference() returns a placeholder carrying the name of an environment variable. The worker substitutes its value in _build_tool, immediately before the model call, so what the workflow holds is the variable's name. It applies to a hosted MCP tool's authorization and each header value, and to the value of each container domain secret on the hosted shell and code interpreter tools. Anything a provider or a remote MCP server sends back is deliberately out of scope. A counterparty that quotes a credential into its own error text is the counterparty's bug, and covering it would mean guessing at every way a string can be rendered. Also fixes a hosted ShellTool crash that blocked one of those sites: _build_tool passed an executor unconditionally, but upstream rejects one for a hosted environment, so every model turn raised UserError.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Giving a hosted tool a credential means putting it in the tool config, and the tool config travels from your workflow to the model as an activity argument. So the credential is written into workflow history on every model turn, readable by anyone who can open the run, and it stays there after you rotate it. There is no way to avoid it today:
authorization, header values and container domain secrets are fields on OpenAI's own API types, and the real token has to arrive at the provider.secret_reference("MY_MCP_TOKEN")returns a placeholder you put where the credential goes. The worker reads that variable from its own environment and substitutes the value immediately before the model call, so what the workflow holds is the variable's name. It covers a hosted MCP tool'sauthorizationand each header value, and thevalueof each container domain secret on the hosted shell and code interpreter tools. Set the variable on every worker that runs model activities; a worker without a value for it fails the call with a non-retryable error naming the variable.What it deliberately does not cover is anything a provider or a remote MCP server sends back. A counterparty that quotes your credential into its own error text is the counterparty's bug, and defending against it means guessing at every way a string can be rendered, which is not a set you can finish enumerating.
Note: hosted
ShellToolwas raisingUserErroron every model turn, because_build_toolpassed an executor unconditionally and upstream rejects one for a hosted environment. That made hosted shell tools unusable, and fixing it is a prerequisite for the domain-secret substitution there, so it rides along.