本文へ移動
技術を、自社の仕事に。
判断と実行を助けるメディア

記事を検索

Microsoft MXCでAIのコードを隔離実行 Linuxで試した設定と制約

目次 · 6項目

生成AIに書かせた集計スクリプトや、社外から受け取ったプラグインを、業務アプリの中で動かしたい。ただ、アプリと同じ権限で実行すると、そのコードはサーバーのホームにある鍵、環境変数に入れたAPIキー、社内のネットワークにまで手が届きます。コードを毎回人が読んでから動かす運用は、件数が増えると続きません。

この「信頼できないコードを、範囲を決めて動かす」ための部品として、MicrosoftがMXC(Microsoft eXecution Containers)を公開しています。2026年10月7日のWindows開発者ブログで「now generally available」(一般提供を開始)と発表され、Windows 11・macOS・Linuxで使える軽い隔離の方式(process container)は、LinuxではBubblewrapを使うと説明されています。READMEは、モデルの出力・プラグイン・ツールのような信頼できないコードをWindows・Linux・macOSで動かす「sandboxed code execution system」と説明しています。アプリにSDKとして組み込み、隔離の方式(バックエンド)、ファイルとネットワークの規則、実行するコマンドを渡すと、MXCが要求を検証してから隔離した環境で起動する仕組みです。

Node版のSDK(@microsoft/mxc-sdk)は、npmで1.0.0が2026年10月6日(UTC)、1.0.1が10月17日に公開されています。GitHubのリリースでは、1.0.0がRust・.NET・Node.jsのSDKの「first stable release」(最初の安定版)とされています。ライセンスはMIT、Node.js 24以上が必要です。要求の形式を定めるスキーマも、リポジトリの文書で1.0.0が「current stable」(現在の安定版)とされています。本記事では、公開されている文書を確認したうえで、編集部の検証環境のLinuxで1.0.1を入れ、Bubblewrap(Linuxの既定のバックエンド)で実際にコードを動かしました。

OSごとに使える隔離の方式

MXCは、OSごとに別の仕組みで隔離します。READMEの表を整理すると次のとおりです。

OS既定のバックエンドほかに選べるもの
Windows 11(x64・ARM64)processcontainerwindows_sandbox(実験的)、wslc、microvm(実験的)、hyperlight(実験的)、isolation_session
Linux(x64・ARM64)bubblewraplxc、microvm、hyperlight
macOS(ARM64・x64)seatbeltなし

READMEで「experimental」(実験的)とされているのは、Windowsの行に印が付いた windows_sandbox・microvm・hyperlight です。SDK 1.0.1の型定義でも、この3つが実験的なバックエンドとして列挙されています。また、Node版の型で containment に指定できるのは process・processcontainer・wslc・lxc・seatbelt・isolation_session・bubblewrap の7つで、microvm・hyperlight・windows_sandbox は含まれていません。業務で使う前提なら、まずは各OSの既定のバックエンドから検討するのが無難です。

Windowsでプロセスの隔離(processcontainer)を使うには、OSの更新も必要です。対応表では、Windows 11 24H2はビルド26100.9278以降、25H2は26200.9278以降とされています。

規則として指定できるのは、ファイル(読み取り専用・読み書き可・見せないパスの一覧)、ネットワーク(外向きと内向きの許可・拒否、プロキシ)、UI(クリップボード、画面、入力の注入)です。ただし、文書は「Native validation decides which policies the backend can enforce」としており、どの規則を守らせられるかはバックエンドごとに決まります。

Linuxで実際に動かしたコード

検証環境は、Ubuntu 24.04、Node.js 24.22.0、@microsoft/mxc-sdk 1.0.1、bubblewrap 0.9.0(aptで導入)です。getPlatformSupport() は isSupported: true、使える方式は bubblewrap を返しました。

生成AIが書いた generated.py を、入力フォルダーは読み取りだけ、出力フォルダーには書き込み可、ネットワークは遮断、30秒で打ち切る、という条件で動かすコードです(パスは検証用の例です)。

import { getPlatformSupport, run, spawn, type ContainerRequest } from '@microsoft/mxc-sdk/v1';

const support = getPlatformSupport();
if (!support.isSupported) throw new Error(support.reason);

