Skip to content

fix(auth): cloud provider model mapping, env forwarding, Vertex/Bedrock auth support#2059

Closed
thedotmack wants to merge 2 commits intomainfrom
bugfix/auth-bugs
Closed

fix(auth): cloud provider model mapping, env forwarding, Vertex/Bedrock auth support#2059
thedotmack wants to merge 2 commits intomainfrom
bugfix/auth-bugs

Conversation

@thedotmack
Copy link
Copy Markdown
Owner

Summary

Test plan

  • Verify Bedrock env vars (CLAUDE_CODE_USE_BEDROCK, AWS_REGION, AWS_ACCESS_KEY_ID, etc.) are forwarded through env-sanitizer
  • Verify Vertex env vars (CLAUDE_CODE_USE_VERTEX, GOOGLE_APPLICATION_CREDENTIALS, GOOGLE_CLOUD_PROJECT) are forwarded through env-sanitizer
  • Verify ANTHROPIC_AUTH_TOKEN is parsed from .env, persisted, and forwarded in buildIsolatedEnv
  • Verify clear error when OpenRouter key is missing (not a 401)
  • Verify model ID mapping logs for cloud providers
  • Verify auth method override when Vertex/Bedrock detected
  • Verify warning when cloud provider detected but credentials missing

Closes #1942, closes #1943, closes #1944, closes #1945, closes #1946

🤖 Generated with Claude Code

…ck auth support

- #1942: Add Bedrock/Vertex model ID translation (e.g. claude-sonnet-4-6 -> provider format)
- #1943: Allowlist CLAUDE_CODE_USE_BEDROCK/VERTEX and AWS_*/Google env vars in env-sanitizer
- #1944: Add ANTHROPIC_AUTH_TOKEN to managed credential keys for parse/persist/forward
- #1945: Skip OAuth validation when Vertex/Bedrock detected, override auth method to 'api'
- #1946: Validate OpenRouter API key before request to prevent cryptic 401 errors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 18, 2026

Warning

Rate limit exceeded

@thedotmack has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 5 minutes and 51 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 5 minutes and 51 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 31831151-2c91-4b18-92a5-42ab2dd79579

📥 Commits

Reviewing files that changed from the base of the PR and between 953a863 and 9c6b552.

📒 Files selected for processing (3)
  • src/services/worker/OpenRouterAgent.ts
  • src/shared/EnvManager.ts
  • src/shared/SettingsDefaultsManager.ts

Walkthrough

These changes extend Claude Code's configuration and authentication system to support cloud providers (AWS Bedrock and Google Cloud Vertex AI). They add model resolution logic based on cloud provider detection, manage provider-specific credentials through existing configuration systems, forward cloud provider environment variables to spawned SDK processes, and validate auth methods appropriate to each provider.

Changes

Cohort / File(s) Summary
Configuration and Model Resolution
src/shared/SettingsDefaultsManager.ts
Added cloud-provider detection (detectCloudProvider), model identifier remapping for Bedrock/Vertex (resolveModelForCloudProvider with provider-specific mapping tables), and auth method validation/override (validateCloudProviderAuth). Modified get() to resolve CLAUDE_MEM_MODEL through provider mapping and loadFromFile() to apply provider detection in both success and error paths.
Credential Management
src/shared/EnvManager.ts
Added ANTHROPIC_AUTH_TOKEN to MANAGED_CREDENTIAL_KEYS and ClaudeMemEnv interface. Updated buildIsolatedEnv to forward ANTHROPIC_AUTH_TOKEN from claude-mem's .env into spawned SDK subprocess environment.
Environment Variable Preservation
src/supervisor/env-sanitizer.ts
Introduced CLOUD_PROVIDER_ENV_VARS allowlist for AWS Bedrock (region/credential variables) and Google Cloud Vertex AI (credential/project variables). Updated sanitizeEnv to preserve these cloud provider variables and added CLAUDE_CODE_USE_BEDROCK/CLAUDE_CODE_USE_VERTEX to ENV_PRESERVE.
API Key Validation
src/services/worker/OpenRouterAgent.ts
Added early validation check in queryOpenRouterMultiTurn to throw clear configuration error when apiKey is empty or undefined, before API call attempt.

Sequence Diagram(s)

