#2068: Isolate Claude Code configuration per IDEasy project#2087
#2068: Isolate Claude Code configuration per IDEasy project#2087maybeec wants to merge 9 commits into
Conversation
Coverage Report for CI Build 28444220737Coverage increased (+0.03%) to 71.386%Details
Uncovered ChangesNo uncovered changes found. Coverage Regressions23 previously-covered lines in 4 files lost coverage.
Coverage Stats💛 - Coveralls |
| */ | ||
| static final List<String> SCRUB_VARS = List.of( | ||
| "ANTHROPIC_API_KEY", "ANTHROPIC_AUTH_TOKEN", "ANTHROPIC_BASE_URL", | ||
| "ANTHROPIC_MODEL", "ANTHROPIC_SMALL_FAST_MODEL", "ANTHROPIC_CUSTOM_HEADERS", |
There was a problem hiding this comment.
I have configured ANTROPIC_MODEL and some other variables in my conf/ide.properties.
Does it really make sense to remove them all with no way to circumvent?
There was a problem hiding this comment.
For a project it would even make sense to configure variables like ANTROPIC_MODEL or BEDROCK_MODEL_ID in settings/ide.properties to share such settings across the team.
I am not convinced that nuking such variables generally is a good idea.
Maybe we should remove them only if they are not comming from ide.properties but are inherited from System environment variables?
| function claude() { | ||
| if [ -n "${IDE_HOME}" ]; then | ||
| ide claude "$@" | ||
| else | ||
| command claude "$@" | ||
| fi | ||
| } | ||
|
|
There was a problem hiding this comment.
nice idea to create such shim.
We once had some situation where a bug in IDEasy prevented to call a tool from IDEasy.
Such shim would take away the option to bypass IDEasy then for average users (who would not get to the idea to unload this function).
So - why would we need this or what would be the problem if we do not add this?
IMHO before running claude, we need to ide install claude what will already prepare the settings and set the variables. Surely if I switch projects with cd and not icd and do not also call some ide command before running the claude command directly, I might be connected to the wrong account.
Therefore I like your idea of this shim...
I am just thinking loud and challenging this so we balances pros and cons and take a clear decision.
| == Isolated Claude configuration | ||
|
|
||
| When you run multiple Claude Code configurations (e.g. different AWS Bedrock accounts, a sovereign endpoint, a company-wide instance), they normally interfere through the shared `~/.claude` home folder and through leaked environment variables. | ||
|
|
||
| IDEasy isolates Claude per project. Running `ide claude` (or simply `claude` while an IDEasy project is active): | ||
|
|
||
| * sets `CLAUDE_CONFIG_DIR` to `$IDE_HOME/conf/claude`, so settings, credentials, MCP servers and history are stored per project; | ||
| * removes leaking provider/auth variables (`ANTHROPIC_*`, `CLAUDE_CODE_USE_BEDROCK`/`VERTEX`/`FOUNDRY`, `CLAUDE_CODE_OAUTH_TOKEN`, `AWS_PROFILE`, `AWS_REGION`, `AWS_*_KEY*`, `AWS_SESSION_TOKEN`, `AWS_BEARER_TOKEN_BEDROCK`) from the launched process; | ||
| * seeds a user-owned `conf/claude/settings.json` skeleton on first install. | ||
|
|
||
| Put *all* provider/auth configuration in `conf/claude/settings.json` under the `env` block (see the generated `conf/claude/README.md` for Bedrock and custom-endpoint examples). | ||
| Because scrubbed variables such as `AWS_PROFILE` are removed from the process, declare them there rather than relying on your shell. |
There was a problem hiding this comment.
Should we add this specificity for Claude here?
IMHO we should explain the general concept and link to
https://github.com/devonfw/IDEasy/blob/main/documentation/sandbox.adoc
Then we can add such text as example.
But for Github Copilot I expect the same isolation - if not the case, we also need to file and fix a bug.
For AWS CLI we have it working and also for many other such tools.
This PR fixes #2068
Running multiple Claude Code configurations side by side (different AWS Bedrock accounts, a sovereign endpoint, a company-wide instance) interferes because Claude Code defaults all state to the shared
~/.claudehome (settings,.credentials.json,.claude.json, MCP servers, history) and because provider/auth environment variables (ANTHROPIC_*,AWS_*,CLAUDE_CODE_USE_BEDROCK, …) leak between contexts — and per Claude's auth precedence a stray variable silently overrides the intended endpoint. The Claude tool added in2026.07.001did no isolation. This PR makes each IDEasy project a self-contained Claude configuration, fixing #2068.Implemented changes:
EnvironmentContext.removeEnvVar(String)(no-op default) with a real unset inProcessContextImpl, so a tool can harden the launched process environment without ever touching the user's interactive shell (the shell-export collector keeps the no-op).Claude.setEnvironmentnow setsCLAUDE_CONFIG_DIR = $IDE_HOME/conf/claude— relocating Claude's settings, credentials,.claude.json, MCP servers and history into the project-localconf/claude— and scrubs leaking provider/auth variables (ANTHROPIC_*,CLAUDE_CODE_USE_BEDROCK/VERTEX/FOUNDRY,CLAUDE_CODE_OAUTH_TOKEN,AWS_*) from the child process.CLAUDE_CONFIG_DIRitself is never scrubbed. The singlesetEnvironmentoverride covers both the launched process andide envshell export.Claude.postInstallseeds a user-ownedconf/claude/settings.json+README.mdwhen absent and never overwrites them; the isolatedsettings.jsonenvblock is the single source of truth for provider/auth config.IDE_HOME-gatedclaudeshell function incli/src/main/package/functionsthat routes bareclaudethroughide claudewhile an IDEasy project is active (transparent passthrough otherwise).documentation/ai.adoc.Accepted shortcomings (by design): on macOS, Claude.ai subscription OAuth lives in the system Keychain, which
CLAUDE_CONFIG_DIRdoes not relocate (Bedrock/API-token auth is unaffected); an enterprisemanaged-settings.jsonoverrides all projects by design; a bareclaudelaunched with no active IDEasy project is not scrubbed.Testing instructions
ide install claude, then confirmconf/claude/settings.jsonandconf/claude/README.mdwere created. Editsettings.json, re-run install, and confirm it is not overwritten.ide claudeand confirm Claude stores its state under<IDE_HOME>/conf/claude(e.g..claude.json, credentials) rather than~/.claude.export ANTHROPIC_BASE_URL=https://leak.exampleand runide claude; confirm the leaked value does not reach Claude (it is scrubbed), while a value declared inconf/claude/settings.jsonunderenvis honored.mvn clean test. SeeProcessContextImplTestandClaudeTest, covering config-dir injection, the env scrub, no-overwrite seeding, and an end-to-end test assertingCLAUDE_CONFIG_DIRreaches the launched process.Checklist for this PR
Make sure everything is checked before merging this PR. For further info please also see
our DoD.
mvn clean testlocally all tests pass and build is successful#«issue-id»: «brief summary»(e.g.#921: fixed setup.bat). If no issue ID exists, title only.In Progressand assigned to you or there is no issue (might happen for very small PRs)with
internal