Skip to content

Fix secret precedence in Oz CLI.#10157

Open
abhishekp106 wants to merge 1 commit intomasterfrom
abhishek/fix_secret_precedence
Open

Fix secret precedence in Oz CLI.#10157
abhishekp106 wants to merge 1 commit intomasterfrom
abhishek/fix_secret_precedence

Conversation

@abhishekp106
Copy link
Copy Markdown
Contributor

Description

Fixes an issue where secrets could collide if specified both as an auth secret and a generic secret. As part of that, we now enforce the following precedence order:

  1. Worker-injected env vars
  2. Any typed secrets (currently these are all auth secrets)
  3. Any generic secrets

We insert typed secrets atomically. If any env var that is part of the auth secret is present in the environment, we skip setting any part of that secret.

Testing

Tested locally that (2) takes precedence over (3).

Agent Mode

  • Warp Agent Mode - This PR was created via Warp's AI Agent Mode

@cla-bot cla-bot Bot added the cla-signed label May 5, 2026
@oz-for-oss
Copy link
Copy Markdown
Contributor

oz-for-oss Bot commented May 5, 2026

@abhishekp106

I'm starting a first review of this pull request.

I completed the review and no human review was requested for this pull request.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@abhishekp106 abhishekp106 requested a review from liliwilson May 5, 2026 16:38
Copy link
Copy Markdown
Contributor

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR centralizes managed-secret env-var construction, gives worker env vars precedence, and adds tests for typed-vs-generic secret precedence.

Concerns

  • Typed auth secrets that emit overlapping env vars can still overwrite each other in nondeterministic HashMap iteration order.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

}

for (env_name, env_value) in entries {
env_vars.insert(OsString::from(env_name), OsString::from(env_value));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] If two typed auth secrets emit the same env var, this insert lets the later HashMap iteration overwrite the earlier one, so Bedrock API-key vs access-key auth can produce nondeterministic credentials. Detect typed-secret env collisions and skip or fail deterministically before inserting.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine because we should only be resolving to one of these from the server, right? Might be good to document that invariant somewhere

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking for this PR, but it might be cleaner to set the auth env vars within the resolve_anthropic_api_key method (and same for codex)? At that point we actually know which one we're using, so we don't have to do the conflict detection 2x

Copy link
Copy Markdown
Contributor

@liliwilson liliwilson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice find - the precedence order you set LGTM!!

}

for (env_name, env_value) in entries {
env_vars.insert(OsString::from(env_name), OsString::from(env_value));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine because we should only be resolving to one of these from the server, right? Might be good to document that invariant somewhere

}
// 2. Typed AnthropicApiKey secret. The secret name does not have to match the env var.
for secret in secrets.values() {
if let ManagedSecretValue::AnthropicApiKey { api_key } = secret {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to be handling the other auth forms here (e.g. bedrock/otherwise) to prevent the auth popup from showing up? Or does claude just detect them automatically

}

for (env_name, env_value) in entries {
env_vars.insert(OsString::from(env_name), OsString::from(env_value));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking for this PR, but it might be cleaner to set the auth env vars within the resolve_anthropic_api_key method (and same for codex)? At that point we actually know which one we're using, so we don't have to do the conflict detection 2x

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants