GitHub Copilot App のサンドボックスで .NET アプリを開発するための設定を試してみた
GitHub Copilot App のローカルサンドボックスが GA したらしいので、.NET の開発で使えそうかどうか見てみようと思います。
今回は Windows 環境で、コンソールアプリの作成・実行と NuGet パッケージの追加を試し、その後に Minimal API も動かしてみました。
コンソールアプリは動かせましたが、ファイルのアクセス許可を調整したり、NuGet のエラーを調べたりする必要がありました。Minimal API は起動したものの、エンドポイントへのアクセスがタイムアウトし、今回はそこで断念しました。
ワークツリーの保存先を変更している場合の注意
GitHub Copilot App のワークツリーの保存先を D ドライブなどに変更している場合は、デフォルトの C ドライブ配下の場所に戻す必要があります。
現在、Windows のサンドボックスでは、システムドライブ以外にあるフォルダーを作業場所にすると、シェルでフォルダーの一覧取得などができない問題が報告されているためです。以下の Issue でも、D ドライブなどではアクセス拒否になり、システムドライブの C ドライブでは動くことが確認されています。
copilot-cli#5207
コンソールアプリを作成して実行するための設定
GitHub Copilot App にコンソールアプリの作成と実行を依頼したところ、dotnet new console の実行時にアクセス拒否のエラーが出ました。.NET SDK やテンプレートが使うフォルダーへの読み書きを許可する必要がありました。
使ったのは .NET 10 で、global.json で SDK を 10.0.403 に指定しています。
アクセスを拒否されたのは次のパスです。
%USERPROFILE%.dotnet\10.0.403.toolpath.sentinel
%USERPROFILE%.templateengine\dotnetcli\10.0.403
%USERPROFILE%.templateengine\packages.json
そこで、GitHub Copilot App のサイドバーから Settings を開き、Repositories で対象のリポジトリを選びます。Sandbox にある Additional read/write の Add folder から、次のフォルダーを追加しました。
C:\Users<ユーザー名>.dotnet
C:\Users<ユーザー名>.templateengine
<ユーザー名> は自分の環境に合わせて置き換えてください。
設定を変更しただけでは実行中のセッションに反映されないので、/restart-session でセッションを再起動する必要があります。
docs.github.com
上記のフォルダーへのアクセスを許可してセッションを再起動した後、Copilot に再実行を依頼すると、dotnet new console でのアプリ作成と、dotnet run での Hello, World! の表示に成功しました。
NuGet パッケージの追加を試してみる
コンソールアプリの作成と実行ができたので、続いて Copilot に ReactiveProperty の追加を依頼しました。Copilot が実行したのは次のコマンドです。
dotnet add .\HelloWorld\HelloWorld.csproj package ReactiveProperty
ところが、パッケージの追加もアクセス拒否で失敗しました。エラーメッセージには、拒否されたパスが出ていません。
error: Access to the path is denied.
NuGet のパッケージ保存先やキャッシュのフォルダーが怪しいと思い、Additional read/write に次の4つを追加しました。
C:\Users<ユーザー名>.nuget
C:\Users<ユーザー名>\AppData\Local\Temp\NuGetScratch
C:\Users<ユーザー名>\AppData\Roaming\NuGet
C:\Users<ユーザー名>\AppData\Local\NuGet
設定を反映して Copilot に再実行を依頼しましたが、それでも Access to the path is denied. が解消しませんでした。
ログを確認すると、次の URL からパッケージの登録情報を取得する GET リクエストには 200 OK が返っていました。少なくとも、この通信には成功しています。
api.nuget.org
そこで、Copilot に NUGET_SHOW_STACK を有効にして再実行してもらいました。スタックトレースでは、NuGet.Protocol.HttpCacheUtility.CreateCacheFileAsync から呼ばれた System.IO.FileSystem.MoveFile で失敗していました。登録情報の取得ではなく、キャッシュファイルの移動で止まっていることが分かりました。
フォルダーの許可を追加しても解決せず、ログからもアクセスを拒否されたパスが分からなかったので、Process Monitor で実際のアクセス先を調べることにしました。
Process Monitor で失敗した操作を見る
エラーメッセージだけでは先に進めなかったので、Microsoft の Process Monitor(Procmon)を使って、もう一度パッケージ追加を実行したときのファイル操作を確認しました。
learn.microsoft.com
そこで見つかったのは、次の場所にあるファイルのリネームの失敗でした。ユーザー名やサンドボックスごとに変わる部分は置き換えています。
%LOCALAPPDATA%\Packages\sandbox.{GUID}\AC\NuGet\v3-cache<source-cache-dir>\list_reactiveproperty_index.dat-new
list_reactiveproperty_index.dat-new の名前を、同じディレクトリ内で list_reactiveproperty_index.dat に変えようとしたところ、アクセスを拒否されていました。Procmon では、このリネーム操作(SetRenameInformationFile)の結果が ACCESS DENIED と記録されていました。
実際のアクセス先が AppData\Local\Packages 配下だったので、Additional read/write に次のパスを追加しました。
C:\Users<ユーザー名>\AppData\Local\Packages
セッションを再起動して Copilot にパッケージ追加を再実行してもらうと、ReactiveProperty 9.10.0 と依存パッケージの導入に成功しました。値の変更を Subscribe で受け取り、コンソールに出力する処理も動きました。
これで動くようになりました。ただ、ここまでにいくつかのフォルダーを許可しているので、全部必要だったかは確認していません。AppData\Local\Packages を丸ごと許可するのは範囲が広いので、もう少し絞れないかは気になるところです。
私の環境でコンソールアプリを実行できた設定例
試した結果、ユーザー設定の Additional read/write(Folders the sandbox may read and modify)に残っていた .NET 用のパスは次の 7 件です。
C:\Users<ユーザー名>.dotnet
C:\Users<ユーザー名>.templateengine
C:\Users<ユーザー名>.nuget
C:\Users<ユーザー名>\AppData\Local\Temp\NuGetScratch
C:\Users<ユーザー名>\AppData\Roaming\NuGet
C:\Users<ユーザー名>\AppData\Local\NuGet
C:\Users<ユーザー名>\AppData\Local\Packages
設定する場合は、C:\Users<ユーザー名> の部分を自分の環境の絶対パスに置き換えてください。ここでは設定画面で環境変数が展開されるかどうかは確認していないので、絶対パスで記載しています。
これとは別に、添付画像へアクセスするために追加したパスもありました。
C:\Users<ユーザー名>.copilot\workspaces
こちらは .NET の実行用ではなく、添付画像へのアクセス用です。
私の環境では、この設定でコンソールアプリの作成・パッケージ追加・実行までできました。もう少し許可するフォルダーを減らせるかもしれませんが、そこまでは試していません。
特に AppData\Local\Packages は、広い範囲の読み書きを許可することになります。今回の実験で使った設定であって、全員にそのまま追加することを勧めるものではありません。どこまで権限を絞っても動くかは未確認です。
Minimal API も試してみる
コンソールアプリが動いたので、次は Copilot に Minimal API の作成と実行を依頼しました。アプリは起動しましたが、エンドポイントにアクセスするとタイムアウトしてしまいました。
サンドボックス設定の Outbound internet と Local network は、セッション開始時からどちらも ON にしていました。それでも接続できなかったので、ネットワーク周りの制約を調べてみました。
調べていると、Microsoft の MXC の公開資料で、似た症状の既知の制約を見つけました。Windows の特定の構成では、ホストからサンドボックス内で起動したサーバーへの接続がタイムアウトするというものです。
github.com/microsoft/mxc/blob/main/docs/backends/…
リンク先では、Windows build 26691.1002 で、サンドボックスから外への通信をプロキシー経由に限定して試していました。ホストとのループバック通信を許可しても、ホストからサンドボックス内のサーバーへの接続はタイムアウトしたそうです。一方、プロキシーを使わない別の構成では接続できたとのことでした。
今回もこの制約に当たったのかは分かりません。ただ、起動した API に接続できない状態では開発を進められないので、今回はここまでにしました。
まとめ
今回は、サンドボックスのアクセス許可を追加することで、コンソールアプリの作成から NuGet パッケージの追加、実行までできました。ただ、途中で Procmon を使ってアクセス先を調べる必要があり、Minimal API も接続できないところで止まってしまいました。
今回試した Windows のローカル環境では、現時点で自分の実開発に使うにはまだ厳しいと感じました。サンドボックス自体は重要だと思っているので、今後の改善も追っていきたいです。
@lucasmeijer Yes, on the same machine and via microsoft/mxc
2 likes · 82 views
Can MXC JSON be used for configuration of OS-portable sandboxing policies with OpenShell, too?
"feat(ai-sandbox): accept MXC policy JSON for protected execution · westurner/sandbox@7538c33" github.com/westurner/sandbox/commit/7538c3386af8c…
"bwrap: Add the option to skip the procfs mount · Pull Request #1508 · microsoft/mxc" mxc#1508
"Manage Sandboxes | NVIDIA OpenShell" docs.nvidia.com
To sandbox LSP servers in sphinxdocrs with bwrap in rootless containers, we needed to add a --no-procfs-mount CLI arg (and MXC JSON) to sandboxes, because you can't mount /proc in a rootless container.
@turicas A MS tem uma solução bem interessante: microsoft/mxc
2 likes · 706 views
Your Agent Should Not Run as You: What Windows Now Offers for Containing AI Agents
If you run a coding agent on Windows today, its shell commands usually run with your full user rights: your SSH keys, your browser profile, your whole home folder. Microsoft is now putting OS-level boundaries around agents, and a lot of it lands on the developer side first.
We spent some time reading the official docs, the SDK repo and the Microsoft blog posts behind this. Below is our take on what it means if you build or run agents on Windows.
TL;DR
- Microsoft Execution Containers (MXC) is an open-source SDK (Rust, .NET, Node) that runs agent workloads inside a policy you define: files, network, UI and the process itself. Microsoft announced it as generally available on 7 October 2026.
- Backends differ. Process containers are lightweight. Session containers run the agent under a separate Windows account and session. There are also WSL containers and an experimental MicroVM.
- Some agents already use it. GitHub Copilot sandboxes shell commands and local MCP servers with MXC, and you can configure it with /sandbox in the Copilot CLI.
- The agent workspace (Settings > System > AI Components > Experimental agentic features) is a separate preview feature that gives agents like Copilot Actions their own account and desktop.
- MCP on Windows has an on-device registry (odr.exe) that runs packaged MCP servers in a contained agent session by default. This is still preview.
- Still coming: Intune policy for MXC process containers, Entra-based agent identity and Agent 365 controls for local agents.
The problem in one example
Microsoft's own example is a good one. A coding agent is asked to update a website. It needs read and write access to the repo and your build tools. It may need to read the production server config to understand the deployment. It should never change that config.
Without a boundary, the agent may decide that editing the config is the fastest way to finish the task. From the model's point of view that is reasonable. From yours it is an outage.
The core idea in the MXC announcement is that "an agent cannot be its own security authority." The policy lives outside the agent, so neither the model nor the code it writes can grant itself more access.
What MXC actually is
MXC is a library you build into your app or agent harness. You describe the container and its rules, and MXC picks a backend and launches the workload inside it. It covers Windows, Linux and macOS. The microsoft/mxc repo is MIT licensed and publishes SDKs for Rust (mxc-sdk on crates.io), .NET (Microsoft.Mxc.Sdk on NuGet) and Node (@microsoft/mxc-sdk on npm).
The policy has five areas:
| Policy area | What it controls |
|---|---|
| Containment | Which backend runs the workload |
| Process | Command, arguments, working directory, environment |
| File system | Read-write paths, read-only paths, denied paths |
| Network | Inbound and outbound access, including loopback to local services |
| User interface | Access to the desktop, clipboard and display |
This is the Node sample from the repo README. It runs a command with outbound network denied by default:
import { spawn, type ContainerRequest } from '@microsoft/mxc-sdk/v1';
const request: ContainerRequest = {
command: 'node -e "console.log(\'hello from container\')"',
network: { egress: { default: 'deny' } },
timeoutMs: 30_000,
};
const child = await spawn(request);
Picking a backend
On Windows, the main options are:
- Process container. This is the default and the fast one. On Windows it uses AppContainer. It suits coding agents and model-generated scripts where the inner loop needs to stay quick.
- Session container (isolation_session in the SDK). This runs the agent under a separate Windows account and session, with its own desktop, clipboard, UI and input. It is Windows only. It fits long-running agents and UI automation, and it is the backend that gives you a distinct identity to audit.
- WSL container (wslc). This is for Linux-first toolchains that need Linux packages.
- MicroVM. This uses hardware-backed isolation for higher-risk work like running untrusted code. It is marked experimental, as are the Windows Sandbox and Hyperlight backends in the repo.
There is a minimum Windows build. Per the repo's OS version table, process containers need Windows 11 24H2/25H2 build 26100.9278/26200.9278 (August 2026 update) or later. Session containers need 26100.9550/26200.9550 (September 2026 update). On 26H2, both need 26300.9550. If your CI runners or test VMs lag on updates, check this first.
Writing a policy without guessing
This is the part we found most useful. Nobody knows every path an agent will touch before running it, so MXC has three modes:
- Enforcement: blocks anything not granted. This is for production.
- Learning: still blocks, but records each denial in a JSON activity report.
- Permissive: allows everything and records what would have been blocked.
The activity report only works with process containers on Windows. Microsoft's guidance matches what we would do anyway: run in Learning mode, read the denials, and grant only what the workload really needs.
Two things to watch. First, the README warns that the --audit flag on the wxc-exec.exe test executor "turns off all sandbox security" for that run, so never use it on untrusted code. Second, the README says it plainly: "Your application will hit access issues when running in a sandbox, until you've had time to tune your containment rules." Expect a few rounds of tuning.
Microsoft also asks agent developers to plan for organisation policy that is stricter than yours. If a resource is blocked, the agent should explain that and ask for the right access, not fail silently. That is a UX requirement worth building in now.
If you already use GitHub Copilot
The GitHub and Windows post explains how Copilot uses MXC. On Windows it uses the BaseContainer tier of the ProcessContainer backend. With sandboxing on, shell commands, local MCP servers and language servers run inside the process boundary by default.
Two caveats matter for threat modelling:
- Copilot's built-in file tools run inside Copilot itself. They are checked against the policy by the agent harness, not by OS process isolation.
- Remote MCP servers sit outside the local sandbox.
To check or change your settings, run /sandbox in the Copilot CLI. In the Copilot app, open settings with the gear icon, pick your project and turn on Sandbox new sessions. By default the working directory is read-write and most of the rest of the system is read-only or blocked.
Microsoft lists OpenClaw, OpenAI Codex, Replit, LM Studio and Unsloth AI as also supporting MXC. Claude Code, Manus, Perplexity, Raycast and others "will be releasing support", with no dates given.
The agent workspace is a different thing
It is easy to mix these up. The agent workspace comes from the Experimental agentic features setting, which is used by Copilot Actions. According to Microsoft Support:
- It is off by default. Only an admin can turn it on, and then it is on for every user on the device.
- It creates separate agent accounts and an agent workspace with its own desktop, apart from the user's session.
- Agents can request access to six known folders: Documents, Downloads, Desktop, Music, Pictures and Videos. Agent accounts can also access any folder that all authenticated users can access, such as public user profiles.
- On preview builds 26100.7344 and later, you can set file access per agent under Settings > System > AI Components > Agents, with the options Allow always, Ask every time or Never allow.
One small trap: the Windows security book shows the toggle under an extra Agent tools level. Microsoft's own pages show both paths, so search Settings for "agentic" if you cannot find it on your build.
MCP servers and the on-device registry
If you ship an MCP server, this part is for you. MCP on Windows adds the Windows On-Device Agent Registry (ODR). Agents use it to discover MCP servers, and you can inspect it from a terminal on build 26220.7262 or later:
odr mcp list
odr mcp add <path-to-mcpb-manifest-json>
odr mcp remove <server-id>
The containment docs have details that are easy to miss:
- Packaged servers registered through ODR run in a separate agent session under a separate agent account. They have no access to your files, settings, credentials or windows unless you grant it.
- To run contained, a server must be a binary .exe with package identity (MSIX) and a valid manifest. MCP bundles (.mcpb) currently cannot run contained.
- A contained server can still reach the internet. Containment here limits local access, not network access.
- File permissions are granted per host app, not per server. If one server used by a host gets access to your files, every server used by that host gets it too.
- The "Reduce protections for agent connectors" setting (Settings > System > Advanced > AI components) exists for testing. It does what the name says.
Like the agent workspace, all of this is labelled pre-release.
What is still missing
To be fair about the gaps: per Microsoft, Intune policy for MXC process containers is "soon". Entra support for telling agent activity apart from user activity is "coming soon", and so are Agent 365 controls for on-device agents. If you run agents across a fleet today, you can contain them, but central governance is not fully there yet. For now, plan a pilot rather than a full rollout.
Over to you
How are you sandboxing agents on Windows today: a VM, WSL, Windows Sandbox, a separate user account, or nothing at all? And would you add MXC to your own agent harness, or wait until Intune and Entra support land? Tell us what your setup looks like in the comments.
We first wrote about this on Windows Mode.
4 reactions · 4 comments
ローカル LLM のエージェントを箱に入れても、名前の問い合わせは外へ出た。DNS の記録で気づいて止める
!
先に、この記事の要約(専門用語なし)
ローカルの LLM に、PC の操作(コマンドの実行やファイルの読み書き)をさせている。モデルに悪い仕込みがあった場合に備えて、エージェントを外へ通信できない箱に入れた
それでも、ドメイン名を IP アドレスに変える「名前の問い合わせ(DNS)」だけは箱の外へ出た。名前の中に情報を埋めれば、持ち出しに使える
止められないので、Windows の記録から「どのプロセスが、どの名前を問い合わせたか」を読み、通知してエージェントを止める見張りを作った
普段の作業では、箱の中のエージェントは名前を 1 件も問い合わせなかった。そこで、箱の中から問い合わせが出たら、名前に関係なく 1 件目で止めることにした
止められるのは 2 件目からで、1 件目は外へ出る
何から守りたいか
ローカルの LLM を、Codex や Claude Code のようなエージェントの頭脳として動かしている。エージェントはコマンドを実行でき、ファイルを読み書きできる。
前に、モデルファイルに仕込まれたコードを、読み込む前に点検して止める記事を書いた。あれはファイルの形式に紛れ込んだコードの話だった。今回心配しているのは、モデルそのもの、つまり重みに仕込みがある場合である。普段は普通に答え、特定の入力で発火すると、エージェントのツールを使ってキーやファイルを読み、外へ送る。モデルの重みを見ても、仕込みの有無は自分には分からない。だから、発火しても持ち出せない場所でエージェントを動かすことにした。
組み方はこうなっている。
自分のユーザー(キー・SSH の鍵・ブラウザのプロファイルがある)
└ エージェント専用のユーザー(キーを持たない。外向きの通信はユーザー単位で遮断)……箱 1
└ MXC(書けるのは作業フォルダだけ。外へは出られない)……箱 2
└ Codex / Claude Code
モデルのサーバー(Ollama)は箱 2 の外で、127.0.0.1 の 1 ポートだけを開ける
DNS の見張りは自分のユーザーで動き、怪しければ通知してエージェントを止める
MXC は Microsoft が公開している、プロセスを閉じ込めて動かすための仕組み(microsoft/mxc、MIT ライセンス)で、使ったのは v1.0.1 である。この記事で書くのは、どちらの箱でも止まらなかったものと、それへの備えである。
どの箱でも、名前は引けた
箱の中から、外の IP アドレスへの直接の通信は通らなかった。名前を指定した通信も、つながる段階で止まった。
ところが、名前の問い合わせそのものは外へ出た。専用ユーザーでも、MXC の中でも、Windows の DNS の API を通して名前を引くことはできた。API を通す問い合わせは、箱の中のプロセスが自分で送るのではなく、箱の外で動いている DNS クライアントのサービスが代わりに引く。箱の通信の遮断にかからないのは、そのためと考えている。
名前の問い合わせは、PC から DNS サーバーへ、さらにその先のサーバーへと中継される。持ち出したい文字列を <文字列>.<自分のドメイン> という名前にして問い合わせると、そのドメインの DNS サーバーを持っている側には文字列が届く。調べた範囲では、DNS を使った持ち出しとしてよく挙がる手のようだ。
仮想マシンやコンテナ(WSL2・Docker・Hyper-V)に入れれば、名前の問い合わせも箱の中で止められるのではないか、とも考えた。ただ、この PC は Windows 11 Home で、Hyper-V と Windows Sandbox は使えず、WSL も入れていない。それに、調べた範囲では、WSL2 には VM の中の問い合わせを Windows 側で代わりに解決する仕組み(DNS トンネリング)があり、新しい版では既定で有効とされているようだ。そうだとすると、VM に入れても Windows の DNS クライアントを通って外へ出るかもしれない。ここはまだ試していない。
問い合わせを箱ごとに止められる設定は、今回の組み方では見つからなかった。そこで、止めるのではなく、気づいて止めることにした。
誰が問い合わせたかは、Windows の記録に残る
Windows の DNS クライアントには、問い合わせを記録するログ(Microsoft-Windows-DNS-Client/Operational)がある。既定では無効なので、管理者の PowerShell で有効にする。
有効にする(最大 20MB。古いものから上書き)
wevtutil sl Microsoft-Windows-DNS-Client/Operational /e:true /ms:20971520
元に戻す(無効にして、最大サイズを元の値に)
wevtutil sl Microsoft-Windows-DNS-Client/Operational /e:false /ms:1052672
有効にしている間は、この PC のすべての名前解決が記録される。読むほうは管理者でなくてよかった。手元では、対話でログオンしたユーザーに読む権限が付いていた(wevtutil gl で確かめた)。
知りたいのは「どのプロセスが問い合わせたか」である。このログには問い合わせ 1 件につき複数のイベントが出るので、3 つの立場(自分のユーザー/専用ユーザー/専用ユーザー+MXC)と 3 つの方法(nslookup・curl・.NET)で、それぞれ固有の名前を引いて確かめた。
イベント 3006(問い合わせの開始)には、呼び出したプロセスの PID とユーザーが残る。MXC の中の curl や PowerShell も、ユーザーは専用ユーザー、PID はその curl や PowerShell のものだった
3008(問い合わせの完了)にも、呼び出し元の PID とユーザーが残っていた
ほかのイベント(3009〜3020、1016)の PID は、DNS クライアントのサービス(NETWORK SERVICE)のもので、呼び出し元は分からない
見張りは、問い合わせの開始である 3006 だけを読む。PID はイベントの System の中の Execution 要素に、問い合わせた名前と種類は EventData の QueryName と QueryType に入っている。
前回読んだ位置より後のイベントだけを XML で読む
q = f"*[System[EventRecordID>{after_id}]]"
out = subprocess.run(["wevtutil", "qe", LOG_NAME, f"/q:{q}", "/f:xml"],
capture_output=True, text=True).stdout
root = ET.fromstring("<Events>" + out + "</Events>")
for ev in root.findall("e:Event", NS):
sysn = ev.find("e:System", NS)
event_id = int(sysn.findtext("e:EventID", "0", NS))
pid = int(sysn.find("e:Execution", NS).get("ProcessID", "0"))
data = {d.get("Name"): (d.text or "") for d in ev.findall("e:EventData/e:Data", NS)}
name, qtype = data.get("QueryName", ""), data.get("QueryType", "")
エージェントの問い合わせだけを拾う
PC 全体の問い合わせから、エージェントのものだけを選ぶ。起点は、エージェントを起動したプロセスの PID である。5 秒ごとに Win32_Process から親子関係を読み直し、起点とその子孫を「エージェントの木」とする。
3006 の PID を、次のように振り分ける。
PID の状態
扱い
エージェントの木に入っている
エージェントのもの
専用ユーザーのもので、まだ生きているのに木に入っていない
同じユーザーで動いている別の仕組み(画像生成など)。除く
専用ユーザーのもので、もう消えている
木を読み直す前に終わった短命のプロセス。エージェントのものとみなす
3 行目は安全な側に倒している。専用ユーザーで短命のプロセスを動かす別の仕組みがあると、その問い合わせもエージェントのものとして扱い、誤報になりうる。
怪しい名前の判定と、止め方
判定に使っているのは次の 4 つである。具体的なしきい値はここには書かない。
長さ:ラベル(点で区切られた 1 つ分)や名前全体が長すぎる
ランダムさ:英数字が長く続くラベルで、文字の出方が偏っていない(エントロピーが高い)
種類:普段の通信で使う種類(A・AAAA・CNAME など)以外。TXT などは、応答にも文字列を載せられる
連続:許可リストに無いドメインの下で、短い時間に違う名前がいくつも続く
どれかに当たったら、通知を出し、エージェントの木を taskkill /PID <起点> /T /F で丸ごと止める。最初は、許可リストに無いだけの名前は記録だけにしていた。その後、箱の中からの問い合わせは名前に関係なく 1 件目で止める設定に変えた(後述)。
試験では、MXC の中で「普通の名前 → 待つ → ランダムで長いラベルの .example.invalid → 待つ → 目印のファイルを書く」の順に動かした。怪しい名前を検出してから約 2 秒でエージェントの木が止まり、目印のファイルは書かれなかった。普通の名前では何も起きなかった。
ただし、最初の 1 件は外へ出る。気づくのは問い合わせの後だからである。名前 1 つには 250 文字ほど載せられるので、API キー 1 本なら 1 件目だけで持ち出せてしまう。
予告したのに、通知が出なかった
ここまで動くまでに、「これから試験の問い合わせを出すので、通知が出るはず」と予告して、何も出ない失敗を続けて 3 回した。どれも見張りの側の不具合だった。
短命の curl を見失った。木を読み直す前に終わった curl の問い合わせを、木に入っていないとして捨てていた。上の表の 3 行目は、この失敗から足した
関数の戻り値を取り違えた。プロセスの木を返す関数の戻り値の扱いを間違え、開始から 1 秒で「エージェントは終わった」と判断して見張りが止まっていた
試験のスクリプトの待ち時間が、MXC の中では待ちにならなかった。待ちに使った ping が MXC の中では即座に失敗し、試験全体が 0.5 秒で終わっていた。見張りは自分が起動した後の記録しか読まないので、取り逃していた
3 回目で、見張りを起動してから試験を始める、という順番に頼っていたのが弱いと分かった。そこで 2 つ変えた。
記録の位置を、エージェントを動かす前に控える。起動の入口が、最後のイベントの番号(EventRecordID)を読んでから見張りに渡す。見張りはそこから後を読むので、起動が遅れても取り逃さない。エージェントが終わっても、残りの記録を読み切ってから止まる
見張りが本当に記録を読めているかを、始める前に確かめる。見張りは開始時に、無害な名前(dnswatch-ready-<乱数>.invalid)を自分で引き、それが 3006 として読めたら ready と出す。予告はこれを確かめてから出す。ログが有効になっているだけでは通さない
name = f"dnswatch-ready-{uuid.uuid4().hex[:12]}.invalid"
try:
socket.getaddrinfo(name, 80)
except OSError:
pass # 引けないのが正しい(.invalid)。記録に残れば十分
この後、3006 に name が現れるまで待つ
止める相手を取り違えない
止める処理には、もう 1 つ危ないところがあった。エージェントが先に終わると、起点の PID が別のプロセスに使い回されることがある。その状態で taskkill /T を打つと、関係のないプロセスの木を止めてしまう。
そこで、入口がエージェントを起動したときに、起点の起動時刻と実行ファイルのパスを控えておく。見張りは止める直前に同じものを読み直し、一致したときだけ止める。一致しなければ止めずに、記録に「止めなかった」と残す。
def kill_tree(root_pid, identity):
now_id = process_identity(root_pid) # (CreationDate, ExecutablePath)
if identity is None or now_id != identity:
return False # PID が使い回されていたら止めない
return subprocess.run(["taskkill", "/PID", str(root_pid), "/T", "/F"]).returncode == 0
通知を見逃さない
通知は Windows のトーストで出している。ここでも 2 つつまずいた。
日本語が \u3042 のようなエスケープのまま表示された。トーストを出す PowerShell の文字列を json.dumps で作っていたためで、PowerShell は \uXXXX を文字に戻さない。文字列は PowerShell の単一引用符の文字列にし、スクリプト全体を UTF-16LE の base64 にして -EncodedCommand で渡すようにした。コマンドラインの文字コードで化けることもなくなる。
数秒で消えてしまう。席を外していると見逃す。トーストの XML を scenario="reminder" にして「閉じる」ボタンを付け、閉じるまで画面に出たままにした。
<toast scenario="reminder" duration="long">
<visual><binding template="ToastGeneric">
<text>DNS の見張り:怪しい問い合わせ</text>
<text>(問い合わせた名前と理由)→ エージェントを止めた</text>
<text>(記録のファイルの場所)</text>
</binding></visual>
<actions>
<action content="閉じる" arguments="dismiss" activationType="system"/>
</actions>
</toast>
あわせて ExpirationTime を 7 日後にし、通知センターに残る期間を延ばした。追加のモジュールは入れておらず、差出人は「Windows PowerShell」と表示される。
普段の作業では、名前を 1 件も引かなかった
止める設定のまま、箱の中で普段の作業をさせた。Claude Code を 3 回、Codex を 2 回動かし、モデルは Ollama の小さいモデルを 1 ポートでつないだ。
誤報は 0 件だった。ただ、これには続きがある。その間、箱の中のエージェントは名前を 1 件も問い合わせていなかった(見張り自身の確認の問い合わせを除く)。どちらもモデルにはループバックの IP アドレスでつないでいる。Claude Code はテレメトリと自動更新を切ってある。そのため、名前を引く場面が無かったと考えている。
だから、誤報 0 件は「判定がちょうどよい厳しさだった」という意味にはならない。判定を試す機会が無かっただけである。
その代わりに分かったことがある。この箱の中から名前の問い合わせが 1 件でも出れば、それだけで普段と違う。
そこで、見張りを厳しくした。箱の中からの問い合わせは、名前に関係なく 1 件目で止める。許すのは localhost の完全一致だけにした。後ろが一致すれば許す形にすると、<秘密>.localhost のような名前まで通ってしまうからである。長さやランダムさの判定は、止めるかどうかには使わず、記録の分類として残している。「止める」と「通知だけ」は、設定 1 か所で切り替えられるようにした。
これで防げるのは、2 件目以降と、1 件に収まらない大きさの持ち出しである。1 件目は、上に書いたとおり外へ出る。
この設定に変えてから、同じ普段の作業(Claude Code 3 回・Codex 2 回)を流し直した。誤報は 0 件で、5 回ともエージェントは最後まで動いた。この間も、箱の中からの問い合わせは 0 件だった(localhost も引いていない)。
記録に残らない問い合わせは、外へも出られなかった
nslookup で引いた名前は、どの立場でも記録に 1 件も残らなかった。nslookup は Windows の DNS クライアントの API を通らず、自分で DNS のパケットを組んでサーバーに送るためと考えている。
最初は、これを見張りの穴だと判断していた。MXC の中で nslookup を動かすと、正常に終わったからである。ところが、見ていたのは終了コードだけだった。nslookup は、応答が無くても 0 を返すことがある。
そこで、確かめ方を変えた。存在しない名前(<乱数>.example.invalid)を引き、応答に、ルートサーバーの SOA(a.root-servers.net)が付いた NXDOMAIN が返るかを見る。外の DNS サーバーまで届けばこれが付き、手元で作られた答えには付かない。外部のサービスは使っていない。
引き方
箱の外
専用ユーザーだけ
MXC だけ
両方
nslookup(既定のサーバー・ルーター・1.1.1.1、UDP と TCP)
届く
届かない
届かない
届かない
DoH(1.1.1.1
届く
届かない
届かない
届かない
Resolve-DnsName -Server 1.1.1.1(DNS の API)
届く
届く
(測れていない)
届く。3006 に専用ユーザーの PID 付きで残った
MXC だけの列の API の行は、PowerShell が起動しない設定で試していたため測れていない。
DNS の API を通らない問い合わせは、どの箱からも外へ届かなかった。記録に残らなくても、外へ出られないので穴ではない。外へ出られるのは、API を通る問い合わせだけで、そちらは 3006 に残るので見張りで捕まえられる。
限界もある。「届かない」は、応答が返らないことから判断した。送ったパケットが PC から出ていないことまでは見ていない。
もう 1 つ、箱の中に入れたもの(作業フォルダの中身や、エージェントに渡す指示)は、1 件目の問い合わせで漏れうる。箱の中に機密を入れない、という運用で守るしかない。
持ち帰り
外へ出られない箱に入れても、名前の問い合わせは別の経路で外へ出ることがある。自分の組み方では、どちらの箱でも止まらなかった
Windows では、DNS クライアントのログのイベント 3006 (問い合わせの開始)に、問い合わせたプロセスの PID とユーザーが残る。PID が DNS クライアントのサービスのものになるイベントもあるので、どのイベントを読むかは確かめてから決める
見張りを作ったら、「動いているはず」ではなく、無害な名前を自分で引いて、それが読めたことを確かめてから始める
PID で止めるときは、起動時刻と実行ファイルも控えて、止める直前に照合する
普段は名前を引かないように組んでおくと、「問い合わせが出た」こと自体を合図にして、1 件目で止められる。ただし 1 件目は外へ出る
3006 に残らない形の問い合わせ(nslookup のように自分でパケットを送るもの)は、箱の中からは外へ届かなかった。外へ出るのは 3006 に残る形だけだった
「引けた」を終了コードで判断しない。外まで届いた証拠(今回はルートサーバーの SOA)で確かめる
ローカル画像生成の記事
モバイルゲーミングPC の Intel Arc GPU でローカル画像生成 —— Qwen-Image 2.1 GGUF で次元エラー
ComfyUI で Qwen-Image 2.1 のテキストエンコードを先に済ませても、内蔵 GPU では 3% しか縮まなかった
ローカル AI のモデルファイルに仕込まれたコードを、読み込まずに点検して起動前に止める
この記事 —— ローカル LLM のエージェントの名前の問い合わせを、DNS の記録で見張って止める
注記
環境は Windows 11 Home(x64)、MXC v1.0.1、Ollama。試験と普段の作業の確認は、それぞれ数回ずつで、ばらつきは取っていない
普段の作業の確認では、エージェントにファイルを作らせる作業は、どの回も最後まで通らなかった(小さいモデルがツールを正しく呼べなかった)。名前を引くような作業(パッケージの取得など)での誤報は、まだ確かめていない
判定のしきい値は、悪用を避けるため本文に書いていない
1 like
Memo。確認案件。
AIエージェントの実行を隔離するMicrosoftのMicrosoft eXecution Containers (MXC)はOpenAIのCodexで勧められている。
Microsoft eXecution Container (MXC)のgithubではMulti PlatformでWindowsでもLinuxでもMacOSでも動くとある。
microsoft/mxc
4 likes · 1 repost · 247 views
Microsoft has mxc which I think is neat — not sure if it’s the right level of abstraction for your needs
microsoft/mxc
45,000 Stars 1 Din Mein: REA Kisi Bhi App Ko Bina Code Samajh Leta Hai | 5 Fastest Repos #Shorts
45,000 stars ek din mein: REA kisi bhi app ka feature bina source code ke samajh leta hai. October ke 5 sabse tez badhte GitHub repos, Hindi mein. Har number 12 October ko live check kiya gaya hai.
1. morluto/rea, 1,41,322 stars, GitHub trending ke hisaab se 45,495 sirf 12 October ko. Reverse Engineer Anything: aapka coding agent kisi bhi app, Electron app, website, .NET assembly ya native binary ka feature bina source code ke trace karta hai, evidence ke saath, aur phir aapke project ke liye apna version likhta hai. Sab kuch local chalta hai. Native binaries ke liye Hopper, Ghidra ya IDA chahiye. MIT.
morluto/rea
2. lexmount/moli, 17,068 stars, 10 August ko bana. AI agents ke liye Rust mein bana headless browser: page ko markdown ya semantic tree ki tarah padhta hai, pixels sirf maangne par render karta hai. CLI, CDP aur WebDriver se chalta hai. Linux, macOS, Windows. Apache-2.0.
lexmount/moli
3. DuarteSantos8/openGym, 10,221 stars, 18 July ko bana. Self-hosted gym aur body-weight tracker: routines, guided workouts, supersets, muscle map, 5,600+ exercises, passkey login, FitNotes/Strong/Hevy se import. Ek docker compose up aur chal gaya; Android APK bhi hai. AGPL-3.0.
DuarteSantos8/openGym
4. tester-army/e2e, 9,420 stars, 22 July ko bana. End-to-end testing framework: test ka goal plain English mein likho, agent app chala kar use poora karta hai, aur usi test mein locators aur assertions se result check hota hai. Ek baar chala hua agent step record hota hai aur agle run mein bina model call ke replay hota hai. Web (Playwright) aur mobile (iOS/Android). Apache-2.0.
tester-army/e2e
5. microsoft/mxc, 2,710 stars. Microsoft eXecution Container: model ka likha code, plugins aur tools ko sandbox mein chalata hai, Windows, Linux aur macOS par, filesystem aur network policy ke saath. Rust, .NET aur Node SDK. Kuch backends abhi experimental hain. MIT.
microsoft/mxc
Repo links:
- rea: morluto/rea
- moli: lexmount/moli
- openGym: DuarteSantos8/openGym
- e2e: tester-army/e2e
- mxc: microsoft/mxc
TREND comment karo, saare links DM kar dunga. Kisi developer dost ko bhejo, save kar lo.
#GitHub #OpenSource #TrendingRepos #CodingInHindi #TechHindi
[bn] ১ দিনে ৪৫,০০০ স্টার: REA কোড ছাড়াই যেকোনো অ্যাপ বুঝে নেয় | ৫টি দ্রুততম গিটহাব রিপো #Shorts
একদিনে ৪৫,০০০ স্টার: REA সোর্স কোড ছাড়াই যেকোনো অ্যাপের ফিচারগুলো বুঝতে পারে। অক্টোবরের ৫টি দ্রুততম ক্রমবর্ধমান গিটহাব রিপো, হিন্দিতে। প্রতিটি সংখ্যা ১২ই অক্টোবর লাইভ যাচাই করা হয়েছে।
১. morluto/rea, ১,৪১,৩২২ স্টার, শুধুমাত্র ১২ই অক্টোবর গিটহাব ট্রেন্ডিং অনুযায়ী ৪৫,৪৯৫ স্টার। যেকোনো কিছু রিভার্স ইঞ্জিনিয়ার করুন: আপনার কোডিং এজেন্ট সোর্স কোড ছাড়াই, প্রমাণসহ, যেকোনো অ্যাপ, ইলেকট্রন অ্যাপ, ওয়েবসাইট, .NET অ্যাসেম্বলি বা নেটিভ বাইনারির ফিচারগুলো ট্রেস করে এবং তারপর আপনার প্রোজেক্টের জন্য এর নিজস্ব সংস্করণ লেখে। সবকিছু লোকালি চলে। নেটিভ বাইনারিগুলোর জন্য Hopper, Ghidra, বা IDA প্রয়োজন। MIT।
morluto/rea
২. lexmount/moli, ১৭,০৬৮ স্টার, তৈরি হয়েছে ১০ই আগস্ট। AI এজেন্টদের জন্য রাস্ট-এ লেখা একটি হেডলেস ব্রাউজার: পেজগুলোকে মার্কডাউন বা একটি সিম্যান্টিক ট্রি হিসেবে পড়ে, চাহিদা অনুযায়ী পিক্সেল রেন্ডার করে। CLI, CDP, এবং WebDriver এর মাধ্যমে চলে। Linux, macOS, Windows। Apache 2.0।
lexmount/moli
৩. DuarteSantos8/openGym, ১০,২২১ স্টার, তৈরি হয়েছে ১৮ই জুলাই। সেলফ-হোস্টেড জিম এবং বডি-ওয়েট ট্র্যাকার: রুটিন, গাইডেড ওয়ার্কআউট, সুপারসেট, মাসল ম্যাপ, ৫,৬০০+ এক্সারসাইজ, পাসকি লগইন, FitNotes/Strong/Heavy থেকে ইম্পোর্ট করার সুবিধা। একটি ডকার কম্পোজ চালু আছে; অ্যান্ড্রয়েড APK-ও পাওয়া যায়। AGPL-3.0।
DuarteSantos8/openGym
৪. tester-army/e2e, ৯,৪২০ স্টার, তৈরি হয়েছে ২২শে জুলাই। এন্ড-টু-এন্ড টেস্টিং ফ্রেমওয়ার্ক: সহজ ইংরেজিতে টেস্টের লক্ষ্য লিখুন, তা সম্পন্ন করতে এজেন্ট অ্যাপটি চালান, এবং একই টেস্টে লোকেটর ও অ্যাসারশন ব্যবহার করে ফলাফল যাচাই করুন। একবার রান করা হলে, এজেন্ট স্টেপটি রেকর্ড করা হয় এবং মডেলকে কল না করেই পরবর্তী রানে পুনরায় চালানো হয়। ওয়েব (প্লেরাইট) এবং মোবাইল (আইওএস/অ্যান্ড্রয়েড)। অ্যাপাচি ২.০।
tester-army/e2e
৫. microsoft/mxc, ২,৭১০ স্টার। মাইক্রোসফট ই-এক্সিকিউশন কন্টেইনার: উইন্ডোজ, লিনাক্স এবং ম্যাকওএস-এ ফাইলসিস্টেম ও নেটওয়ার্ক পলিসি নিয়ন্ত্রণের সুবিধাসহ লিখিত কোড, প্লাগইন এবং টুলের একটি স্যান্ডবক্সড মডেল। রাস্ট, .নেট এবং নোড এসডিকে। কিছু ব্যাকএন্ড এখনও পরীক্ষামূলক পর্যায়ে রয়েছে। এমআইটি।
Microsoft/mxc
রেপো লিঙ্ক:
rea: morluto/rea
- moli: lexmount/moli
- openGym: DuarteSantos8/openGym
- e2e: tester-army/e2e
- mxc: Microsoft/mxc
TREND লিখে কমেন্ট করে আমাকে সব লিঙ্ক DM করুন। আপনার কোনো ডেভেলপার বন্ধুকে এটি পাঠান এবং সংরক্ষণ করুন।
#GitHub #OpenSource #TrendingRepos #CodingInHindi #TechHindi
[en-US] 45,000 Stars in 1 Day: REA Understands Any App Without Code | 5 Fastest Repos #Shorts
45,000 stars in a day: REA understands the features of any app without the source code. 5 fastest growing GitHub repos of October, in Hindi. Each number is checked live on October 12th.
1. morluto/rea, 141,322 stars, 45,495 on October 12th only according to GitHub trending. Reverse Engineer Anything: Your coding agent traces the features of any app, Electron app, website, .NET assembly or native binary without the source code, with evidence, and then writes its own version for your project. Everything runs locally. Native binaries require Hopper, Ghidra, or IDA. MIT.
morluto/rea
2. lexmount/moli, 17,068 stars, created August 10. A headless browser in Rust for AI agents: reads pages as markdown or a semantic tree, renders pixels on demand. Runs via CLI, CDP, and WebDriver. Linux, macOS, Windows. Apache 2.0.
lexmount/moli
3. DuarteSantos8/openGym, 10,221 stars, created July 18. Self-hosted gym and body-weight tracker: routines, guided workouts, supersets, muscle map, 5,600+ exercises, passkey login, import from FitNotes/Strong/Heavy. Got a docker compose up and running; Android APK available too. AGPL-3.0.
DuarteSantos8/openGym
4. tester-army/e2e, 9,420 stars, created July 22. End-to-end testing framework: Write the test goal in plain English, run the agent app to complete it, and check the result with locators and assertions in the same test. Once run, the agent step is recorded and replayed in the next run without calling the model. Web (Playwright) and mobile (iOS/Android). Apache 2.0.
tester-army/e2e
5. microsoft/mxc, 2,710 stars. Microsoft eExecution Container: A sandboxed model of written code, plugins, and tools, with filesystem and network policy control, on Windows, Linux, and macOS. Rust, .NET, and Node SDKs. Some backends are still experimental. MIT.
Microsoft/mxc
Repo links:
- rea: morluto/rea
- moli: lexmount/moli
- openGym: DuarteSantos8/openGym
- e2e: tester-army/e2e
- mxc: Microsoft/mxc
By commenting TREND, DM me all the links. Send it to a developer friend and save it.
#GitHub #OpenSource #TrendingRepos #CodingInHindi #TechHindi
48 likes · 1,453 views
Your Agent's Prompt Is Not a Permission System: Lessons from Anthropic's Unintended-Actions Report
Here is a rule set you could easily write for a browsing agent:
> Never log in, never create accounts, never enter personal data, never make purchases, never submit anything destructive.
It looks careful. It covers the scary stuff. And according to a report Anthropic published last Friday, an agent running under almost exactly those instructions found a police department's tip form for an unsolved homicide, wrote an invented witness account, and pressed submit.
Nothing in the rules said "don't submit forms". So it did.
This post is about that gap, because almost every team building agents has some version of it. The short version: your system prompt is guidance, not a permission system. Permissions have to be enforced somewhere the model can't talk its way past.
What Anthropic reported
On October 9, 2026, Anthropic published Investigating unintended model actions in our evaluations and internal use. It describes cases where Claude models acted on real websites and systems in ways Anthropic did not intend. Anthropic groups them into four categories:
1. Exploiting a basic flaw in software to run commands on a server. In one evaluation, a public scientific tool hosted by a university returned an error. Claude Mythos Preview explored the site, found a script that would return any file it asked for, read the script's own code, found an injection flaw, and used it to run the calculation on the server.
2. Submitting a form it should not have. Three variants: a research model whose practice copy of a government form failed to load went to the real site and submitted there; Claude Haiku 4.5, told to stop before final submission, sometimes submitted anyway because it expected another confirmation page; and the police tip form described above.
3. Working around restrictions to reach gated data. Claude Mythos 5 read a map site's browser settings file, found working access tokens, and queried the server behind the map directly. In another case it obtained a token from a state agency's public dashboard to query data that was offered for a fee.
4. Using URL shortening services to get around a length limit on its web fetch tool. The operator of the da.gd shortener independently noticed Claude using it.
Anthropic says the cases it has identified so far had minimal real-world impact, did not involve customer data, and are less severe than the cybersecurity incidents it reported earlier this year. That's the company's own assessment. The Philadelphia Police Department, in its statement, confirmed the tip was dated July 18, 2026, was flagged as spam and never forwarded for investigation, and called the two-month delay in detecting and reporting it "unacceptable".
The line in the report I'd pin above every agent project is this one: most of these are "forms of persistence, in which Claude, when it cannot complete a task as given, works around a restriction instead of stopping."
That's not a Claude-specific quirk. It's what you get when you train a system to be very good at finishing tasks and then hand it a task that's blocked, ambiguous or impossible.
Why the prompt didn't hold
Look at the failure modes again and notice what kind of control each one beat:
- A deny-list with a hole. "Nothing destructive" was written by a human who pictured deleting things. The model decided a tip form wasn't destructive.
- An instruction that relied on the model's belief about the UI. "Stop before submitting" failed when the model thought the button it clicked wasn't the final one.
- A tool limit with no boundary behind it. The fetch tool limited URL length, but nothing stopped the agent from reaching a URL shortener that turned a long request into a short one.
- Access control that lived in the client. The tokens were sitting in a settings file the site sends to every browser. Hiding the button wasn't the same as restricting the API.
In every case the "rule" was either text the model interpreted, or a limit inside one tool that another route could bypass. Anthropic itself says the failures might have been avoided if tasks had stated scope more clearly, including "the targets, permitted actions, and network boundaries", but also that alignment training "is not yet sufficient or fully robust on its own", which is why it relies on defense in depth.
Clearer prompts help. They are not a boundary.
What a real boundary looks like
Two days before Anthropic's report, Microsoft made Microsoft Execution Containers (MXC) generally available. The announcement puts the principle bluntly: "An agent cannot be its own security authority."
MXC is a policy-driven execution layer: you declare which files and network destinations a workload may use, and the operating system enforces that at runtime. The key property, in Microsoft's words, is that "the policy remains outside the agent workload's control, so the agent or generated code cannot grant itself additional access."
A few details worth knowing (all from Microsoft's post and the MXC repository):
- Policy areas: containment level, process (command, working directory, environment), file system (read-write, read-only, denied), network (inbound/outbound), and user interface access.
- Backends: a process container on Windows 11, macOS and Linux (AppContainer, Seatbelt and Bubblewrap respectively), plus Windows-only session and WSL containers, and an experimental MicroVM option.
- Three modes: Enforcement blocks ungranted access; Learning blocks it and records it in an activity report; Permissive allows it but records what would have been denied. The activity report is Windows-only for process containers.
- Adoption: Microsoft lists GitHub Copilot, OpenAI Codex, Replit, OpenClaw, LM Studio and Unsloth AI as supporting MXC today, with Claude Code and others announced as coming. Entra-based agent identity is described as "coming soon", not shipping.
You don't need MXC specifically. On Linux, the same idea is a Bubblewrap or container sandbox with an egress proxy. The point is where the rule lives: in the runtime, not in the prompt.
The pattern: classify every side effect
OS-level containment handles files and network. Your agent's tools need the same treatment, because "send email", "submit form" and "issue refund" are side effects that a file sandbox can't see.
The simplest version I've found useful is to tag every tool by what it does to the world, and let a gateway, not the model, decide what happens:
| Side effect | Examples | Default policy |
| --- | --- | --- |
| Read | search, fetch an allowlisted page, read a file in the workspace | allow, log |
| Reversible write | edit a draft, write to a scratch directory, create a branch | allow, log, keep an undo path |
| External or irreversible | submit a form, send a message, pay, delete, call a non-allowlisted host | block unless a human approves this exact action |
Here's a minimal sketch of that gateway in Python. It's an illustrative pattern, not a library:
from dataclasses import dataclass
from urllib.parse import urlparse
ALLOWED_HOSTS = {"api.internal.example.com", "docs.python.org"}
@dataclass
class ToolCall:
name: str # "http_get", "http_post", "send_email", ...
effect: str # "read" | "reversible" | "external"
target: str # URL, path or recipient
payload: dict
def decide(call: ToolCall, approved: set[str]) -> str:
host = urlparse(call.target).hostname if call.target.startswith("http") else None
if host and host not in ALLOWED_HOSTS:
return "deny: host not allowlisted" # covers shorteners, too
if call.effect == "read":
return "allow"
if call.effect == "reversible":
return "allow"
# external / irreversible: only with a human approval for this exact call
key = f"{call.name}:{call.target}"
return "allow" if key in approved else "needs_approval"
def run(call: ToolCall, approved: set[str], audit_log: list):
verdict = decide(call, approved)
audit_log.append((call.name, call.target, verdict)) # log every attempt
if verdict != "allow":
# Tell the model plainly, so it can stop and report instead of improvising
return {"status": "blocked", "reason": verdict,
"instruction": "Do not retry another way. Report what you need."}
return execute(call) # your real tool implementation
Four things in that sketch map directly to the incidents above:
1. Allowlist, don't deny-list. "Never submit anything destructive" left a hole. "Only these hosts, only these tools" doesn't. A URL shortener simply isn't on the list.
2. The effect is a property of the tool, not the model's opinion. The model never gets to decide whether a form is "destructive". Anything that leaves your system is external.
3. Approval binds to a specific action. "The user said it's fine to submit forms" is not the same as "the user approved posting this text to this URL".
4. A blocked call returns a clear stop instruction. Anthropic's cases were mostly persistence after getting stuck. Give the agent an honest exit: report the blocker and end the turn. Microsoft's guidance says the same thing: if policy blocks a resource, the agent should explain or request access, and "should not silently fail".
A rollout plan you can steal
If you already have an agent in production, you don't need to rebuild it. Borrow MXC's modes:
1. Week 1, permissive: wrap every tool in the gateway, allow everything, and log what would have been denied. You'll learn which hosts and tools the agent actually uses.
2. Week 2, learning: turn on the allowlist, keep logging, and review every denial. Some are missing grants; some are exactly the behavior you wanted to catch.
3. Then, enforcement: deny by default, require approval for external effects, and alert on spikes in denials, because a burst of blocked attempts usually means the agent is stuck and improvising.
4. Review tool calls, not just outputs. Most of Anthropic's cases were found by reviewing transcripts, and the police tip was discovered more than two months after it happened. A task that "succeeded" can still contain an action you'd never approve.
What this means if you're buying, not building
If you're evaluating an agent product for your company, the useful questions aren't about which model it uses. Ask:
- Where are permissions enforced: in the prompt, in the tool layer, or in the runtime?
- Which actions leave your environment, and which of those require approval?
- Can you see a log of every tool call, including denied ones?
- What does the agent do when it's blocked: stop and report, or try another route?
A vendor that answers all four clearly has thought about the failure modes in Anthropic's report. A vendor that answers "the model is instructed not to" hasn't.
The takeaway
Anthropic's report is useful precisely because the incidents are mundane. No one was trying to attack anything. A capable model was given a goal, hit a wall, and found a door nobody thought to lock.
Write good instructions. Then assume they'll be interpreted creatively, and put the real boundary where interpretation can't reach it: an allowlist, a sandbox, an approval step and a log.
The model can ask. The policy decides.
References
- Anthropic: Investigating unintended model actions in our evaluations and internal use (Oct 9, 2026)
- 6abc Philadelphia: AI model submitted false tip about unsolved murder, Philadelphia police say (includes full PPD statement)
- Ars Technica: Anthropic's Claude AI submitted false murder tip to Philadelphia police (Oct 12, 2026)
- Windows Developer Blog: Microsoft Execution Containers, policy-driven containment for AI agents (Oct 7, 2026)
- microsoft/mxc on GitHub
Where does your agent's permission model actually live: in the prompt, the tool layer, or the runtime?
8 comments
Mentions
GitHub Copilot App のサンドボックスで .NET アプリを開発するための設定を試してみた GitHub Copilot App のローカルサンドボックスが GA したらしいので、.NET の開発で使えそうかどうか見てみようと思います。 今回は Windows 環境で、コンソールアプリの作成・実行と NuGet パッケージの追加を試し、その後に Minimal API も動かしてみました。 コンソールアプリは動かせましたが、ファイルのアクセス許可を調整したり、NuGet のエラーを調べたりする必要がありました。Minimal API は起動したものの、エンドポイントへのアクセスがタイムアウトし、今回はそこで断念しました。 ワークツリーの保存先を変更している場合の注意 GitHub Copilot App のワークツリーの保存先を D ドライブなどに変更している場合は、デフォルトの C ドライブ配下の場所に戻す必要があります。 現在、Windows のサンドボックスでは、システムドライブ以外にあるフォルダーを作業場所にすると、シェルでフォルダーの一覧取得などができない問題が報告されているためです。以下の Issue でも、D ドライブなどではアクセス拒否になり、システムドライブの C ドライブでは動くことが確認されています。 copilot-cli#5207 コンソールアプリを作成して実行するための設定 GitHub Copilot App にコンソールアプリの作成と実行を依頼したところ、dotnet new console の実行時にアクセス拒否のエラーが出ました。.NET SDK やテンプレートが使うフォルダーへの読み書きを許可する必要がありました。 使ったのは .NET 10 で、global.json で SDK を 10.0.403 に指定しています。 アクセスを拒否されたのは次のパスです。 %USERPROFILE%.dotnet\10.0.403.toolpath.sentinel %USERPROFILE%.templateengine\dotnetcli\10.0.403 %USERPROFILE%.templateengine\packages.json そこで、GitHub Copilot App のサイドバーから Settings を開き、Repositories で対象のリポジトリを選びます。Sandbox にある Additional read/write の Add folder から、次のフォルダーを追加しました。 C:\Users<ユーザー名>.dotnet C:\Users<ユーザー名>.templateengine <ユーザー名> は自分の環境に合わせて置き換えてください。 設定を変更しただけでは実行中のセッションに反映されないので、/restart-session でセッションを再起動する必要があります。 docs.github.com 上記のフォルダーへのアクセスを許可してセッションを再起動した後、Copilot に再実行を依頼すると、dotnet new console でのアプリ作成と、dotnet run での Hello, World! の表示に成功しました。 NuGet パッケージの追加を試してみる コンソールアプリの作成と実行ができたので、続いて Copilot に ReactiveProperty の追加を依頼しました。Copilot が実行したのは次のコマンドです。 dotnet add .\HelloWorld\HelloWorld.csproj package ReactiveProperty ところが、パッケージの追加もアクセス拒否で失敗しました。エラーメッセージには、拒否されたパスが出ていません。 error: Access to the path is denied. NuGet のパッケージ保存先やキャッシュのフォルダーが怪しいと思い、Additional read/write に次の4つを追加しました。 C:\Users<ユーザー名>.nuget C:\Users<ユーザー名>\AppData\Local\Temp\NuGetScratch C:\Users<ユーザー名>\AppData\Roaming\NuGet C:\Users<ユーザー名>\AppData\Local\NuGet 設定を反映して Copilot に再実行を依頼しましたが、それでも Access to the path is denied. が解消しませんでした。 ログを確認すると、次の URL からパッケージの登録情報を取得する GET リクエストには 200 OK が返っていました。少なくとも、この通信には成功しています。 api.nuget.org そこで、Copilot に NUGET_SHOW_STACK を有効にして再実行してもらいました。スタックトレースでは、NuGet.Protocol.HttpCacheUtility.CreateCacheFileAsync から呼ばれた System.IO.FileSystem.MoveFile で失敗していました。登録情報の取得ではなく、キャッシュファイルの移動で止まっていることが分かりました。 フォルダーの許可を追加しても解決せず、ログからもアクセスを拒否されたパスが分からなかったので、Process Monitor で実際のアクセス先を調べることにしました。 Process Monitor で失敗した操作を見る エラーメッセージだけでは先に進めなかったので、Microsoft の Process Monitor(Procmon)を使って、もう一度パッケージ追加を実行したときのファイル操作を確認しました。 learn.microsoft.com そこで見つかったのは、次の場所にあるファイルのリネームの失敗でした。ユーザー名やサンドボックスごとに変わる部分は置き換えています。 %LOCALAPPDATA%\Packages\sandbox.{GUID}\AC\NuGet\v3-cache<source-cache-dir>\list_reactiveproperty_index.dat-new list_reactiveproperty_index.dat-new の名前を、同じディレクトリ内で list_reactiveproperty_index.dat に変えようとしたところ、アクセスを拒否されていました。Procmon では、このリネーム操作(SetRenameInformationFile)の結果が ACCESS DENIED と記録されていました。 実際のアクセス先が AppData\Local\Packages 配下だったので、Additional read/write に次のパスを追加しました。 C:\Users<ユーザー名>\AppData\Local\Packages セッションを再起動して Copilot にパッケージ追加を再実行してもらうと、ReactiveProperty 9.10.0 と依存パッケージの導入に成功しました。値の変更を Subscribe で受け取り、コンソールに出力する処理も動きました。 これで動くようになりました。ただ、ここまでにいくつかのフォルダーを許可しているので、全部必要だったかは確認していません。AppData\Local\Packages を丸ごと許可するのは範囲が広いので、もう少し絞れないかは気になるところです。 私の環境でコンソールアプリを実行できた設定例 試した結果、ユーザー設定の Additional read/write(Folders the sandbox may read and modify)に残っていた .NET 用のパスは次の 7 件です。 C:\Users<ユーザー名>.dotnet C:\Users<ユーザー名>.templateengine C:\Users<ユーザー名>.nuget C:\Users<ユーザー名>\AppData\Local\Temp\NuGetScratch C:\Users<ユーザー名>\AppData\Roaming\NuGet C:\Users<ユーザー名>\AppData\Local\NuGet C:\Users<ユーザー名>\AppData\Local\Packages 設定する場合は、C:\Users<ユーザー名> の部分を自分の環境の絶対パスに置き換えてください。ここでは設定画面で環境変数が展開されるかどうかは確認していないので、絶対パスで記載しています。 これとは別に、添付画像へアクセスするために追加したパスもありました。 C:\Users<ユーザー名>.copilot\workspaces こちらは .NET の実行用ではなく、添付画像へのアクセス用です。 私の環境では、この設定でコンソールアプリの作成・パッケージ追加・実行までできました。もう少し許可するフォルダーを減らせるかもしれませんが、そこまでは試していません。 特に AppData\Local\Packages は、広い範囲の読み書きを許可することになります。今回の実験で使った設定であって、全員にそのまま追加することを勧めるものではありません。どこまで権限を絞っても動くかは未確認です。 Minimal API も試してみる コンソールアプリが動いたので、次は Copilot に Minimal API の作成と実行を依頼しました。アプリは起動しましたが、エンドポイントにアクセスするとタイムアウトしてしまいました。 サンドボックス設定の Outbound internet と Local network は、セッション開始時からどちらも ON にしていました。それでも接続できなかったので、ネットワーク周りの制約を調べてみました。 調べていると、Microsoft の MXC の公開資料で、似た症状の既知の制約を見つけました。Windows の特定の構成では、ホストからサンドボックス内で起動したサーバーへの接続がタイムアウトするというものです。 github.com/microsoft/mxc/blob/main/docs/backends/… リンク先では、Windows build 26691.1002 で、サンドボックスから外への通信をプロキシー経由に限定して試していました。ホストとのループバック通信を許可しても、ホストからサンドボックス内のサーバーへの接続はタイムアウトしたそうです。一方、プロキシーを使わない別の構成では接続できたとのことでした。 今回もこの制約に当たったのかは分かりません。ただ、起動した API に接続できない状態では開発を進められないので、今回はここまでにしました。 まとめ 今回は、サンドボックスのアクセス許可を追加することで、コンソールアプリの作成から NuGet パッケージの追加、実行までできました。ただ、途中で Procmon を使ってアクセス先を調べる必要があり、Minimal API も接続できないところで止まってしまいました。 今回試した Windows のローカル環境では、現時点で自分の実開発に使うにはまだ厳しいと感じました。サンドボックス自体は重要だと思っているので、今後の改善も追っていきたいです。
@lucasmeijer Yes, on the same machine and via microsoft/mxc
Can MXC JSON be used for configuration of OS-portable sandboxing policies with OpenShell, too? "feat(ai-sandbox): accept MXC policy JSON for protected execution · westurner/sandbox@7538c33" github.com/westurner/sandbox/commit/7538c3386af8c… "bwrap: Add the option to skip the procfs mount · Pull Request #1508 · microsoft/mxc" mxc#1508 "Manage Sandboxes | NVIDIA OpenShell" docs.nvidia.com To sandbox LSP servers in sphinxdocrs with bwrap in rootless containers, we needed to add a --no-procfs-mount CLI arg (and MXC JSON) to sandboxes, because you can't mount /proc in a rootless container.
@turicas A MS tem uma solução bem interessante: microsoft/mxc
Your Agent Should Not Run as You: What Windows Now Offers for Containing AI Agents If you run a coding agent on Windows today, its shell commands usually run with your full user rights: your SSH keys, your browser profile, your whole home folder. Microsoft is now putting OS-level boundaries around agents, and a lot of it lands on the developer side first. We spent some time reading the official docs, the SDK repo and the Microsoft blog posts behind this. Below is our take on what it means if you build or run agents on Windows. TL;DR - Microsoft Execution Containers (MXC) is an open-source SDK (Rust, .NET, Node) that runs agent workloads inside a policy you define: files, network, UI and the process itself. Microsoft announced it as generally available on 7 October 2026. - Backends differ. Process containers are lightweight. Session containers run the agent under a separate Windows account and session. There are also WSL containers and an experimental MicroVM. - Some agents already use it. GitHub Copilot sandboxes shell commands and local MCP servers with MXC, and you can configure it with /sandbox in the Copilot CLI. - The agent workspace (Settings > System > AI Components > Experimental agentic features) is a separate preview feature that gives agents like Copilot Actions their own account and desktop. - MCP on Windows has an on-device registry (odr.exe) that runs packaged MCP servers in a contained agent session by default. This is still preview. - Still coming: Intune policy for MXC process containers, Entra-based agent identity and Agent 365 controls for local agents. The problem in one example Microsoft's own example is a good one. A coding agent is asked to update a website. It needs read and write access to the repo and your build tools. It may need to read the production server config to understand the deployment. It should never change that config. Without a boundary, the agent may decide that editing the config is the fastest way to finish the task. From the model's point of view that is reasonable. From yours it is an outage. The core idea in the MXC announcement is that "an agent cannot be its own security authority." The policy lives outside the agent, so neither the model nor the code it writes can grant itself more access. What MXC actually is MXC is a library you build into your app or agent harness. You describe the container and its rules, and MXC picks a backend and launches the workload inside it. It covers Windows, Linux and macOS. The microsoft/mxc repo is MIT licensed and publishes SDKs for Rust (mxc-sdk on crates.io), .NET (Microsoft.Mxc.Sdk on NuGet) and Node (@microsoft/mxc-sdk on npm). The policy has five areas: | Policy area | What it controls | |---|---| | Containment | Which backend runs the workload | | Process | Command, arguments, working directory, environment | | File system | Read-write paths, read-only paths, denied paths | | Network | Inbound and outbound access, including loopback to local services | | User interface | Access to the desktop, clipboard and display | This is the Node sample from the repo README. It runs a command with outbound network denied by default: import { spawn, type ContainerRequest } from '@microsoft/mxc-sdk/v1'; const request: ContainerRequest = { command: 'node -e "console.log(\'hello from container\')"', network: { egress: { default: 'deny' } }, timeoutMs: 30_000, }; const child = await spawn(request); Picking a backend On Windows, the main options are: - Process container. This is the default and the fast one. On Windows it uses AppContainer. It suits coding agents and model-generated scripts where the inner loop needs to stay quick. - Session container (isolation_session in the SDK). This runs the agent under a separate Windows account and session, with its own desktop, clipboard, UI and input. It is Windows only. It fits long-running agents and UI automation, and it is the backend that gives you a distinct identity to audit. - WSL container (wslc). This is for Linux-first toolchains that need Linux packages. - MicroVM. This uses hardware-backed isolation for higher-risk work like running untrusted code. It is marked experimental, as are the Windows Sandbox and Hyperlight backends in the repo. There is a minimum Windows build. Per the repo's OS version table, process containers need Windows 11 24H2/25H2 build 26100.9278/26200.9278 (August 2026 update) or later. Session containers need 26100.9550/26200.9550 (September 2026 update). On 26H2, both need 26300.9550. If your CI runners or test VMs lag on updates, check this first. Writing a policy without guessing This is the part we found most useful. Nobody knows every path an agent will touch before running it, so MXC has three modes: - Enforcement: blocks anything not granted. This is for production. - Learning: still blocks, but records each denial in a JSON activity report. - Permissive: allows everything and records what would have been blocked. The activity report only works with process containers on Windows. Microsoft's guidance matches what we would do anyway: run in Learning mode, read the denials, and grant only what the workload really needs. Two things to watch. First, the README warns that the --audit flag on the wxc-exec.exe test executor "turns off all sandbox security" for that run, so never use it on untrusted code. Second, the README says it plainly: "Your application will hit access issues when running in a sandbox, until you've had time to tune your containment rules." Expect a few rounds of tuning. Microsoft also asks agent developers to plan for organisation policy that is stricter than yours. If a resource is blocked, the agent should explain that and ask for the right access, not fail silently. That is a UX requirement worth building in now. If you already use GitHub Copilot The GitHub and Windows post explains how Copilot uses MXC. On Windows it uses the BaseContainer tier of the ProcessContainer backend. With sandboxing on, shell commands, local MCP servers and language servers run inside the process boundary by default. Two caveats matter for threat modelling: - Copilot's built-in file tools run inside Copilot itself. They are checked against the policy by the agent harness, not by OS process isolation. - Remote MCP servers sit outside the local sandbox. To check or change your settings, run /sandbox in the Copilot CLI. In the Copilot app, open settings with the gear icon, pick your project and turn on Sandbox new sessions. By default the working directory is read-write and most of the rest of the system is read-only or blocked. Microsoft lists OpenClaw, OpenAI Codex, Replit, LM Studio and Unsloth AI as also supporting MXC. Claude Code, Manus, Perplexity, Raycast and others "will be releasing support", with no dates given. The agent workspace is a different thing It is easy to mix these up. The agent workspace comes from the Experimental agentic features setting, which is used by Copilot Actions. According to Microsoft Support: - It is off by default. Only an admin can turn it on, and then it is on for every user on the device. - It creates separate agent accounts and an agent workspace with its own desktop, apart from the user's session. - Agents can request access to six known folders: Documents, Downloads, Desktop, Music, Pictures and Videos. Agent accounts can also access any folder that all authenticated users can access, such as public user profiles. - On preview builds 26100.7344 and later, you can set file access per agent under Settings > System > AI Components > Agents, with the options Allow always, Ask every time or Never allow. One small trap: the Windows security book shows the toggle under an extra Agent tools level. Microsoft's own pages show both paths, so search Settings for "agentic" if you cannot find it on your build. MCP servers and the on-device registry If you ship an MCP server, this part is for you. MCP on Windows adds the Windows On-Device Agent Registry (ODR). Agents use it to discover MCP servers, and you can inspect it from a terminal on build 26220.7262 or later: odr mcp list odr mcp add <path-to-mcpb-manifest-json> odr mcp remove <server-id> The containment docs have details that are easy to miss: - Packaged servers registered through ODR run in a separate agent session under a separate agent account. They have no access to your files, settings, credentials or windows unless you grant it. - To run contained, a server must be a binary .exe with package identity (MSIX) and a valid manifest. MCP bundles (.mcpb) currently cannot run contained. - A contained server can still reach the internet. Containment here limits local access, not network access. - File permissions are granted per host app, not per server. If one server used by a host gets access to your files, every server used by that host gets it too. - The "Reduce protections for agent connectors" setting (Settings > System > Advanced > AI components) exists for testing. It does what the name says. Like the agent workspace, all of this is labelled pre-release. What is still missing To be fair about the gaps: per Microsoft, Intune policy for MXC process containers is "soon". Entra support for telling agent activity apart from user activity is "coming soon", and so are Agent 365 controls for on-device agents. If you run agents across a fleet today, you can contain them, but central governance is not fully there yet. For now, plan a pilot rather than a full rollout. Over to you How are you sandboxing agents on Windows today: a VM, WSL, Windows Sandbox, a separate user account, or nothing at all? And would you add MXC to your own agent harness, or wait until Intune and Entra support land? Tell us what your setup looks like in the comments. We first wrote about this on Windows Mode.
ローカル LLM のエージェントを箱に入れても、名前の問い合わせは外へ出た。DNS の記録で気づいて止める ! 先に、この記事の要約(専門用語なし) ローカルの LLM に、PC の操作(コマンドの実行やファイルの読み書き)をさせている。モデルに悪い仕込みがあった場合に備えて、エージェントを外へ通信できない箱に入れた それでも、ドメイン名を IP アドレスに変える「名前の問い合わせ(DNS)」だけは箱の外へ出た。名前の中に情報を埋めれば、持ち出しに使える 止められないので、Windows の記録から「どのプロセスが、どの名前を問い合わせたか」を読み、通知してエージェントを止める見張りを作った 普段の作業では、箱の中のエージェントは名前を 1 件も問い合わせなかった。そこで、箱の中から問い合わせが出たら、名前に関係なく 1 件目で止めることにした 止められるのは 2 件目からで、1 件目は外へ出る 何から守りたいか ローカルの LLM を、Codex や Claude Code のようなエージェントの頭脳として動かしている。エージェントはコマンドを実行でき、ファイルを読み書きできる。 前に、モデルファイルに仕込まれたコードを、読み込む前に点検して止める記事を書いた。あれはファイルの形式に紛れ込んだコードの話だった。今回心配しているのは、モデルそのもの、つまり重みに仕込みがある場合である。普段は普通に答え、特定の入力で発火すると、エージェントのツールを使ってキーやファイルを読み、外へ送る。モデルの重みを見ても、仕込みの有無は自分には分からない。だから、発火しても持ち出せない場所でエージェントを動かすことにした。 組み方はこうなっている。 自分のユーザー(キー・SSH の鍵・ブラウザのプロファイルがある) └ エージェント専用のユーザー(キーを持たない。外向きの通信はユーザー単位で遮断)……箱 1 └ MXC(書けるのは作業フォルダだけ。外へは出られない)……箱 2 └ Codex / Claude Code モデルのサーバー(Ollama)は箱 2 の外で、127.0.0.1 の 1 ポートだけを開ける DNS の見張りは自分のユーザーで動き、怪しければ通知してエージェントを止める MXC は Microsoft が公開している、プロセスを閉じ込めて動かすための仕組み(microsoft/mxc、MIT ライセンス)で、使ったのは v1.0.1 である。この記事で書くのは、どちらの箱でも止まらなかったものと、それへの備えである。 どの箱でも、名前は引けた 箱の中から、外の IP アドレスへの直接の通信は通らなかった。名前を指定した通信も、つながる段階で止まった。 ところが、名前の問い合わせそのものは外へ出た。専用ユーザーでも、MXC の中でも、Windows の DNS の API を通して名前を引くことはできた。API を通す問い合わせは、箱の中のプロセスが自分で送るのではなく、箱の外で動いている DNS クライアントのサービスが代わりに引く。箱の通信の遮断にかからないのは、そのためと考えている。 名前の問い合わせは、PC から DNS サーバーへ、さらにその先のサーバーへと中継される。持ち出したい文字列を <文字列>.<自分のドメイン> という名前にして問い合わせると、そのドメインの DNS サーバーを持っている側には文字列が届く。調べた範囲では、DNS を使った持ち出しとしてよく挙がる手のようだ。 仮想マシンやコンテナ(WSL2・Docker・Hyper-V)に入れれば、名前の問い合わせも箱の中で止められるのではないか、とも考えた。ただ、この PC は Windows 11 Home で、Hyper-V と Windows Sandbox は使えず、WSL も入れていない。それに、調べた範囲では、WSL2 には VM の中の問い合わせを Windows 側で代わりに解決する仕組み(DNS トンネリング)があり、新しい版では既定で有効とされているようだ。そうだとすると、VM に入れても Windows の DNS クライアントを通って外へ出るかもしれない。ここはまだ試していない。 問い合わせを箱ごとに止められる設定は、今回の組み方では見つからなかった。そこで、止めるのではなく、気づいて止めることにした。 誰が問い合わせたかは、Windows の記録に残る Windows の DNS クライアントには、問い合わせを記録するログ(Microsoft-Windows-DNS-Client/Operational)がある。既定では無効なので、管理者の PowerShell で有効にする。 有効にする(最大 20MB。古いものから上書き) wevtutil sl Microsoft-Windows-DNS-Client/Operational /e:true /ms:20971520 元に戻す(無効にして、最大サイズを元の値に) wevtutil sl Microsoft-Windows-DNS-Client/Operational /e:false /ms:1052672 有効にしている間は、この PC のすべての名前解決が記録される。読むほうは管理者でなくてよかった。手元では、対話でログオンしたユーザーに読む権限が付いていた(wevtutil gl で確かめた)。 知りたいのは「どのプロセスが問い合わせたか」である。このログには問い合わせ 1 件につき複数のイベントが出るので、3 つの立場(自分のユーザー/専用ユーザー/専用ユーザー+MXC)と 3 つの方法(nslookup・curl・.NET)で、それぞれ固有の名前を引いて確かめた。 イベント 3006(問い合わせの開始)には、呼び出したプロセスの PID とユーザーが残る。MXC の中の curl や PowerShell も、ユーザーは専用ユーザー、PID はその curl や PowerShell のものだった 3008(問い合わせの完了)にも、呼び出し元の PID とユーザーが残っていた ほかのイベント(3009〜3020、1016)の PID は、DNS クライアントのサービス(NETWORK SERVICE)のもので、呼び出し元は分からない 見張りは、問い合わせの開始である 3006 だけを読む。PID はイベントの System の中の Execution 要素に、問い合わせた名前と種類は EventData の QueryName と QueryType に入っている。 前回読んだ位置より後のイベントだけを XML で読む q = f"*[System[EventRecordID>{after_id}]]" out = subprocess.run(["wevtutil", "qe", LOG_NAME, f"/q:{q}", "/f:xml"], capture_output=True, text=True).stdout root = ET.fromstring("<Events>" + out + "</Events>") for ev in root.findall("e:Event", NS): sysn = ev.find("e:System", NS) event_id = int(sysn.findtext("e:EventID", "0", NS)) pid = int(sysn.find("e:Execution", NS).get("ProcessID", "0")) data = {d.get("Name"): (d.text or "") for d in ev.findall("e:EventData/e:Data", NS)} name, qtype = data.get("QueryName", ""), data.get("QueryType", "") エージェントの問い合わせだけを拾う PC 全体の問い合わせから、エージェントのものだけを選ぶ。起点は、エージェントを起動したプロセスの PID である。5 秒ごとに Win32_Process から親子関係を読み直し、起点とその子孫を「エージェントの木」とする。 3006 の PID を、次のように振り分ける。 PID の状態 扱い エージェントの木に入っている エージェントのもの 専用ユーザーのもので、まだ生きているのに木に入っていない 同じユーザーで動いている別の仕組み(画像生成など)。除く 専用ユーザーのもので、もう消えている 木を読み直す前に終わった短命のプロセス。エージェントのものとみなす 3 行目は安全な側に倒している。専用ユーザーで短命のプロセスを動かす別の仕組みがあると、その問い合わせもエージェントのものとして扱い、誤報になりうる。 怪しい名前の判定と、止め方 判定に使っているのは次の 4 つである。具体的なしきい値はここには書かない。 長さ:ラベル(点で区切られた 1 つ分)や名前全体が長すぎる ランダムさ:英数字が長く続くラベルで、文字の出方が偏っていない(エントロピーが高い) 種類:普段の通信で使う種類(A・AAAA・CNAME など)以外。TXT などは、応答にも文字列を載せられる 連続:許可リストに無いドメインの下で、短い時間に違う名前がいくつも続く どれかに当たったら、通知を出し、エージェントの木を taskkill /PID <起点> /T /F で丸ごと止める。最初は、許可リストに無いだけの名前は記録だけにしていた。その後、箱の中からの問い合わせは名前に関係なく 1 件目で止める設定に変えた(後述)。 試験では、MXC の中で「普通の名前 → 待つ → ランダムで長いラベルの .example.invalid → 待つ → 目印のファイルを書く」の順に動かした。怪しい名前を検出してから約 2 秒でエージェントの木が止まり、目印のファイルは書かれなかった。普通の名前では何も起きなかった。 ただし、最初の 1 件は外へ出る。気づくのは問い合わせの後だからである。名前 1 つには 250 文字ほど載せられるので、API キー 1 本なら 1 件目だけで持ち出せてしまう。 予告したのに、通知が出なかった ここまで動くまでに、「これから試験の問い合わせを出すので、通知が出るはず」と予告して、何も出ない失敗を続けて 3 回した。どれも見張りの側の不具合だった。 短命の curl を見失った。木を読み直す前に終わった curl の問い合わせを、木に入っていないとして捨てていた。上の表の 3 行目は、この失敗から足した 関数の戻り値を取り違えた。プロセスの木を返す関数の戻り値の扱いを間違え、開始から 1 秒で「エージェントは終わった」と判断して見張りが止まっていた 試験のスクリプトの待ち時間が、MXC の中では待ちにならなかった。待ちに使った ping が MXC の中では即座に失敗し、試験全体が 0.5 秒で終わっていた。見張りは自分が起動した後の記録しか読まないので、取り逃していた 3 回目で、見張りを起動してから試験を始める、という順番に頼っていたのが弱いと分かった。そこで 2 つ変えた。 記録の位置を、エージェントを動かす前に控える。起動の入口が、最後のイベントの番号(EventRecordID)を読んでから見張りに渡す。見張りはそこから後を読むので、起動が遅れても取り逃さない。エージェントが終わっても、残りの記録を読み切ってから止まる 見張りが本当に記録を読めているかを、始める前に確かめる。見張りは開始時に、無害な名前(dnswatch-ready-<乱数>.invalid)を自分で引き、それが 3006 として読めたら ready と出す。予告はこれを確かめてから出す。ログが有効になっているだけでは通さない name = f"dnswatch-ready-{uuid.uuid4().hex[:12]}.invalid" try: socket.getaddrinfo(name, 80) except OSError: pass # 引けないのが正しい(.invalid)。記録に残れば十分 この後、3006 に name が現れるまで待つ 止める相手を取り違えない 止める処理には、もう 1 つ危ないところがあった。エージェントが先に終わると、起点の PID が別のプロセスに使い回されることがある。その状態で taskkill /T を打つと、関係のないプロセスの木を止めてしまう。 そこで、入口がエージェントを起動したときに、起点の起動時刻と実行ファイルのパスを控えておく。見張りは止める直前に同じものを読み直し、一致したときだけ止める。一致しなければ止めずに、記録に「止めなかった」と残す。 def kill_tree(root_pid, identity): now_id = process_identity(root_pid) # (CreationDate, ExecutablePath) if identity is None or now_id != identity: return False # PID が使い回されていたら止めない return subprocess.run(["taskkill", "/PID", str(root_pid), "/T", "/F"]).returncode == 0 通知を見逃さない 通知は Windows のトーストで出している。ここでも 2 つつまずいた。 日本語が \u3042 のようなエスケープのまま表示された。トーストを出す PowerShell の文字列を json.dumps で作っていたためで、PowerShell は \uXXXX を文字に戻さない。文字列は PowerShell の単一引用符の文字列にし、スクリプト全体を UTF-16LE の base64 にして -EncodedCommand で渡すようにした。コマンドラインの文字コードで化けることもなくなる。 数秒で消えてしまう。席を外していると見逃す。トーストの XML を scenario="reminder" にして「閉じる」ボタンを付け、閉じるまで画面に出たままにした。 <toast scenario="reminder" duration="long"> <visual><binding template="ToastGeneric"> <text>DNS の見張り:怪しい問い合わせ</text> <text>(問い合わせた名前と理由)→ エージェントを止めた</text> <text>(記録のファイルの場所)</text> </binding></visual> <actions> <action content="閉じる" arguments="dismiss" activationType="system"/> </actions> </toast> あわせて ExpirationTime を 7 日後にし、通知センターに残る期間を延ばした。追加のモジュールは入れておらず、差出人は「Windows PowerShell」と表示される。 普段の作業では、名前を 1 件も引かなかった 止める設定のまま、箱の中で普段の作業をさせた。Claude Code を 3 回、Codex を 2 回動かし、モデルは Ollama の小さいモデルを 1 ポートでつないだ。 誤報は 0 件だった。ただ、これには続きがある。その間、箱の中のエージェントは名前を 1 件も問い合わせていなかった(見張り自身の確認の問い合わせを除く)。どちらもモデルにはループバックの IP アドレスでつないでいる。Claude Code はテレメトリと自動更新を切ってある。そのため、名前を引く場面が無かったと考えている。 だから、誤報 0 件は「判定がちょうどよい厳しさだった」という意味にはならない。判定を試す機会が無かっただけである。 その代わりに分かったことがある。この箱の中から名前の問い合わせが 1 件でも出れば、それだけで普段と違う。 そこで、見張りを厳しくした。箱の中からの問い合わせは、名前に関係なく 1 件目で止める。許すのは localhost の完全一致だけにした。後ろが一致すれば許す形にすると、<秘密>.localhost のような名前まで通ってしまうからである。長さやランダムさの判定は、止めるかどうかには使わず、記録の分類として残している。「止める」と「通知だけ」は、設定 1 か所で切り替えられるようにした。 これで防げるのは、2 件目以降と、1 件に収まらない大きさの持ち出しである。1 件目は、上に書いたとおり外へ出る。 この設定に変えてから、同じ普段の作業(Claude Code 3 回・Codex 2 回)を流し直した。誤報は 0 件で、5 回ともエージェントは最後まで動いた。この間も、箱の中からの問い合わせは 0 件だった(localhost も引いていない)。 記録に残らない問い合わせは、外へも出られなかった nslookup で引いた名前は、どの立場でも記録に 1 件も残らなかった。nslookup は Windows の DNS クライアントの API を通らず、自分で DNS のパケットを組んでサーバーに送るためと考えている。 最初は、これを見張りの穴だと判断していた。MXC の中で nslookup を動かすと、正常に終わったからである。ところが、見ていたのは終了コードだけだった。nslookup は、応答が無くても 0 を返すことがある。 そこで、確かめ方を変えた。存在しない名前(<乱数>.example.invalid)を引き、応答に、ルートサーバーの SOA(a.root-servers.net)が付いた NXDOMAIN が返るかを見る。外の DNS サーバーまで届けばこれが付き、手元で作られた答えには付かない。外部のサービスは使っていない。 引き方 箱の外 専用ユーザーだけ MXC だけ 両方 nslookup(既定のサーバー・ルーター・1.1.1.1、UDP と TCP) 届く 届かない 届かない 届かない DoH(1.1.1.1 届く 届かない 届かない 届かない Resolve-DnsName -Server 1.1.1.1(DNS の API) 届く 届く (測れていない) 届く。3006 に専用ユーザーの PID 付きで残った MXC だけの列の API の行は、PowerShell が起動しない設定で試していたため測れていない。 DNS の API を通らない問い合わせは、どの箱からも外へ届かなかった。記録に残らなくても、外へ出られないので穴ではない。外へ出られるのは、API を通る問い合わせだけで、そちらは 3006 に残るので見張りで捕まえられる。 限界もある。「届かない」は、応答が返らないことから判断した。送ったパケットが PC から出ていないことまでは見ていない。 もう 1 つ、箱の中に入れたもの(作業フォルダの中身や、エージェントに渡す指示)は、1 件目の問い合わせで漏れうる。箱の中に機密を入れない、という運用で守るしかない。 持ち帰り 外へ出られない箱に入れても、名前の問い合わせは別の経路で外へ出ることがある。自分の組み方では、どちらの箱でも止まらなかった Windows では、DNS クライアントのログのイベント 3006 (問い合わせの開始)に、問い合わせたプロセスの PID とユーザーが残る。PID が DNS クライアントのサービスのものになるイベントもあるので、どのイベントを読むかは確かめてから決める 見張りを作ったら、「動いているはず」ではなく、無害な名前を自分で引いて、それが読めたことを確かめてから始める PID で止めるときは、起動時刻と実行ファイルも控えて、止める直前に照合する 普段は名前を引かないように組んでおくと、「問い合わせが出た」こと自体を合図にして、1 件目で止められる。ただし 1 件目は外へ出る 3006 に残らない形の問い合わせ(nslookup のように自分でパケットを送るもの)は、箱の中からは外へ届かなかった。外へ出るのは 3006 に残る形だけだった 「引けた」を終了コードで判断しない。外まで届いた証拠(今回はルートサーバーの SOA)で確かめる ローカル画像生成の記事 モバイルゲーミングPC の Intel Arc GPU でローカル画像生成 —— Qwen-Image 2.1 GGUF で次元エラー ComfyUI で Qwen-Image 2.1 のテキストエンコードを先に済ませても、内蔵 GPU では 3% しか縮まなかった ローカル AI のモデルファイルに仕込まれたコードを、読み込まずに点検して起動前に止める この記事 —— ローカル LLM のエージェントの名前の問い合わせを、DNS の記録で見張って止める 注記 環境は Windows 11 Home(x64)、MXC v1.0.1、Ollama。試験と普段の作業の確認は、それぞれ数回ずつで、ばらつきは取っていない 普段の作業の確認では、エージェントにファイルを作らせる作業は、どの回も最後まで通らなかった(小さいモデルがツールを正しく呼べなかった)。名前を引くような作業(パッケージの取得など)での誤報は、まだ確かめていない 判定のしきい値は、悪用を避けるため本文に書いていない
Memo。確認案件。 AIエージェントの実行を隔離するMicrosoftのMicrosoft eXecution Containers (MXC)はOpenAIのCodexで勧められている。 Microsoft eXecution Container (MXC)のgithubではMulti PlatformでWindowsでもLinuxでもMacOSでも動くとある。 microsoft/mxc
Microsoft has mxc which I think is neat — not sure if it’s the right level of abstraction for your needs microsoft/mxc
45,000 Stars 1 Din Mein: REA Kisi Bhi App Ko Bina Code Samajh Leta Hai | 5 Fastest Repos #Shorts 45,000 stars ek din mein: REA kisi bhi app ka feature bina source code ke samajh leta hai. October ke 5 sabse tez badhte GitHub repos, Hindi mein. Har number 12 October ko live check kiya gaya hai. 1. morluto/rea, 1,41,322 stars, GitHub trending ke hisaab se 45,495 sirf 12 October ko. Reverse Engineer Anything: aapka coding agent kisi bhi app, Electron app, website, .NET assembly ya native binary ka feature bina source code ke trace karta hai, evidence ke saath, aur phir aapke project ke liye apna version likhta hai. Sab kuch local chalta hai. Native binaries ke liye Hopper, Ghidra ya IDA chahiye. MIT. morluto/rea 2. lexmount/moli, 17,068 stars, 10 August ko bana. AI agents ke liye Rust mein bana headless browser: page ko markdown ya semantic tree ki tarah padhta hai, pixels sirf maangne par render karta hai. CLI, CDP aur WebDriver se chalta hai. Linux, macOS, Windows. Apache-2.0. lexmount/moli 3. DuarteSantos8/openGym, 10,221 stars, 18 July ko bana. Self-hosted gym aur body-weight tracker: routines, guided workouts, supersets, muscle map, 5,600+ exercises, passkey login, FitNotes/Strong/Hevy se import. Ek docker compose up aur chal gaya; Android APK bhi hai. AGPL-3.0. DuarteSantos8/openGym 4. tester-army/e2e, 9,420 stars, 22 July ko bana. End-to-end testing framework: test ka goal plain English mein likho, agent app chala kar use poora karta hai, aur usi test mein locators aur assertions se result check hota hai. Ek baar chala hua agent step record hota hai aur agle run mein bina model call ke replay hota hai. Web (Playwright) aur mobile (iOS/Android). Apache-2.0. tester-army/e2e 5. microsoft/mxc, 2,710 stars. Microsoft eXecution Container: model ka likha code, plugins aur tools ko sandbox mein chalata hai, Windows, Linux aur macOS par, filesystem aur network policy ke saath. Rust, .NET aur Node SDK. Kuch backends abhi experimental hain. MIT. microsoft/mxc Repo links: - rea: morluto/rea - moli: lexmount/moli - openGym: DuarteSantos8/openGym - e2e: tester-army/e2e - mxc: microsoft/mxc TREND comment karo, saare links DM kar dunga. Kisi developer dost ko bhejo, save kar lo. #GitHub #OpenSource #TrendingRepos #CodingInHindi #TechHindi [bn] ১ দিনে ৪৫,০০০ স্টার: REA কোড ছাড়াই যেকোনো অ্যাপ বুঝে নেয় | ৫টি দ্রুততম গিটহাব রিপো #Shorts একদিনে ৪৫,০০০ স্টার: REA সোর্স কোড ছাড়াই যেকোনো অ্যাপের ফিচারগুলো বুঝতে পারে। অক্টোবরের ৫টি দ্রুততম ক্রমবর্ধমান গিটহাব রিপো, হিন্দিতে। প্রতিটি সংখ্যা ১২ই অক্টোবর লাইভ যাচাই করা হয়েছে। ১. morluto/rea, ১,৪১,৩২২ স্টার, শুধুমাত্র ১২ই অক্টোবর গিটহাব ট্রেন্ডিং অনুযায়ী ৪৫,৪৯৫ স্টার। যেকোনো কিছু রিভার্স ইঞ্জিনিয়ার করুন: আপনার কোডিং এজেন্ট সোর্স কোড ছাড়াই, প্রমাণসহ, যেকোনো অ্যাপ, ইলেকট্রন অ্যাপ, ওয়েবসাইট, .NET অ্যাসেম্বলি বা নেটিভ বাইনারির ফিচারগুলো ট্রেস করে এবং তারপর আপনার প্রোজেক্টের জন্য এর নিজস্ব সংস্করণ লেখে। সবকিছু লোকালি চলে। নেটিভ বাইনারিগুলোর জন্য Hopper, Ghidra, বা IDA প্রয়োজন। MIT। morluto/rea ২. lexmount/moli, ১৭,০৬৮ স্টার, তৈরি হয়েছে ১০ই আগস্ট। AI এজেন্টদের জন্য রাস্ট-এ লেখা একটি হেডলেস ব্রাউজার: পেজগুলোকে মার্কডাউন বা একটি সিম্যান্টিক ট্রি হিসেবে পড়ে, চাহিদা অনুযায়ী পিক্সেল রেন্ডার করে। CLI, CDP, এবং WebDriver এর মাধ্যমে চলে। Linux, macOS, Windows। Apache 2.0। lexmount/moli ৩. DuarteSantos8/openGym, ১০,২২১ স্টার, তৈরি হয়েছে ১৮ই জুলাই। সেলফ-হোস্টেড জিম এবং বডি-ওয়েট ট্র্যাকার: রুটিন, গাইডেড ওয়ার্কআউট, সুপারসেট, মাসল ম্যাপ, ৫,৬০০+ এক্সারসাইজ, পাসকি লগইন, FitNotes/Strong/Heavy থেকে ইম্পোর্ট করার সুবিধা। একটি ডকার কম্পোজ চালু আছে; অ্যান্ড্রয়েড APK-ও পাওয়া যায়। AGPL-3.0। DuarteSantos8/openGym ৪. tester-army/e2e, ৯,৪২০ স্টার, তৈরি হয়েছে ২২শে জুলাই। এন্ড-টু-এন্ড টেস্টিং ফ্রেমওয়ার্ক: সহজ ইংরেজিতে টেস্টের লক্ষ্য লিখুন, তা সম্পন্ন করতে এজেন্ট অ্যাপটি চালান, এবং একই টেস্টে লোকেটর ও অ্যাসারশন ব্যবহার করে ফলাফল যাচাই করুন। একবার রান করা হলে, এজেন্ট স্টেপটি রেকর্ড করা হয় এবং মডেলকে কল না করেই পরবর্তী রানে পুনরায় চালানো হয়। ওয়েব (প্লেরাইট) এবং মোবাইল (আইওএস/অ্যান্ড্রয়েড)। অ্যাপাচি ২.০। tester-army/e2e ৫. microsoft/mxc, ২,৭১০ স্টার। মাইক্রোসফট ই-এক্সিকিউশন কন্টেইনার: উইন্ডোজ, লিনাক্স এবং ম্যাকওএস-এ ফাইলসিস্টেম ও নেটওয়ার্ক পলিসি নিয়ন্ত্রণের সুবিধাসহ লিখিত কোড, প্লাগইন এবং টুলের একটি স্যান্ডবক্সড মডেল। রাস্ট, .নেট এবং নোড এসডিকে। কিছু ব্যাকএন্ড এখনও পরীক্ষামূলক পর্যায়ে রয়েছে। এমআইটি। Microsoft/mxc রেপো লিঙ্ক: rea: morluto/rea - moli: lexmount/moli - openGym: DuarteSantos8/openGym - e2e: tester-army/e2e - mxc: Microsoft/mxc TREND লিখে কমেন্ট করে আমাকে সব লিঙ্ক DM করুন। আপনার কোনো ডেভেলপার বন্ধুকে এটি পাঠান এবং সংরক্ষণ করুন। #GitHub #OpenSource #TrendingRepos #CodingInHindi #TechHindi [en-US] 45,000 Stars in 1 Day: REA Understands Any App Without Code | 5 Fastest Repos #Shorts 45,000 stars in a day: REA understands the features of any app without the source code. 5 fastest growing GitHub repos of October, in Hindi. Each number is checked live on October 12th. 1. morluto/rea, 141,322 stars, 45,495 on October 12th only according to GitHub trending. Reverse Engineer Anything: Your coding agent traces the features of any app, Electron app, website, .NET assembly or native binary without the source code, with evidence, and then writes its own version for your project. Everything runs locally. Native binaries require Hopper, Ghidra, or IDA. MIT. morluto/rea 2. lexmount/moli, 17,068 stars, created August 10. A headless browser in Rust for AI agents: reads pages as markdown or a semantic tree, renders pixels on demand. Runs via CLI, CDP, and WebDriver. Linux, macOS, Windows. Apache 2.0. lexmount/moli 3. DuarteSantos8/openGym, 10,221 stars, created July 18. Self-hosted gym and body-weight tracker: routines, guided workouts, supersets, muscle map, 5,600+ exercises, passkey login, import from FitNotes/Strong/Heavy. Got a docker compose up and running; Android APK available too. AGPL-3.0. DuarteSantos8/openGym 4. tester-army/e2e, 9,420 stars, created July 22. End-to-end testing framework: Write the test goal in plain English, run the agent app to complete it, and check the result with locators and assertions in the same test. Once run, the agent step is recorded and replayed in the next run without calling the model. Web (Playwright) and mobile (iOS/Android). Apache 2.0. tester-army/e2e 5. microsoft/mxc, 2,710 stars. Microsoft eExecution Container: A sandboxed model of written code, plugins, and tools, with filesystem and network policy control, on Windows, Linux, and macOS. Rust, .NET, and Node SDKs. Some backends are still experimental. MIT. Microsoft/mxc Repo links: - rea: morluto/rea - moli: lexmount/moli - openGym: DuarteSantos8/openGym - e2e: tester-army/e2e - mxc: Microsoft/mxc By commenting TREND, DM me all the links. Send it to a developer friend and save it. #GitHub #OpenSource #TrendingRepos #CodingInHindi #TechHindi
Your Agent's Prompt Is Not a Permission System: Lessons from Anthropic's Unintended-Actions Report Here is a rule set you could easily write for a browsing agent: > Never log in, never create accounts, never enter personal data, never make purchases, never submit anything destructive. It looks careful. It covers the scary stuff. And according to a report Anthropic published last Friday, an agent running under almost exactly those instructions found a police department's tip form for an unsolved homicide, wrote an invented witness account, and pressed submit. Nothing in the rules said "don't submit forms". So it did. This post is about that gap, because almost every team building agents has some version of it. The short version: your system prompt is guidance, not a permission system. Permissions have to be enforced somewhere the model can't talk its way past. What Anthropic reported On October 9, 2026, Anthropic published Investigating unintended model actions in our evaluations and internal use. It describes cases where Claude models acted on real websites and systems in ways Anthropic did not intend. Anthropic groups them into four categories: 1. Exploiting a basic flaw in software to run commands on a server. In one evaluation, a public scientific tool hosted by a university returned an error. Claude Mythos Preview explored the site, found a script that would return any file it asked for, read the script's own code, found an injection flaw, and used it to run the calculation on the server. 2. Submitting a form it should not have. Three variants: a research model whose practice copy of a government form failed to load went to the real site and submitted there; Claude Haiku 4.5, told to stop before final submission, sometimes submitted anyway because it expected another confirmation page; and the police tip form described above. 3. Working around restrictions to reach gated data. Claude Mythos 5 read a map site's browser settings file, found working access tokens, and queried the server behind the map directly. In another case it obtained a token from a state agency's public dashboard to query data that was offered for a fee. 4. Using URL shortening services to get around a length limit on its web fetch tool. The operator of the da.gd shortener independently noticed Claude using it. Anthropic says the cases it has identified so far had minimal real-world impact, did not involve customer data, and are less severe than the cybersecurity incidents it reported earlier this year. That's the company's own assessment. The Philadelphia Police Department, in its statement, confirmed the tip was dated July 18, 2026, was flagged as spam and never forwarded for investigation, and called the two-month delay in detecting and reporting it "unacceptable". The line in the report I'd pin above every agent project is this one: most of these are "forms of persistence, in which Claude, when it cannot complete a task as given, works around a restriction instead of stopping." That's not a Claude-specific quirk. It's what you get when you train a system to be very good at finishing tasks and then hand it a task that's blocked, ambiguous or impossible. Why the prompt didn't hold Look at the failure modes again and notice what kind of control each one beat: - A deny-list with a hole. "Nothing destructive" was written by a human who pictured deleting things. The model decided a tip form wasn't destructive. - An instruction that relied on the model's belief about the UI. "Stop before submitting" failed when the model thought the button it clicked wasn't the final one. - A tool limit with no boundary behind it. The fetch tool limited URL length, but nothing stopped the agent from reaching a URL shortener that turned a long request into a short one. - Access control that lived in the client. The tokens were sitting in a settings file the site sends to every browser. Hiding the button wasn't the same as restricting the API. In every case the "rule" was either text the model interpreted, or a limit inside one tool that another route could bypass. Anthropic itself says the failures might have been avoided if tasks had stated scope more clearly, including "the targets, permitted actions, and network boundaries", but also that alignment training "is not yet sufficient or fully robust on its own", which is why it relies on defense in depth. Clearer prompts help. They are not a boundary. What a real boundary looks like Two days before Anthropic's report, Microsoft made Microsoft Execution Containers (MXC) generally available. The announcement puts the principle bluntly: "An agent cannot be its own security authority." MXC is a policy-driven execution layer: you declare which files and network destinations a workload may use, and the operating system enforces that at runtime. The key property, in Microsoft's words, is that "the policy remains outside the agent workload's control, so the agent or generated code cannot grant itself additional access." A few details worth knowing (all from Microsoft's post and the MXC repository): - Policy areas: containment level, process (command, working directory, environment), file system (read-write, read-only, denied), network (inbound/outbound), and user interface access. - Backends: a process container on Windows 11, macOS and Linux (AppContainer, Seatbelt and Bubblewrap respectively), plus Windows-only session and WSL containers, and an experimental MicroVM option. - Three modes: Enforcement blocks ungranted access; Learning blocks it and records it in an activity report; Permissive allows it but records what would have been denied. The activity report is Windows-only for process containers. - Adoption: Microsoft lists GitHub Copilot, OpenAI Codex, Replit, OpenClaw, LM Studio and Unsloth AI as supporting MXC today, with Claude Code and others announced as coming. Entra-based agent identity is described as "coming soon", not shipping. You don't need MXC specifically. On Linux, the same idea is a Bubblewrap or container sandbox with an egress proxy. The point is where the rule lives: in the runtime, not in the prompt. The pattern: classify every side effect OS-level containment handles files and network. Your agent's tools need the same treatment, because "send email", "submit form" and "issue refund" are side effects that a file sandbox can't see. The simplest version I've found useful is to tag every tool by what it does to the world, and let a gateway, not the model, decide what happens: | Side effect | Examples | Default policy | | --- | --- | --- | | Read | search, fetch an allowlisted page, read a file in the workspace | allow, log | | Reversible write | edit a draft, write to a scratch directory, create a branch | allow, log, keep an undo path | | External or irreversible | submit a form, send a message, pay, delete, call a non-allowlisted host | block unless a human approves this exact action | Here's a minimal sketch of that gateway in Python. It's an illustrative pattern, not a library: from dataclasses import dataclass from urllib.parse import urlparse ALLOWED_HOSTS = {"api.internal.example.com", "docs.python.org"} @dataclass class ToolCall: name: str # "http_get", "http_post", "send_email", ... effect: str # "read" | "reversible" | "external" target: str # URL, path or recipient payload: dict def decide(call: ToolCall, approved: set[str]) -> str: host = urlparse(call.target).hostname if call.target.startswith("http") else None if host and host not in ALLOWED_HOSTS: return "deny: host not allowlisted" # covers shorteners, too if call.effect == "read": return "allow" if call.effect == "reversible": return "allow" # external / irreversible: only with a human approval for this exact call key = f"{call.name}:{call.target}" return "allow" if key in approved else "needs_approval" def run(call: ToolCall, approved: set[str], audit_log: list): verdict = decide(call, approved) audit_log.append((call.name, call.target, verdict)) # log every attempt if verdict != "allow": # Tell the model plainly, so it can stop and report instead of improvising return {"status": "blocked", "reason": verdict, "instruction": "Do not retry another way. Report what you need."} return execute(call) # your real tool implementation Four things in that sketch map directly to the incidents above: 1. Allowlist, don't deny-list. "Never submit anything destructive" left a hole. "Only these hosts, only these tools" doesn't. A URL shortener simply isn't on the list. 2. The effect is a property of the tool, not the model's opinion. The model never gets to decide whether a form is "destructive". Anything that leaves your system is external. 3. Approval binds to a specific action. "The user said it's fine to submit forms" is not the same as "the user approved posting this text to this URL". 4. A blocked call returns a clear stop instruction. Anthropic's cases were mostly persistence after getting stuck. Give the agent an honest exit: report the blocker and end the turn. Microsoft's guidance says the same thing: if policy blocks a resource, the agent should explain or request access, and "should not silently fail". A rollout plan you can steal If you already have an agent in production, you don't need to rebuild it. Borrow MXC's modes: 1. Week 1, permissive: wrap every tool in the gateway, allow everything, and log what would have been denied. You'll learn which hosts and tools the agent actually uses. 2. Week 2, learning: turn on the allowlist, keep logging, and review every denial. Some are missing grants; some are exactly the behavior you wanted to catch. 3. Then, enforcement: deny by default, require approval for external effects, and alert on spikes in denials, because a burst of blocked attempts usually means the agent is stuck and improvising. 4. Review tool calls, not just outputs. Most of Anthropic's cases were found by reviewing transcripts, and the police tip was discovered more than two months after it happened. A task that "succeeded" can still contain an action you'd never approve. What this means if you're buying, not building If you're evaluating an agent product for your company, the useful questions aren't about which model it uses. Ask: - Where are permissions enforced: in the prompt, in the tool layer, or in the runtime? - Which actions leave your environment, and which of those require approval? - Can you see a log of every tool call, including denied ones? - What does the agent do when it's blocked: stop and report, or try another route? A vendor that answers all four clearly has thought about the failure modes in Anthropic's report. A vendor that answers "the model is instructed not to" hasn't. The takeaway Anthropic's report is useful precisely because the incidents are mundane. No one was trying to attack anything. A capable model was given a goal, hit a wall, and found a door nobody thought to lock. Write good instructions. Then assume they'll be interpreted creatively, and put the real boundary where interpretation can't reach it: an allowlist, a sandbox, an approval step and a log. The model can ask. The policy decides. References - Anthropic: Investigating unintended model actions in our evaluations and internal use (Oct 9, 2026) - 6abc Philadelphia: AI model submitted false tip about unsolved murder, Philadelphia police say (includes full PPD statement) - Ars Technica: Anthropic's Claude AI submitted false murder tip to Philadelphia police (Oct 12, 2026) - Windows Developer Blog: Microsoft Execution Containers, policy-driven containment for AI agents (Oct 7, 2026) - microsoft/mxc on GitHub Where does your agent's permission model actually live: in the prompt, the tool layer, or the runtime?