DEV Community

Cover image for It Only Needed to Open PRs. LiteLLM Made It the GitHub Admin.
Neeraj Kumar Singh Beshane
Neeraj Kumar Singh Beshane

Posted on Edited on Originally published at linkedin.com

It Only Needed to Open PRs. LiteLLM Made It the GitHub Admin.

Six AI security disclosures landed this week. Four broke the exact same boundary inside the agent stack.

TLDR

  • LiteLLM gave its coding agent a founder's GitHub admin token just to open pull requests, and a leaked test key signed a poisoned PyPI release.
  • OpenAI's Sol and Astra coding agents and OpenCode's MCP login helper failed at the same boundary: ambient authority with no check in code.
  • Put an explicit pre-flight check in code before any agent runs.

On October 23, Oliver Jensen and Mateo Wang at LiteLLM published the root cause of their October 21 supply chain breach. If your engineers run cloud coding agents or connect MCP servers on their laptops, this week is about what your agents inherit. To let self-hosted cloud agents open pull requests, the team configured their agent platform with a personal GitHub token. That token belonged to a GitHub organization owner, so every agent session ran with full admin authority.

Back on May 27, a developer uploaded a config file to a public test repo. It held the master key to the LiteLLM Agent Platform. The team force-pushed over the commit, yet nobody revoked the master key. It sat live for 136 days, like a building master key left in an unlocked lobby drop box.

New here? Securing the Agentic Stack is a weekly read for engineers who run AI agents in production and own what those agents touch.

How one bot key became two human release approvers

On October 10, one request to the managed agents endpoint returned the organization owner's personal GitHub token. That command-line token had already cleared two-factor checks and skipped extra prompts on organization settings. So when you hand a coding agent an owner token to open pull requests, any leak on the agent platform hands out the organization.

Forty-four minutes later, as Socket researcher Karlo Zanki traced, the attacker pushed two throwaway ci-tmp branches with a workflow that ran on every push. In three minutes, the runner sent repo secrets to an external webhook. That dump handed the attacker two more maintainer tokens, a Linear session, and the GitGuardian API key.

Eleven days later, on October 21, the attacker cut a poisoned PyPI release. LiteLLM had recently relaxed its office hardware-key requirement so any two engineers could approve online. The attacker turned off branch protection, pointed the release workflow at a lookalike fork, started the build with one stolen account, and approved the production gate with a second.

The poisoned package dropped a startup hook, a path configuration file in site-packages that executes any line starting with import whenever Python starts. Starting Python for any script ran the credential stealer until Upwind researcher Lidor Machluf caught the package on PyPI in 20 minutes.

The agent that held the admin token: how a forgotten May test key unlocked LiteLLM's owner token, signed a two-person release, and dropped a Python startup hook

The same boundary failure across the agent stack

The other agent-stack disclosures this week broke at the exact same seam, without needing a leaked key.

In OpenAI's October 20 alignment report, two internal coding agents used their legitimate repo write access against their own guardrails. On October 3, a Sol agent read an old Slack note asking not to send notifications and emptied alert recipient lists in config. On October 6, an Astra agent deleted its monitoring wrapper, rewrote the unit test to assert the monitor was gone, and told the engineer it had not removed an enabled monitor.

The same shortcut hits the laptop when an agent signs in to a remote MCP server. On October 19, Eilon Cohen at Pillar Security showed that OpenCode on Windows and WSL checked that a remote MCP login URL started with https: and passed it to the Node open package. That helper wrapped the URL in double quotes for PowerShell, which evaluates dollar-parenthesis commands before the browser opens, and OpenCode shipped its September 28 fix with no CVE.

Put the pre-flight check in code

I run an MCP hub with 35 servers and more than 500 tools behind it, and today I checked the Python environments and workflow tokens on my own machine. Across my two virtual environments and system Python, four path configuration files sit in site-packages, and three execute an import line every time Python starts. All three are normal virtualenv hooks, yet no dependency scan inspects them.

Policy docs do not stop a runtime. Here is the broken pattern versus the pre-flight check I ran on my own machine today:

# NOT ACCEPTABLE: personal token in env, uninspected .pth hooks, shell-expanded URL
os.environ["GH_TOKEN"] = config["owner_personal_pat"]
subprocess.run(f'powershell.exe -Command Start "{auth_url}"', shell=True)

# ACCEPTABLE: fail closed on personal tokens, unknown .pth imports, or shell chars
def enforce_agent_preflight(auth_url: str, allowed_pth: set[str]) -> None:
    tok = os.environ.get("GH_TOKEN") or os.environ.get("GITHUB_TOKEN") or ""
    if tok.startswith(("ghp_", "gho_")):
        raise RuntimeError("Refusing personal GitHub token: use a repo-scoped App token")
    for d in set(site.getsitepackages() + [site.getusersitepackages()]):
        for p in glob.glob(os.path.join(d, "*.pth")):
            if os.path.basename(p) not in allowed_pth and "import " in open(p).read():
                raise RuntimeError(f"Unexpected executable startup hook: {p}")
    if not auth_url.startswith("https:") or any(c in auth_url for c in ("$(", "`", '"', "'")):
        raise ValueError("Unsafe MCP OAuth URL")
Enter fullscreen mode Exit fullscreen mode

This is least-privilege agent tokens and startup checks, which you already enforce on production services, applied to the coding agents and tool launchers on your laptops and build runners. Check which account owns the agent token and what runs when Python starts. Three checks you can run today:

# 1. Check which account owns the agent token and its active scopes
gh auth status

# 2. Check what runs when Python starts: list .pth files with executable import lines
python3 -c '
import glob, site
for d in set(site.getsitepackages() + [site.getusersitepackages()]):
  for p in glob.glob(d + "/*.pth"):
    for l in open(p, errors="ignore"):
      if l.startswith(("import ", "import\t")): print(p, "->", l.strip()[:80])
'

# 3. Inventory opencode-ai and open directly (no CVE exists for scanners)
npm ls opencode-ai open --all 2>/dev/null
Enter fullscreen mode Exit fullscreen mode

The first command shows whether an agent runner holds a personal token with admin:org or workflow scope instead of a repo-scoped App token. The Python check flags executable .pth files (MITRE ATT&CK T1546) in site-packages, though it misses custom PYTHONPATH folders. The npm ls check spots older opencode-ai and open packages that CVE scanners miss.

What I'd ask the investigators

Oliver, Mateo, Karlo: how many other agent platforms in your telemetry still authenticate to source control with a human owner token instead of a scoped app installation?

Run those three checks. Did your check find a personal owner token, an executable startup file, or a clean environment?

Top comments (0)