Skip to content

#2068: Isolate Claude Code configuration per IDEasy project#2087

Open
maybeec wants to merge 9 commits into
devonfw:mainfrom
maybeec:feature/claude-config-isolation
Open

#2068: Isolate Claude Code configuration per IDEasy project#2087
maybeec wants to merge 9 commits into
devonfw:mainfrom
maybeec:feature/claude-config-isolation

Conversation

@maybeec

@maybeec maybeec commented Jun 29, 2026

Copy link
Copy Markdown
Member

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 ~/.claude home (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 in 2026.07.001 did no isolation. This PR makes each IDEasy project a self-contained Claude configuration, fixing #2068.

Implemented changes:

  • Added EnvironmentContext.removeEnvVar(String) (no-op default) with a real unset in ProcessContextImpl, 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.setEnvironment now sets CLAUDE_CONFIG_DIR = $IDE_HOME/conf/claude — relocating Claude's settings, credentials, .claude.json, MCP servers and history into the project-local conf/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_DIR itself is never scrubbed. The single setEnvironment override covers both the launched process and ide env shell export.
  • Claude.postInstall seeds a user-owned conf/claude/settings.json + README.md when absent and never overwrites them; the isolated settings.json env block is the single source of truth for provider/auth config.
  • Added an IDE_HOME-gated claude shell function in cli/src/main/package/functions that routes bare claude through ide claude while an IDEasy project is active (transparent passthrough otherwise).
  • Documented the isolation model and its accepted limitations in documentation/ai.adoc.

Accepted shortcomings (by design): on macOS, Claude.ai subscription OAuth lives in the system Keychain, which CLAUDE_CONFIG_DIR does not relocate (Bedrock/API-token auth is unaffected); an enterprise managed-settings.json overrides all projects by design; a bare claude launched with no active IDEasy project is not scrubbed.


Testing instructions

  1. In an IDEasy project, run ide install claude, then confirm conf/claude/settings.json and conf/claude/README.md were created. Edit settings.json, re-run install, and confirm it is not overwritten.
  2. Run ide claude and confirm Claude stores its state under <IDE_HOME>/conf/claude (e.g. .claude.json, credentials) rather than ~/.claude.
  3. export ANTHROPIC_BASE_URL=https://leak.example and run ide claude; confirm the leaked value does not reach Claude (it is scrubbed), while a value declared in conf/claude/settings.json under env is honored.
  4. Set up a second IDEasy project and repeat; confirm the two projects use fully independent Claude configurations.
  5. Automated: mvn clean test. See ProcessContextImplTest and ClaudeTest, covering config-dir injection, the env scrub, no-overwrite seeding, and an end-to-end test asserting CLAUDE_CONFIG_DIR reaches the launched process.

Checklist for this PR

Make sure everything is checked before merging this PR. For further info please also see
our DoD.

  • When running mvn clean test locally all tests pass and build is successful
  • PR title is of the form #«issue-id»: «brief summary» (e.g. #921: fixed setup.bat). If no issue ID exists, title only.
  • PR top-level comment summarizes what has been done and contains link to addressed issue(s)
  • PR and issue(s) have suitable labels
  • Issue is set to In Progress and assigned to you or there is no issue (might happen for very small PRs)
  • You followed all coding conventions
  • You have added the issue implemented by your PR in CHANGELOG.adoc unless issue is labeled
    with internal
  • You have formulated clear instructions on how to test your contribution under "Testing instructions"

@github-project-automation github-project-automation Bot moved this to 🆕 New in IDEasy board Jun 29, 2026
@maybeec maybeec added enhancement New feature or request claude labels Jun 29, 2026
@maybeec maybeec moved this from 🆕 New to Team Review in IDEasy board Jun 29, 2026
@maybeec maybeec requested a review from hohwille June 29, 2026 19:01
@coveralls

coveralls commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 28444220737

Coverage increased (+0.03%) to 71.386%

Details

  • Coverage increased (+0.03%) from the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • 23 coverage regressions across 4 files.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

23 previously-covered lines in 4 files lost coverage.

File Lines Losing Coverage Coverage
com/devonfw/tools/ide/process/ProcessContextImpl.java 16 81.38%
com/devonfw/tools/ide/tool/claude/Claude.java 4 80.95%
com/devonfw/tools/ide/process/EnvironmentContext.java 2 0.0%
com/devonfw/tools/ide/tool/ide/IdeToolCommandlet.java 1 78.33%

Coverage Stats

Coverage Status
Relevant Lines: 16306
Covered Lines: 12139
Line Coverage: 74.44%
Relevant Branches: 7298
Covered Branches: 4711
Branch Coverage: 64.55%
Branches in Coverage %: Yes
Coverage Strength: 3.16 hits per line

💛 - Coveralls

@maybeec maybeec added this to the release:2026.07.001 milestone Jun 29, 2026
*/
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",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?

@hohwille hohwille Jun 30, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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?

Comment on lines +126 to +133
function claude() {
if [ -n "${IDE_HOME}" ]; then
ide claude "$@"
else
command claude "$@"
fi
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

Comment thread documentation/ai.adoc
Comment on lines +100 to +111
== 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

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.

@hohwille hohwille left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

@maybeec thanks for your PR. Excellent fix with a holistic solution. Great job 👍
I left some review comments for discussion and challenging (however, nothing wrong, just trying to trigger if we can improve further).

@github-project-automation github-project-automation Bot moved this from Team Review to 👀 In review in IDEasy board Jun 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude enhancement New feature or request

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

Claude: move config to project-local path

3 participants