Skip to content
Deployment & Production

Your Coding Agent Shipped Six Security Fixes In Three Days: Sandbox Read-Deny Gaps, Symlink Reads, Permission Bypasses. Here Is The Patch Cadence And Policy Layer A Bank Needs For Agent Tooling

Between 4 and 6 October Claude Code shipped versions 2.1.290 through 2.1.292, and the release notes read like a security advisory: managed-sandbox read-deny paths that shifted mid-session not blocking project grants, notebook and PDF reads that could return files outside the approved scope through link manipulation, symlink vulnerabilities exposing unauthorised files, dangerous rm commands losing safeguards when redirected to home paths, permission bypasses for network-path file reads via hooks, and cached server settings able to disable the built-in policy plugin. These are good releases: the vendor found and fixed real escapes. They are also a reminder that the agent half of a bank's developers now use - Barclays is putting one in half of its engineers' hands - is a privileged piece of software with a weekly security cycle, and most firms manage it like a text editor. This is the operating model: pinning and a two-lane update cadence, a policy plugin you own, hook-based guards, and a CI check that no engineer runs a version with a known escape. With code.

AlchmAI Engineering14 min read

3

Claude Code releases in three days - 2.1.290 (4 October), 2.1.291 and 2.1.292 (6 October) - each with security fixes

6

Distinct escape classes fixed: sandbox read-deny gaps, out-of-scope notebook/PDF reads, symlink reads, rm safeguard loss, hook-based permission bypass, policy plugin disablement

50%

Of Barclays developers due to be using Claude Code by year-end - the scale at which agent tooling becomes a fleet to patch

2 lanes

Update cadence we recommend: security fixes within 72 hours, feature releases on a weekly evaluated train

The release notes are worth reading slowly. Version 2.1.290 on 4 October fixed dangerous rm commands losing their safeguards when output was redirected to home-directory paths, symlink vulnerabilities in file reads that could expose unauthorised files, and strengthened permission enforcement against bypass attempts. Version 2.1.292 on 6 October fixed managed-sandbox read-deny paths that shifted mid-session and stopped blocking project grants, notebook and PDF reads that could return files outside the approved scope through link manipulation, cached server settings that could disable the built-in policy plugin, and permission bypasses for file reads from network paths via pre-tool hooks - alongside new agent capabilities, plugin marketplace installation and cloud-session stability work.

None of this is a criticism of the tool. A vendor finding and fixing sandbox and permission escapes within days is exactly what you want, and the pace of fixes reflects how hard the problem is: a coding agent reads files, runs commands and talks to the network on a developer's machine, inside the perimeter, with the developer's credentials unless you have arranged otherwise. What the week exposes is the gap between how capable that software is and how most firms manage it - installed by individuals, updated when they feel like it, configured by whoever last edited a settings file. Barclays committing half its developers to the same tool by year-end is the scale at which that gap becomes a fleet-management problem with a security clock.

1. Pin, Inventory, And Run Two Lanes

Treat the agent like any other endpoint software with a CVE stream: a managed install with a pinned version, an inventory of what is running where, and two update lanes. Security fixes go out within 72 hours after a smoke test; feature releases ride a weekly train after your evaluation suite has run against them, because a new version can change agent behaviour as well as fix holes.

yamlfleet/agent-tooling.yaml
tool: claude-code
pinned_version: "2.1.292"
minimum_safe_version: "2.1.292"       # below this: known read-deny / symlink / policy-plugin escapes
lanes:
  security:
    sla_hours: 72
    gate: smoke-tests                  # install, run a scripted session in the reference repo, confirm policy plugin active
  feature:
    cadence: weekly
    gate: agent-eval-suite             # behaviour evals on the golden repo; block on regressions
inventory:
  source: mdm                          # every developer machine reports installed version daily
  alert_if_below_minimum: true
managed_settings:
  path: /Library/Application Support/ClaudeCode/managed-settings.json   # or the equivalent per OS
  owner: platform-security
  policy_plugin: bank-agent-policy@1.4.0
pythonci/agent_version_gate.py
"""Fail CI when a commit carrying AI-assisted provenance was produced by an agent version with known escapes."""
import subprocess, sys

MINIMUM_SAFE = {"claude-code": (2, 1, 292)}

def parse(v: str): return tuple(int(x) for x in v.split("."))

def trailers(commit: str) -> dict:
    out = subprocess.check_output(["git", "show", "-s", "--format=%(trailers)", commit], text=True)
    return dict(l.split(": ", 1) for l in out.splitlines() if ": " in l)

def gate(commit: str) -> list:
    t = trailers(commit)
    if t.get("AI-Assisted") != "true":
        return []
    agent, version = t.get("AI-Agent", ""), t.get("AI-Agent-Version", "")
    if agent in MINIMUM_SAFE and (not version or parse(version) < MINIMUM_SAFE[agent]):
        return [f"{agent} {version or 'unknown'} is below minimum safe version {'.'.join(map(str, MINIMUM_SAFE[agent]))}"]
    return []