const request: ContainerRequest = {
  command: '/usr/bin/python3 generated.py',
  workingDirectory: '/srv/job/in',
  filesystem: {
    readonlyPaths: ['/srv/job/in'],
    readwritePaths: ['/srv/job/out'],
  },
  network: {
    egress: { default: 'deny' },
    ingress: { default: 'deny', hostLoopback: 'deny' },
  },
  timeoutMs: 30_000,
};

// 終了まで待って、出力をまとめて受け取る
const result = await run(request);
console.log(result.exitCode, result.timedOut, result.warnings);

// 実行中の出力を順に受け取る
const child = await spawn(request);
try {
  child.standardOutput?.on('data', (chunk) => process.stdout.write(chunk));
  child.standardError?.on('data', (chunk) => process.stderr.write(chunk));
  console.log(await child.wait());
} finally {
  child.dispose();
}

このコードは tsc(strict)の型チェックを通り、実行すると generated.py は出力フォルダーに書き込めて、入力フォルダーへの書き込みは「Read-only file system」、1.1.1.1への接続は失敗しました。run と spawn はどちらも終了コード0、打ち切りなし、警告なしでした。

ほかの条件も試した結果をまとめたのが次の図です。

LinuxのBubblewrapでMXCを動かした結果の図。ホームに置いたファイルは見えない、ホスト側の環境変数のAPIキーは渡らない、読み取り専用のフォルダーには書けない、許可したフォルダーには書ける、ネットワーク遮断では1.1.1.1にも8.8.8.8にもつながらない、1.1.1.1/32のTCP 443だけ許可すると1.1.1.1だけつながる、2秒で打ち切るとtimedOutがtrue

見るべき点は2つです。1つ目は、何も指定しないものは見えないことです。Bubblewrapの文書のとおり、/usr/bin や /etc などの決まったシステムのパス以外は、readonlyPaths・readwritePaths に書かない限りサンドボックスから見えません。ホームに置いたファイルは「No such file or directory」になり、ホスト側で設定した FAKE_API_KEY という環境変数も中には渡りませんでした(中の環境変数は PATH・PWD・TERM だけ)。2つ目は、network を書かなくても外に出られないことです。network を省いた場合も、egress.default: 'deny' と同じく接続できませんでした。

通信先を絞るときに必要になるもの

「遮断」ではなく「特定の宛先だけ許可」や「外向きは許可」にすると、必要な道具が増えます。bubblewrapだけを入れた状態で egress.default: 'allow' を試すと、次のエラーで起動前に止まりました。

Bubblewrap: network.egress requires 'slirp4netns' on PATH: No such file or directory (os error 2). Install slirp4netns or use ruleless network.egress.default='deny'.

文書によると、規則のない遮断は名前空間を分けるだけで済みますが、宛先を絞る場合は slirp4netns・iptables・ip・nsenter・unshare と、カーネルの nf_conntrack が必要です。slirp4netnsとiproute2を入れたうえで、egress.allow に1.1.1.1/32のTCP 443だけを書いて試すと、1.1.1.1にはつながり、8.8.8.8は時間切れになりました。このとき、IPv6の規則を入れなかったという警告が warnings に返りました(この環境のカーネルがIPv6に対応していないため)。

設定の段階で断られるものもあります。手元で確かめたものと、文書で断られると書かれているものです。

設定結果理由(文書・エラーの要旨)
ingress.default: 'allow'起動前にエラー外からサンドボックスへ入る経路を作れないため
cidr にホスト名(example.com)起動前にエラー規則はIPアドレスかCIDRだけ。名前で絞るなら外部のプロキシを使う
プロキシと egress.allow の併用断られる(文書)プロキシを使う場合は、外向きを遮断して規則を書かない形に限られる

ホスト名で通信先を絞りたい場合、MXCは名前の一覧を持ちません。文書は runtimeConfig.networkProxy で手元のプロキシを指定し、名前による許可・拒否はそのプロキシ側で設定する形を示しています(本記事ではプロキシ経由の通信は試していません)。

組み込む前に確認しておきたい制約