No sequence diagrams generated — changes are primarily configuration initialization, validation logic, and environment variable management without complex multi-step interactions warranting visualization.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 A hop through the clouds, now Bedrock and Vertex align,
Models remapped, auth validated—no more "not logged in,"
AWS whispers, Google Cloud sings, credentials now gleam,
The rabbit adjusts the config—a multi-cloud dream! 🌩️✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: cloud provider model mapping and environment variable forwarding for Vertex/Bedrock auth support.
Description check ✅ Passed The description provides detailed explanations of all five fixes, test plan items, and correctly links all five related issues.
Linked Issues check ✅ Passed The PR successfully addresses all five linked issues: model mapping for cloud providers [#1942], env forwarding for cloud credentials [#1943], ANTHROPIC_AUTH_TOKEN support [#1944], Vertex/Bedrock auth method override [#1945], and OpenRouter API key validation [#1946].
Out of Scope Changes check ✅ Passed All code changes are directly related to the five linked issues and the stated PR objectives; no out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bugfix/auth-bugs

Comment @coderabbitai help to get the list of available commands and usage tips.

@claude
Copy link
Copy Markdown

claude Bot commented Apr 18, 2026

Code Review

Overview

This PR bundles 5 related fixes for cloud provider (Bedrock/Vertex) and auth support: model ID translation, env var forwarding, ANTHROPIC_AUTH_TOKEN management, auth method override, and OpenRouter key validation. The changes are closely related and the grouping is reasonable.


Strengths

  • Consistent patterns: ANTHROPIC_AUTH_TOKEN handling mirrors the existing ANTHROPIC_API_KEY pattern throughout EnvManager.ts — load, save, and forward all updated in lockstep.
  • Clean separation: CLOUD_PROVIDER_ENV_VARS as a named exported Set in env-sanitizer.ts makes the allowlist easy to audit and extend.
  • Early validation: The OpenRouter guard throws with a clear, actionable message before touching the network — exactly right.
  • Error path consistency: resolveModelForCloudProvider and validateCloudProviderAuth are applied on both the success and error paths in loadSettings().

Issues & Suggestions

1. Hardcoded version suffixes will go stale (medium)

'claude-sonnet-4-6': 'anthropic.claude-sonnet-4-6-v1:0',
'claude-sonnet-4-6': 'claude-sonnet-4-6@20250514',

The :v1:0 / @20250514 strings will need manual updates with every new model version. Consider whether the mapping should live in a config file or settings, making it user-patchable without a code release.

2. Missing current models in the maps (medium)

claude-haiku-4-5 and claude-opus-4-7 are absent from both BEDROCK_MODEL_MAP and VERTEX_MODEL_MAP. Users on those models will hit the "no mapping found" warning path and get an untranslated model ID, which will likely cause a hard API error.

3. Double resolveModelForCloudProvider call (low)

get('CLAUDE_MEM_MODEL') applies the mapping, and loadSettings() also calls it explicitly on the returned object. If any caller uses loadSettings() and then later calls get('CLAUDE_MEM_MODEL'), the mapping runs twice. It's effectively idempotent (a Bedrock ID won't match a second time), but it's a hidden invariant that's easy to break. Consider applying the mapping in only one place.

4. False-positive warnings for credential-less auth (low)

The Bedrock warning fires when no AWS_* vars are set, but IAM role-based auth (instance profiles, ECS task roles, IRSA) intentionally has no env vars. Similarly for Vertex with Workload Identity on GKE. The warnings could mislead users whose auth is working correctly. Consider adding a note like "This warning can be ignored if using IAM role or Workload Identity auth."

5. validateCloudProviderAuth mutates its argument (low)

settings.CLAUDE_MEM_CLAUDE_AUTH_METHOD = 'api';

Mutating the settings object passed in is a surprising side effect. A cleaner pattern returns the modified value or takes a settings ref explicitly. At minimum, the JSDoc should note this mutation.

6. AWS_SECRET_ACCESS_KEY forwarded via CLOUD_PROVIDER_ENV_VARS (informational)

This is correct and necessary, but it's worth a comment in the code noting that cloud provider users have reduced env isolation by design. Future reviewers might otherwise flag this as a security regression without context.


Test Coverage

The test plan is entirely manual. Given the complexity of the model-mapping logic and the auth override behavior, unit tests would catch regressions cheaply:

  • resolveModelForCloudProvider with each provider/model combination, including the unmapped case
  • detectCloudProvider with the various truthy env var forms ("1", "true")
  • sanitizeEnv with cloud provider vars present

