openclaw - 💡(How to fix) Fix Feature: per-agent env-var scoping (agents.list[].env.vars) to prevent credential leak across agents

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Add per-agent env-var scoping at agents.list[].env.vars (mirroring the existing top-level env.vars), so each agent's Bash tool calls — and any tools that read process.env — see only that agent's credentials.

Today, env.vars is global. Every agent inherits the union of all credentials (e.g. GITHUB_TOKEN, LOIS_GITHUB_TOKEN, HELGEM_GITHUB_TOKEN). That breaks identity isolation for any CLI tool the agent shells out to (gh, git, cloud CLIs, custom scripts), and silently leaks one agent's credentials into another agent's process.

Root Cause

Symptom: shared ~/.config/gh/hosts.yml gets rewritten by whichever agent last ran gh auth setup-git (often during plugin/skill init). Mid-session, my agent silently flipped to Lois's identity and a label-edit call returned 403 because her PAT scopes are narrower. Same risk exists for ~/.gitconfig, ~/.npmrc, etc.

Fix Action

Fix / Workaround

Workaround in use today

  • #67682 — Per-agent MCP env var injection (subset: MCP only)
  • #37584 — Per-agent tool settings, e.g. tools.web.search.apiKey (subset: specific tools)
  • #78063 — GH CLI auth missed when agent HOME differs from root config (different direction: workaround sets one global GH_CONFIG_DIR)
  • #78965 — Per-agent Unix sandbox backend (heavier solution: full OS-user isolation)

Code Example

$ env | grep -iE "token|github"
GITHUB_USERNAME=<set>
GITHUB_EMAIL=<set>
LOIS_GITHUB_TOKEN=<set>     # leaked into alejandro's process env
LOIS_GITHUB_USERNAME=<set>
LOIS_GITHUB_EMAIL=<set>
HELGEM_GITHUB_TOKEN=<set>
OPENCLAW_SERVICE_MANAGED_ENV_KEYS=GITHUB_EMAIL,GITHUB_USERNAME

---

{
  env: {
    vars: {
      // global defaults — kept for backwards compat
      GITHUB_USERNAME: "ops-bot",
    },
  },
  agents: {
    list: [
      {
        id: "alejandro",
        env: {
          vars: {
            GITHUB_TOKEN: "ghp_alejandro_xxxxx",
            GITHUB_USERNAME: "alejandroiman85",
            GITHUB_EMAIL: "[email protected]",
          },
        },
      },
      {
        id: "lois",
        env: {
          vars: {
            GITHUB_TOKEN: "ghp_lois_xxxxx",
            GITHUB_USERNAME: "loisgriffin85",
            GITHUB_EMAIL: "[email protected]",
          },
        },
      },
    ],
  },
}
RAW_BUFFERClick to expand / collapse

Feature type

Configuration / multi-agent isolation

Summary

Add per-agent env-var scoping at agents.list[].env.vars (mirroring the existing top-level env.vars), so each agent's Bash tool calls — and any tools that read process.env — see only that agent's credentials.

Today, env.vars is global. Every agent inherits the union of all credentials (e.g. GITHUB_TOKEN, LOIS_GITHUB_TOKEN, HELGEM_GITHUB_TOKEN). That breaks identity isolation for any CLI tool the agent shells out to (gh, git, cloud CLIs, custom scripts), and silently leaks one agent's credentials into another agent's process.

Current behavior (verified on 2026.5.7)

Searched the runtime schema for any per-agent env slot — none exists. The closest agent-scoped fields are agents.list[].runtime, .tools, .skills, .contextLimits, .thinkingDefault — but no env.

Concretely, on a two-agent setup (alejandro + lois):

$ env | grep -iE "token|github"
GITHUB_USERNAME=<set>
GITHUB_EMAIL=<set>
LOIS_GITHUB_TOKEN=<set>     # leaked into alejandro's process env
LOIS_GITHUB_USERNAME=<set>
LOIS_GITHUB_EMAIL=<set>
HELGEM_GITHUB_TOKEN=<set>
OPENCLAW_SERVICE_MANAGED_ENV_KEYS=GITHUB_EMAIL,GITHUB_USERNAME

OpenClaw already partially scopes: OPENCLAW_SERVICE_MANAGED_ENV_KEYS=GITHUB_EMAIL,GITHUB_USERNAME shows the harness manages those two per agent. But token vars are not in the managed set — they bleed through to every agent.

Symptom: shared ~/.config/gh/hosts.yml gets rewritten by whichever agent last ran gh auth setup-git (often during plugin/skill init). Mid-session, my agent silently flipped to Lois's identity and a label-edit call returned 403 because her PAT scopes are narrower. Same risk exists for ~/.gitconfig, ~/.npmrc, etc.

Proposed solution

{
  env: {
    vars: {
      // global defaults — kept for backwards compat
      GITHUB_USERNAME: "ops-bot",
    },
  },
  agents: {
    list: [
      {
        id: "alejandro",
        env: {
          vars: {
            GITHUB_TOKEN: "ghp_alejandro_xxxxx",
            GITHUB_USERNAME: "alejandroiman85",
            GITHUB_EMAIL: "[email protected]",
          },
        },
      },
      {
        id: "lois",
        env: {
          vars: {
            GITHUB_TOKEN: "ghp_lois_xxxxx",
            GITHUB_USERNAME: "loisgriffin85",
            GITHUB_EMAIL: "[email protected]",
          },
        },
      },
    ],
  },
}

Semantics: agents.list[].env.vars deep-merges over global env.vars for that agent's process env. Keys defined only globally still inherit. Keys defined per-agent override globally. Vars defined only by other agents are not present.

This naturally composes with the related issues — MCP env (#67682) and tool settings (#37584) can both default to inheriting from agents.list[].env.

Workaround in use today

Wrapper scripts (gh-as <agent>, git-as <agent>) that:

  • read each agent's token from a known source (openclaw.json for one, env for another)
  • exec the underlying CLI with GH_TOKEN=… + GH_CONFIG_DIR=$(mktemp -d) so the shared hosts.yml is bypassed entirely
  • inject user.name/user.email and a temp GIT_ASKPASS for git

Works, but discipline-based: any bare gh/git call still hits the shared config and flips identity again.

Related issues

  • #67682 — Per-agent MCP env var injection (subset: MCP only)
  • #37584 — Per-agent tool settings, e.g. tools.web.search.apiKey (subset: specific tools)
  • #78063 — GH CLI auth missed when agent HOME differs from root config (different direction: workaround sets one global GH_CONFIG_DIR)
  • #78965 — Per-agent Unix sandbox backend (heavier solution: full OS-user isolation)

Acceptance criteria

  1. agents.list[].env.vars accepted in config schema; reload-safe.
  2. Each agent's process env is only the global env.vars merged with its own agents.list[].env.vars. Other agents' keys are not present.
  3. Existing top-level env.vars-only configs continue to work unchanged.
  4. OPENCLAW_SERVICE_MANAGED_ENV_KEYS (or equivalent) reflects the full set of per-agent-scoped keys, not just GITHUB_EMAIL/GITHUB_USERNAME.

Environment

  • OpenClaw version: 2026.4.20 (verified against 2026.5.7 runtime schema as well)
  • OS: Linux 6.8.0-107-generic (Ubuntu equivalent)
  • Install: npm global, systemd user service
  • Multi-agent: 2 agents (alejandro, lois) sharing one $HOME

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix Feature: per-agent env-var scoping (agents.list[].env.vars) to prevent credential leak across agents