A Policy That Failed to Load Looks Like No Policy: Claude Code GHSA-gfvf-j8jh-jxxw

Written by the Rafter Team

As of September 30, 2026.
Every control that loads at startup has a branch for when the load fails, and that branch decides whether the control exists. A Claude Code advisory published September 29 is a small, clean example. The fix is out, the severity is Low, and the shape of the bug applies to nearly every policy an agent runs under.
What happened
GHSA-gfvf-j8jh-jxxw (CVE-2026-103012) covers server-managed settings. Claude for Enterprise and Team organizations can push settings to every developer's Claude Code from the server: permission deny rules, model restrictions and what the advisory calls "managed-only locks."
To fetch those settings, Claude Code had to pick a credential.
It picked an API key that Claude Code had stored, for example from an earlier /login or written directly to its configuration, ahead of the user's valid Enterprise or Team sign-in.
The session itself still authenticated with the Enterprise or Team account.
When the settings endpoint rejected that stored key, one of two things happened:
- The session started with none of the organization's server-managed policies.
- If a cached copy of the settings was already on the machine, it kept applying that stale copy and never received later changes.
Either way, the session kept running, in the advisory's words, "while continuing to operate as the organization's account." The identity stayed, and the rules did not.
Scope and fix
The affected package is @anthropic-ai/claude-code from 2.0.68 up to 2.1.260.
Claude for Enterprise was affected from 2.0.68; Team was affected from 2.1.38, when server-managed settings became available there.
Endpoint-managed settings, delivered by MDM or as a file on the machine, were not affected.
The advisory rates it Low, 2.0 on CVSS 4.0, and files it under CWE-696, incorrect behavior order. Exploiting it needs local access to a device that holds a stored API key, and the no-policy case also needs the machine to have no cached copy of the managed settings. Tamas Voros of the NVIDIA AI Red Team reported it.
The fix is in 2.1.260, published to npm on September 3. Installs on the standard auto-update have already received it; anyone updating by hand should move to 2.1.260 or later.
The failure branch
The score fits the bug. The pattern deserves more attention than the score.
A policy fetched at startup can fail for many reasons: a rejected key, an expired token, a network partition, an outage at the settings service. The code has to do something in each case. It can refuse to start, start with the last known policy, or start with none. Here it did the second or third, silently, and the session looked the same either way.
From inside a session, a policy that failed to load looks the same as an organization that never wrote one. The developer sees a working agent. The administrator sees a policy that was published. Neither sees the gap between them.
Failing open is sometimes the right call. A developer tool that refuses to start every time a settings service hiccups will get disabled, and then no policy runs at all.
But that should be a deliberate decision, and a visible one. Here the behavior fell out of the order in which credentials were tried. We wrote about this class of bug in general in mishandling of exceptional conditions.
The stale-copy branch is the quieter of the two. A deny rule added after an incident, for a command or a model the organization just banned, never reaches the machines that need it most. Nothing errors.
What to do now
- Confirm the version. Check that every machine reports 2.1.260 or later with
claude --version. Machines with auto-update turned off are the ones to look for. - Find stored API keys on Enterprise and Team machines. A key left over from an earlier
/loginwas the trigger. If developers sign in with the organization account, they should not also hold a stored key. - Put the rules that must hold in endpoint-managed settings. The advisory says MDM and file-based settings were not affected. Server-managed settings are convenient; the deny rules you cannot afford to lose can live in both places.
- Test the failure branch. For every agent policy you rely on, block the policy fetch on purpose and start a session. Does it refuse, warn, or run without the rules? Do this for your own tooling too, including any guardrails you built around agents.
- Make the active policy visible. A session should be able to say which policy version it runs, so a gap shows up in a log instead of an incident review.
Where Rafter fits
Rafter's command-gating hooks for Claude Code and Codex (rafter agent init --with-claude-code or --with-codex) run locally and work offline, so they do not depend on a settings fetch at startup.
They are a second layer, not a replacement for your organization's managed settings, and the same test applies to them: break the config on purpose and see what the hook does.