Summary

Solid fixes for a real pain point — the patterns are consistent and the intent is clear. The two medium items (stale version strings, missing models) are the ones most likely to produce user-facing errors before the next release.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 18, 2026

Greptile Summary

This PR adds cloud provider (Bedrock/Vertex) awareness to model ID resolution and auth method selection, allowlists cloud credential env vars through the sanitizer, adds ANTHROPIC_AUTH_TOKEN to managed credentials, and adds a pre-flight OpenRouter API key check.

  • P1 — SettingsDefaultsManager.loadFromFile: When no settings file exists yet (first-time user), the early-return path at line 337 skips both resolveModelForCloudProvider and validateCloudProviderAuth. New Bedrock/Vertex users will receive an untranslated model ID and no auth-method override on first run.

Confidence Score: 4/5

Safe to merge after fixing the no-settings-file early-return path in loadFromFile.

One P1 bug: first-time users with Bedrock/Vertex enabled won't get model ID translation or auth override because the no-file early-return skips the new cloud provider processing. The other three files are clean. The P2 findings (log spam, misleading credential warning) are non-blocking.

src/shared/SettingsDefaultsManager.ts — the no-settings-file early return path needs the same model resolution and auth validation applied in the happy path.

Important Files Changed

Filename Overview
src/shared/SettingsDefaultsManager.ts Adds cloud provider model mapping, auth detection, and startup validation — but the no-settings-file early return path skips both model resolution and auth override (P1), and model resolution logs on every get() call (P2).
src/supervisor/env-sanitizer.ts Adds CLAUDE_CODE_USE_BEDROCK/CLAUDE_CODE_USE_VERTEX to ENV_PRESERVE (correct) and creates CLOUD_PROVIDER_ENV_VARS allowlist — the AWS/Google vars were already passing through the filter, so this is explicit but harmless documentation.
src/shared/EnvManager.ts Adds ANTHROPIC_AUTH_TOKEN to managed credential keys, ClaudeMemEnv interface, load/save logic, and buildIsolatedEnv forwarding — complete and consistent with existing credential handling.
src/services/worker/OpenRouterAgent.ts Adds pre-flight API key validation in queryOpenRouterMultiTurn to throw a clear error instead of a cryptic 401 — straightforward and correct.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[loadFromFile called] --> B{settings file exists?}
    B -- No --> C[applyEnvOverrides defaults]
    C --> C1[⚠️ resolveModelForCloudProvider SKIPPED]
    C1 --> C2[⚠️ validateCloudProviderAuth SKIPPED]
    C2 --> Z[Return settings]
    B -- Yes --> D[Read + merge file settings]
    D --> E[applyEnvOverrides]
    E --> F[resolveModelForCloudProvider]
    F --> G{cloud provider detected?}
    G -- bedrock --> H[Map model ID via BEDROCK_MODEL_MAP]
    G -- vertex --> I[Map model ID via VERTEX_MODEL_MAP]
    G -- none --> J[Return unchanged model ID]
    H --> K[validateCloudProviderAuth]
    I --> K
    J --> K
    K --> L{auth method = cli?}
    L -- Yes + provider set --> M[Override to api]
    L -- No --> N[Keep as-is]
    M --> Z
    N --> Z
    B -- Error --> P[applyEnvOverrides getAllDefaults]
    P --> Q[resolveModelForCloudProvider]
    Q --> R[validateCloudProviderAuth]
    R --> Z
Loading

Comments Outside Diff (1)

  1. src/shared/SettingsDefaultsManager.ts, line 336-337 (link)

    P1 Cloud provider processing skipped for first-time users

    When loadFromFile is called and no settings file exists yet, the early return at line 337 bypasses both resolveModelForCloudProvider and validateCloudProviderAuth. This means a brand-new user running with CLAUDE_CODE_USE_BEDROCK=1 will get an unmapped model ID (e.g. claude-sonnet-4-6 instead of anthropic.claude-sonnet-4-6-v1:0) and the auth method will not be overridden from cli to api.

    Fix in Claude Code

Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix(auth): cloud provider model mapping,..." | Re-trigger Greptile