文書と検証から、業務アプリに組み込む前に確かめておきたい点を挙げます。

  1. 作業フォルダーがHOMEになる。 workingDirectory を指定すると、そのフォルダーが HOME になりました(検証でも同じ)。文書は、そこにある .gitconfig・.npmrc などが利用者の設定として読まれると注意しています。信頼できない入力を置くフォルダーなら、environment で HOME を別の場所に指定します
  2. 環境変数を1つ渡すと既定の値が付かない。 environment を指定し、inheritDefaultEnvironment を true にしないと、既定の PATH・TERM は渡されません。検証で environment: { FOO: 'bar' } だけを渡すと、中の env に並んだのは FOO と PWD だけでした(echo $PATH はシェルが自前で補った値を表示するため、見た目では気づきにくい点に注意します)
  3. Bubblewrapは使い捨ての実行だけ。 コンテナを作って何度も使う操作(provisionなど)には対応していません。Node版SDK 1.0.1の型で、この操作に指定できるのは isolation_session と wslc(どちらもWindows)だけです
  4. 判定結果はプロセスの間、使い回される。 Node版の getPlatformSupport() は、失敗も含めて結果をモジュールが読み込まれている間保持します。bwrapなどを後から入れたら、Nodeのプロセスを再起動します
  5. 拒否されたアクセスの記録はWindowsのみ。 どのファイルが拒否されたかを記録する仕組み(learning mode)はWindowsのAppContainer系だけが対象です。Linuxでは、拒否されたかどうかを実行の出力から読み取ることになります
  6. 送信される診断データ。 Microsoftの公式ビルドは、利用者の同意など複数の条件がそろった場合に診断データを送れます。READMEによると、Windows以外では何もしない作りです

なお、検証はroot(uid 0)で実行しました。サンドボックスの中の id -u も0でした。実際のサービスでは一般ユーザーで動かすことになるため、その条件での動作は確かめていません。

隔離の線をどこに引くかの考え方はAIの実行環境の線を引く記事、外向き通信の許可リストの点検はAIサンドボックスの外向き通信の記事で整理しています。

まず手元で試すなら

  1. 既定の遮断で1本動かす: 対象のOSでSDKを入れ、getPlatformSupport() が返す使える方式を確かめたうえで、ネットワーク遮断・読み取り専用の入力フォルダー・書き込み可の出力フォルダーだけを指定して、実際に動かしたいスクリプトを実行します。足りないパスや通信が、エラーとして見えてきます
  2. 断られる設定を先に洗い出す: 宛先の許可、ホスト名での制限、外からの接続など、業務で必要な通信の条件を書き出し、使うバックエンドで受け付けられるかを run の前に確認します。断られる条件があれば、プロキシを置くか、別のバックエンドにするかを決めます

2026年10月20日に、Windows開発者ブログのMXCの発表(2026年10月7日)、microsoft/mxc のGitHubのリリース(v1.0.0・v1.0.1)・README、docs/glossary.md、docs/api-reference(README と Node V1)、docs/container-lifecycle.md、docs/schema.md、docs/containment-policy/README.md、docs/backends/bwrap/bubblewrap-backend.md、docs/backends/process-container/os-version-support.md、docs/logging-access-denied.md、docs/telemetry.md、sdk/node の README・CHANGELOG、schemas/stable/mxc-config.schema.1.0.0.json と、npm の @microsoft/mxc-sdk の公開日時・1.0.1 の型定義を確認しました(資料調査)。編集部の検証環境(Ubuntu 24.04、Node.js 24.22.0、bubblewrap 0.9.0、slirp4netns 1.2.1、root で実行)で @microsoft/mxc-sdk 1.0.1 を使い、本文のコードと図の各条件を実行しました(実機検証)。Windows・macOSのバックエンド、lxc、プロキシ経由の通信、一般ユーザーでの実行、.NET・Rust版のSDKは確認していません。

AIが生成したコードやプラグインを業務システムで安全に動かす仕組みづくりは、グリームハブの開発・AI・自動化のご相談で承っています。扱うデータや通信先によって構成が変わるため、お問い合わせからご相談ください。

参考資料

この記事を共有XFacebook
鈴木 翔

技術の可能性に魅了され、学生時代からプログラミングとデジタルアートの分野に深い関心を持つ

この記事のテーマを、自社の次の一歩へ

自社での進め方を、具体的に。

つくりたい仕組み、既存システム、運用の条件を整理し、実現に向けた次の一歩を考えます。

  • 実現したい仕組み
  • 既存環境との接続
  • 運用の条件
開発・運用の構想を相談する

構想段階からご相談いただけます。この記事の情報を相談フォームに引き継ぎます。

最新記事をメールで受け取る