anomalyco / anomalyco/opencode

[BUG]: amazon-bedrock and sap-ai-core write stored API keys into process.env, leaking them to every child process

Open
#46,745 1 comment 0 reactions 1 assignee View on GitHub

@neriousy is already working on this.

Since Sep 2, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
Avg merge
7h 2m
Merged PRs (30d)
384

Description

Description

Two provider loaders copy a stored credential out of auth.json and assign it into process.env. Once that happens the secret is part of the process environment for the rest of the run, so it is inherited by every child process opencode spawns and appears anywhere the environment is dumped.

packages/opencode/src/provider/provider.ts, amazon-bedrock:

const awsBearerToken = iife(() => {
  const envToken = process.env.AWS_BEARER_TOKEN_BEDROCK
  if (envToken) return envToken
  if (auth?.type === "api") {
    process.env.AWS_BEARER_TOKEN_BEDROCK = auth.key
    return auth.key
  }
  return undefined
})

sap-ai-core, same shape:

const envServiceKey = iife(() => {
  const envAICoreServiceKey = process.env.AICORE_SERVICE_KEY
  if (envAICoreServiceKey) return envAICoreServiceKey
  if (auth?.type === "api") {
    process.env.AICORE_SERVICE_KEY = auth.key
    return auth.key
  }
  return undefined
})

Both are the only two process.env[...] = <credential> assignments in that file.

Why it matters

auth.json is written 0600 precisely because its contents are secret. Assigning a value into process.env moves it into a place with none of those properties:

  • Inherited by children. Every process opencode spawns gets it — the bash tool's shells, MCP servers, git subprocesses, hooks. A credential scoped to one provider becomes ambient to every subprocess in the session.
  • Visible to anything that reads the environment. /proc/<pid>/environ for same-user processes, crash and diagnostic dumps, and any tool that prints its environment.
  • Not what the user configured. A key supplied through auth login is stored in a 0600 file; the user has no indication it will also be exported into the environment of unrelated subprocesses.

The comment above the bedrock block shows the assignment is a deliberate workaround, not an oversight:

// TODO: Using process.env directly because Env.set only updates a process.env shallow copy,
// until the scope of the Env API is clarified (test only or runtime?)

So the intent was to make the value visible to the AWS SDK, and the process-wide write is the side effect. The value is already returned from the iife and used directly, so the assignment exists only to reach an SDK that reads the environment.

Suggested fix

Pass the credential to the SDK explicitly instead of exporting it. The AWS SDK accepts a bearer token through its client config, and both call sites already hold the value in a local, so the process.env write can be dropped rather than replaced. If a specific SDK path genuinely can only read the environment, scoping the variable to the child that needs it — rather than the whole process — keeps the blast radius to that call.

Resolving the Env.set question named in the TODO would cover both providers at once.

Steps to reproduce
  1. Configure amazon-bedrock with an API key (auth login), so auth.json holds {"type":"api","key":"..."}
  2. Start a session and have a model request load the provider
  3. Use the bash tool to print the environment

AWS_BEARER_TOKEN_BEDROCK is present in the child shell, holding the key from auth.json. Same for AICORE_SERVICE_KEY with sap-ai-core.

Additional context

Found while auditing which code paths consume a stored provider key, for a plugin that serves credentials from an external secret store. The env-assignment behaviour is independent of that work — it affects any user with a stored API key for either provider.

Severity is bounded: it requires an already-configured provider, and reading it needs same-user access or a dump that includes the environment. It is a hardening issue rather than a remote vulnerability, but the fix looks small.

OpenCode version

dev

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.