if __name__ == "__main__":
    failures = gate(sys.argv[1])
    print("
".join(failures) or "agent-version-gate: ok")
    sys.exit(1 if failures else 0)

The version trailer extends the provenance scheme from our AI-coding governance guide: the agent writes its version into the commit, and CI refuses work produced by a version with a known escape. It does not prevent the escape - the fleet update does that - but it stops the output of an unpatched agent reaching main unnoticed, and it gives you an audit trail of exposure.

2. Own The Policy Plugin

One of this week's fixes was a cached server setting that could disable the built-in policy plugin. The lesson is not that the plugin is unreliable; it is that your controls should not live only in a component you do not control. Ship your own policy plugin through managed settings, owned by platform security, that encodes what agents may never do in your repositories, and verify on every session start that it is loaded.

jsonmanaged-settings.json
{
  "permissions": {
    "deny": [
      "Bash(rm -rf *)",
      "Bash(curl * | sh)",
      "Bash(git push --force*)",
      "Read(~/.ssh/**)",
      "Read(~/.aws/**)",
      "Read(**/.env*)",
      "WebFetch(*)"
    ],
    "allow": [
      "Read(./**)",
      "Edit(./**)",
      "Bash(npm test*)",
      "Bash(npm run fitness*)",
      "Bash(git status*)",
      "Bash(git diff*)"
    ]
  },
  "enabledPlugins": ["bank-agent-policy@bank-marketplace"],
  "disableBypassPermissionsMode": "disable",
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash|Edit|Write|Read", "hooks": [{ "type": "command", "command": "/opt/bank/agent-guard.sh" }] }
    ],
    "SessionStart": [
      { "hooks": [{ "type": "command", "command": "/opt/bank/verify-policy-plugin.sh" }] }
    ]
  }
}

Setting names follow the documented managed-settings schema at the time of writing; verify against the version you deploy. The structure is what matters: deny lists for the catastrophic cases, a narrow allow list, your plugin required, the bypass mode disabled, a pre-tool hook that runs your guard, and a session-start hook that fails loudly if the policy plugin is not active.

3. Guards That Do Not Depend On The Vendor

bash/opt/bank/agent-guard.sh
#!/usr/bin/env bash
# PreToolUse hook: receives the tool call as JSON on stdin; exit 2 blocks the call with the message shown.
set -euo pipefail
payload="$(cat)"
tool="$(jq -r '.tool_name' <<<"$payload")"
input="$(jq -c '.tool_input' <<<"$payload")"

# 1. Resolve every path argument and refuse anything outside the repository (defeats symlink and ../ tricks
#    independently of the agent's own checks).
repo="$(git rev-parse --show-toplevel 2>/dev/null || echo "$PWD")"
for p in $(jq -r '.. | strings | select(startswith("/") or startswith("~") or startswith("."))' <<<"$input"); do
  real="$(python3 -c 'import os,sys; print(os.path.realpath(os.path.expanduser(sys.argv[1])))' "$p" 2>/dev/null || true)"
  if [[ -n "$real" && "$real" != "$repo"* && "$real" != /tmp/* ]]; then
    echo "blocked: $tool touches path outside repository: $real" >&2; exit 2
  fi
done

# 2. Commands: refuse destructive patterns regardless of redirection or quoting games.
if [[ "$tool" == "Bash" ]]; then
  cmd="$(jq -r '.command' <<<"$input")"
  if grep -Eq '(^|[;&|[:space:]])rm[[:space:]]+-[a-zA-Z]*r|mkfs|dd[[:space:]]+if=|:\(\)\{' <<<"$cmd"; then
    echo "blocked: destructive command pattern" >&2; exit 2
  fi
fi

# 3. Log every call for the audit trail, then allow.
jq -c --arg t "$tool" '{at: now, tool: $t, input: .tool_input}' <<<"$payload" >> "$HOME/.bank-agent-audit.jsonl"
exit 0

“The vendor fixed six escapes in three days. That is the good news. The bad news is that every machine still running last week's version has all six - and in most firms nobody knows which machines those are.”


What To Do This Week

  1. 01Inventory: find out which agent versions are running on which machines. If the answer is 'we do not know', that is the finding.
  2. 02Move to a managed install with a pinned version and a 72-hour security lane; push 2.1.292 or later now.
  3. 03Ship managed settings with your own policy plugin, bypass mode disabled, and a session-start check that it loaded.
  4. 04Add the version trailer to provenance and the CI gate that refuses unpatched agents' commits.
  5. 05Subscribe someone to the release notes. This week's notes were the advisory; the next ones will be too.

The Bottom Line

Claude Code's 4 to 6 October releases fixed sandbox read-deny gaps, out-of-scope file reads, symlink exposures, lost rm safeguards, hook-based permission bypasses and a way to disable the policy plugin - a healthy vendor response to real escapes, and proof that coding agents are privileged software with a weekly security cycle. Firms putting them in half their developers' hands need a fleet model: managed installs with pinned versions and a 72-hour security lane, an inventory that alerts below the minimum safe version, a policy plugin and managed settings they own with bypass disabled, pre-tool guards that resolve paths and refuse destructive commands independently of the vendor, and a CI gate that keeps unpatched agents' work off main. That is how we deploy agent tooling for financial firms in London, and this week's release notes are the argument for doing it before the next ones.

References & Further Reading

AI Agency Developer Londoncoding agent securityClaude Codepatch managementAI Automation London codepolicy plugindeveloper tooling
Share Email
AI

AlchmAI Engineering

Engineering, London

Written by the AlchmAI engineering team in Mayfair, London. We build trading platforms, real-time charts, market data pipelines and AI features for brokers, prop firms and fintech teams. The Playbook is where we explain how we approach these systems, with code you can run and sources you can check.

Code in this guide is illustrative and supplied without warranty. Review and test it before production use. Nothing here is investment advice. Important information