Comment on lines 271 to +277
static get(key: keyof SettingsDefaults): string {
return process.env[key] ?? this.DEFAULTS[key];
const value = process.env[key] ?? this.DEFAULTS[key];
// Resolve cloud-provider-specific model ID when reading the model setting
if (key === 'CLAUDE_MEM_MODEL') {
return this.resolveModelForCloudProvider(value);
}
return 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.

P2 Console log spam on every get('CLAUDE_MEM_MODEL') call

resolveModelForCloudProvider unconditionally calls console.log/console.warn each time it runs, and get('CLAUDE_MEM_MODEL') is the hot path for reading any model setting. Every call throughout the application's lifecycle will emit the mapping message (or warning), flooding the console rather than logging once at startup.

Consider logging only when loadFromFile resolves the model (startup), or use a boolean flag to log the mapping/warning only once.

Fix in Claude Code

Comment thread src/shared/SettingsDefaultsManager.ts Outdated

if (provider === 'bedrock') {
// Bedrock uses AWS IAM — OAuth token and ANTHROPIC_API_KEY are not required
if (!process.env.AWS_ACCESS_KEY_ID && !process.env.AWS_PROFILE && !process.env.AWS_DEFAULT_REGION && !process.env.AWS_REGION) {
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.

P2 Bedrock warning fires for valid ~/.aws credential configurations

The condition includes !process.env.AWS_DEFAULT_REGION and !process.env.AWS_REGION as part of the "no credentials" check, but those are region vars, not auth credentials. A user whose credentials live in ~/.aws/credentials (the default shared-credential file setup) will have no AWS env vars set at all yet have perfectly valid credentials. The warning will fire as a false positive for this common AWS setup.

Consider narrowing to actual credential indicators only:

Suggested change
if (!process.env.AWS_ACCESS_KEY_ID && !process.env.AWS_PROFILE && !process.env.AWS_DEFAULT_REGION && !process.env.AWS_REGION) {
if (!process.env.AWS_ACCESS_KEY_ID && !process.env.AWS_PROFILE) {

Fix in Claude Code

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/shared/SettingsDefaultsManager.ts (1)

323-337: ⚠️ Potential issue | 🟠 Major

Apply cloud-provider resolution in the no-file branch too.

When settingsPath does not exist, this branch returns right after applyEnvOverrides(defaults). Fresh Bedrock/Vertex installs therefore miss both the model remap and the cliapi auth-method override on first run.

🔧 Proposed fix
-        return this.applyEnvOverrides(defaults);
+        const final = this.applyEnvOverrides(defaults);
+        final.CLAUDE_MEM_MODEL = this.resolveModelForCloudProvider(final.CLAUDE_MEM_MODEL);
+        this.validateCloudProviderAuth(final);
+        return final;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/SettingsDefaultsManager.ts` around lines 323 - 337, When
settingsPath doesn't exist, after creating defaults and before returning, run
the same resolution steps the file-exists branch performs so new installs get
cloud-provider resolution, model remap and the cli→api auth-method override;
specifically, call the same helper(s) used elsewhere to apply cloud-provider
resolution and model-remap/auth-override (rather than only applyEnvOverrides)
and then return the resolved settings from this.applyEnvOverrides(defaults).
Keep getAllDefaults(), the settingsPath creation code and the console warn, but
ensure you invoke the existing resolution routines (the cloud-provider
resolution and model remap/auth override helpers used in the other branch)
before returning.
🧹 Nitpick comments (1)
src/shared/SettingsDefaultsManager.ts (1)

201-203: Consider de-duplicating these provider logs.

These messages are emitted every time settings are loaded, so under the normal loadFromFile(USER_SETTINGS_PATH) flow they will repeat on ordinary request traffic. A once-per-process guard would keep them useful.

Based on learnings, SettingsDefaultsManager.loadFromFile(USER_SETTINGS_PATH) is intentionally called per request.

Also applies to: 234-251

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/shared/SettingsDefaultsManager.ts` around lines 201 - 203, The provider
mapping log in SettingsDefaultsManager (the block that logs `[SETTINGS] Cloud
provider "${provider}" detected — mapping model "${modelId}" → "${mapped}"` when
`mapped` is truthy, and the similar logs around the 234-251 region) should be
emitted only once per process to avoid noisy repetition; add a module-level
guard (e.g., a Set<string> or boolean map keyed by `provider` or
`provider|modelId`) and check it before logging, then mark the provider as
logged after the first log; update the logging points that reference `provider`,
`modelId`, and `mapped` to consult this guard so subsequent calls to
`SettingsDefaultsManager.loadFromFile` skip duplicate logs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/services/worker/OpenRouterAgent.ts`:
- Around line 373-380: The current fail-fast guard in OpenRouterAgent.ts checks
only falsy apiKey but allows whitespace-only strings; update the check around
the apiKey variable (the block that throws "OpenRouter API key not
configured...") to treat whitespace-only values as missing by using a trimmed
check (e.g., if (!apiKey || apiKey.trim().length === 0)) so a key of only spaces
will throw the same clear Error; keep the existing error message and throw site
(the same throw in the OpenRouterAgent initialization) unchanged otherwise.

In `@src/shared/EnvManager.ts`:
- Around line 239-242: In buildIsolatedEnv(), remove any ambient/inherited
ANTHROPIC_AUTH_TOKEN from the isolatedEnv before re-injecting the managed
credential: explicitly clear/delete isolatedEnv.ANTHROPIC_AUTH_TOKEN (or avoid
copying it earlier) and then set isolatedEnv.ANTHROPIC_AUTH_TOKEN =
credentials.ANTHROPIC_AUTH_TOKEN only when credentials.ANTHROPIC_AUTH_TOKEN is
present; reference symbols: buildIsolatedEnv, isolatedEnv, and
credentials.ANTHROPIC_AUTH_TOKEN.

In `@src/shared/SettingsDefaultsManager.ts`:
- Around line 191-196: The helper resolveModelForCloudProvider currently treats
only process.env.CLAUDE_MEM_MODEL as explicit but is also called from
loadFromFile on merged settings, causing user-saved CLAUDE_MEM_MODEL from
settings.json to be remapped; change resolveModelForCloudProvider so it only
skips remapping when the incoming modelId equals the hardcoded default (i.e.,
perform mapping only if modelId === <the default constant or literal default
value>), and keep the existing early-return for process.env.CLAUDE_MEM_MODEL;
apply the same fix to the other occurrence referenced around lines 368–370 so
saved settings are not rewritten or warned about.

---

Outside diff comments:
In `@src/shared/SettingsDefaultsManager.ts`:
- Around line 323-337: When settingsPath doesn't exist, after creating defaults
and before returning, run the same resolution steps the file-exists branch
performs so new installs get cloud-provider resolution, model remap and the
cli→api auth-method override; specifically, call the same helper(s) used
elsewhere to apply cloud-provider resolution and model-remap/auth-override
(rather than only applyEnvOverrides) and then return the resolved settings from
this.applyEnvOverrides(defaults). Keep getAllDefaults(), the settingsPath
creation code and the console warn, but ensure you invoke the existing
resolution routines (the cloud-provider resolution and model remap/auth override
helpers used in the other branch) before returning.

---

Nitpick comments:
In `@src/shared/SettingsDefaultsManager.ts`:
- Around line 201-203: The provider mapping log in SettingsDefaultsManager (the
block that logs `[SETTINGS] Cloud provider "${provider}" detected — mapping
model "${modelId}" → "${mapped}"` when `mapped` is truthy, and the similar logs
around the 234-251 region) should be emitted only once per process to avoid
noisy repetition; add a module-level guard (e.g., a Set<string> or boolean map
keyed by `provider` or `provider|modelId`) and check it before logging, then
mark the provider as logged after the first log; update the logging points that
reference `provider`, `modelId`, and `mapped` to consult this guard so
subsequent calls to `SettingsDefaultsManager.loadFromFile` skip duplicate logs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f0a933e6-a322-4d4d-ae7a-8f5f13496281

📥 Commits

Reviewing files that changed from the base of the PR and between beea789 and 953a863.

📒 Files selected for processing (4)
  • src/services/worker/OpenRouterAgent.ts
  • src/shared/EnvManager.ts
  • src/shared/SettingsDefaultsManager.ts
  • src/supervisor/env-sanitizer.ts

Comment thread src/services/worker/OpenRouterAgent.ts
Comment thread src/shared/EnvManager.ts
Comment thread src/shared/SettingsDefaultsManager.ts
…ial checks, env isolation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@claude
Copy link
Copy Markdown

claude Bot commented Apr 18, 2026

Code Review

Overview

This PR adds cloud provider awareness (Bedrock/Vertex AI) for model ID resolution, fixes env var forwarding for AWS/GCP credentials, adds ANTHROPIC_AUTH_TOKEN as a managed credential, and improves OpenRouter API key validation. The intent is solid and the changes are generally well-structured.


Issues & Suggestions

OpenRouterAgent.ts — Duplicate validation (minor bug)

The new check at ~line 377 is redundant — there's already an identical guard at ~line 91 (before logTelemetry) that throws the same error. Unless there's a code path that bypasses the first check, the second is dead code. If the intent is to catch a race where apiKey becomes empty after the first check, that scenario isn't possible with synchronous config reads. Recommend removing the duplicate.

SettingsDefaultsManager.tsresolveModelForCloudProvider called in two code paths

get('CLAUDE_MEM_MODEL') applies the remapping, and load() also applies it to the returned SettingsDefaults object. These are independent paths (one reads process.env/DEFAULTS, the other reads the settings file), so there's no double-mapping in practice — but it creates a subtle contract: callers using the load() result get a pre-mapped model, while callers using get() get it mapped on the fly. A comment documenting this intentional split would prevent future confusion.

SettingsDefaultsManager.tsvalidateCloudProviderAuth mutates its argument

settings.CLAUDE_MEM_CLAUDE_AUTH_METHOD = 'api'; // side effect on caller's object

Mutation of a passed-in settings object is surprising. Consider returning a new object or returning a boolean/enum that the caller uses to decide whether to override. The current approach works but makes unit testing harder and the call site behavior implicit.

SettingsDefaultsManager.ts — Sparse model maps create a silent future hazard

Only 3 models are in each map. When the default CLAUDE_MEM_MODEL is bumped to claude-opus-4-7 or claude-haiku-4-5, the unmapped warning fires — which is the correct fallback behavior, but users upgrading will get noisy warnings without an obvious fix. Consider:

  1. Adding the full current Claude 4.x family to the maps now, or
  2. Documenting in a comment that the maps must be kept in sync with DEFAULTS.CLAUDE_MEM_MODEL.

env-sanitizer.ts — Two sets with identical behavior

ENV_PRESERVE and CLOUD_PROVIDER_ENV_VARS both result in the same action (sanitized[key] = value; continue). Having two sets is reasonable for semantic grouping, but it'd be worth a brief comment explaining why they're kept separate (e.g. "separated for clarity, not different behavior").

EnvManager.tsAWS_DEFAULT_REGION inconsistency

CLOUD_PROVIDER_ENV_VARS in env-sanitizer.ts includes AWS_DEFAULT_REGION, but the credential warning in validateCloudProviderAuth only checks AWS_REGION. Small inconsistency — the warning should also accept AWS_DEFAULT_REGION as satisfying the region requirement:

if (!process.env.AWS_ACCESS_KEY_ID && !process.env.AWS_PROFILE) {
  // also check AWS_REGION || AWS_DEFAULT_REGION

Security Observations

  • Forwarding AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN through the sanitizer is necessary for Bedrock but expands the credential surface area passed to SDK subprocesses. This is acceptable given the explicit opt-in (CLAUDE_CODE_USE_BEDROCK=1), but worth flagging in the security audit trail.
  • Adding ANTHROPIC_AUTH_TOKEN to BLOCKED_ENV_VARS (so ambient values are stripped and only managed credentials are used) is the right approach — avoids credential precedence surprises.

Tests

None of the test plan checkboxes are checked and no test files appear in the diff. Given this touches auth flows and credential forwarding, at least a unit test for:

  • resolveModelForCloudProvider with all three env combinations (none/bedrock/vertex)
  • sanitizeEnv preserving CLOUD_PROVIDER_ENV_VARS
  • loadClaudeMemEnv / saveClaudeMemEnv round-trip for ANTHROPIC_AUTH_TOKEN

...would significantly reduce regression risk here.


Summary

The approach is correct and addresses real user pain with cloud providers. Main asks before merging:

  1. Remove the duplicate OpenRouter key check
  2. Add AWS_DEFAULT_REGION to the Bedrock credential presence check
  3. Consider test coverage for the new auth/mapping paths

Good PR overall.

@thedotmack
Copy link
Copy Markdown
Owner Author

Closing to start fresh from main — will redo fixes isolated in Docker container.

@thedotmack thedotmack closed this Apr 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant