Conversation
Providers::Base#inspect has redacted the key since the provider classes landed, which covers logs and error output. It does not cover serialization, because neither serializer asks inspect anything. Verified on 3.3.8 and 3.4.8: Marshal.dump(provider) and YAML.dump(provider) both contained the key verbatim, and so did YAML.dump(client) -- the client holds the provider, and YAML walks to it where Marshal gives up on the Procs. That is a plaintext key in a cache entry, a Sidekiq argument, a config dump, or a crash report, from an object that looks redacted when you print it. Do not serialize it. marshal_dump/encode_with write the base URL and nothing else; marshal_load/init_with read the key back from the provider's environment variable, which is where a long-lived process should be getting it. A provider restored without that variable set has no key, and building a Client from it raises ConfigurationError -- a loud failure rather than a Bearer header with nothing after it. api_key stays readable in process. The leak was never deliberate access. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Providers::Base#inspecthas redacted the API key since the provider classes landed. Serialization does not go throughinspect, and nothing covered it.Verified on Ruby 3.2.11, 3.3.8 and 3.4.8:
YAML.dump(client)leaks too — it walks to the provider, whereMarshal.dump(client)merely gives up on theProctransport.That is a plaintext key in a cache entry, a background-job argument, a config dump or a crash report, produced by an object that looks redacted when you print it.
The fix
Don't serialize the key.
marshal_dump/encode_withwrite the base URL and nothing else;marshal_load/init_withread the key back from the provider's environment variable, which is where a long-lived process should be getting it anyway.A provider restored without that variable set has no key, and building a
Clientfrom it raisesConfigurationError— a loud failure rather than aBearerheader with nothing after it.api_keystays readable in process; the leak was never deliberate access.Tests
test/redaction_test.rb, 11 cases: both serializers for every registered provider, the client-level YAML walk, base URL survival, environment round-trip, and the no-key-in-env failure. Suite green on 3.2.11 / 3.3.8 / 3.4.8.One of a series from a security and API-coverage audit. Branches are independent, each off
main, so they can be taken in any order or individually.🤖 Generated with Claude Code