summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/AuditReport.md4
-rw-r--r--doc/Design.md34
-rw-r--r--doc/Specifications.md21
3 files changed, 46 insertions, 13 deletions
diff --git a/doc/AuditReport.md b/doc/AuditReport.md
index 3cbed19..2155236 100644
--- a/doc/AuditReport.md
+++ b/doc/AuditReport.md
@@ -1,5 +1,9 @@
# v1再監査報告とSandbox Usability Revision状況
+> 2026-08-13オンデマンド昇格改定: 以下の管理者環境証跡は常時管理者方式の過去commitに対する履歴である。`asInvoker` main、Task単位helper、Named Pipe、dynamic WFP、persistent loopback Recoveryは最新commitで再検証するまでPASS根拠としない。
+
+2026-08-13 working treeでmainを`asInvoker`、昇格hostを`requireAdministrator/uiAccess=false`とし、WFP/loopback mutationを固定`admin/` hostへ分離した。通常tokenのHTTP/stdio MCPから実Taskを実行し、初回`process_run`時のUAC、logon SID DACL Named Pipe、LPAC Process Tree、dynamic WFP、ACL/WFP cleanupを確認した。Windows suiteは昇格子Processだけで79件PASS、Core 105件、Planner 10件、administrative boundary 4件がfail/skip 0。実UAC拒否、hostile peer実Process matrix、実helper crashからのstartup Recoveryは未再検証のため、TraceabilityではPARTIALを維持する。
+
> 2026-08-13 schema version 2追補: YAMLを唯一のSandbox desired stateとし、個別のExecutable Approval/Sandbox Resolution操作を廃止した。CLIはcommand省略のServer起動、`apply`、`show`に限定し、確認結果はconfig別Applied Configuration Storeへ一括保存する。本追補より前の管理者・publish証跡は旧schemaの履歴であり、schema version 2のPASS根拠ではない。最終検証はRelease build warning/error 0、Core 104件、Planner 10件、Windows Security/Recovery 56件、README operational 19件がfail/skip 0。publish HTTP MCPも`deepseek-v4-flash:cloud`でcompleted 3/3となり、cmd→cmd/curl/venv Python、Network none、終了後残留0を確認した。
## 基準
diff --git a/doc/Design.md b/doc/Design.md
index 80b5acc..5a8d0f0 100644
--- a/doc/Design.md
+++ b/doc/Design.md
@@ -93,8 +93,9 @@ Agent Runtime ─── Session Store (memory)
├── Less Privileged AppContainer (LPAC)
├── NTFS ACL
├── Job Object
- ├── WFP
- └── Named Pipe
+ └── Named Pipe ── Task単位runas Process
+ ├── WFP dynamic session
+ └── loopback exemption
│
▼
Sandbox Process Tree
@@ -121,6 +122,7 @@ src/
Agent.Core/ # Agent loop, session, prompt, ollama abstractions
Agent.Planner/ # TaskGraph, TokenPERT, TokenCPM
Agent.Windows/ # SandboxPolicy enforcement and Win32 interop
+ Agent.Admin/ # Sandbox Brokerの固定network処理を行う通常clientと昇格host
tests/
Agent.Core.Tests/
Agent.Planner.Tests/
@@ -140,6 +142,7 @@ state/
```text
Agent.App -> Agent.Mcp -> Agent.Core -> Agent.Planner
Agent.App -------------------------> Agent.Windows
+Agent.App / Agent.Windows ---------> Agent.Admin.Client
Agent.Core -> ISandbox/IToolExecutor interfaces
Agent.Windows implements those interfaces
```
@@ -234,7 +237,7 @@ result: <final natural-language answer; completed only>
### 5.8 起動preflightとHTTP request log
-- Appはtransport構築前に`WindowsPlatformCheck`を実行する。administrator/BFE/WFP probeが1つでも失敗した場合はhostをbuild/startせずfatalとする。
+- Appはtransport構築前に`WindowsPlatformCheck`を実行し、OS、Application Profile、BFE read-only open、固定Bundle pathの昇格用Executableとversionを検査する。Administrator判定、WFP transaction、filter add/delete probeは行わない。
- `StartAsync`完了後にだけ`IMcpHostObserver.Ready`を通知するため、「起動中」と「接続可能」を区別できる。
- HTTP middlewareはsocket endpointとrouting metadataだけをbounded in-memory queueへ`TryWrite`し、専用background writerがstderr、application log、`logs/http.jsonl`へ出力する。request threadはconsole/file I/Oを待たず、queue飽和時はrequestを止めずlog entryをdropして件数を警告する。
- forwarded header、credential header、query、payloadは保存しない。
@@ -539,7 +542,7 @@ network:
- reparse chainを最終targetまで解決しcycle、missing target、非local filesystemを拒否する。
- `agent-mcp apply [config] [--yes]`だけがApplied Configuration Storeを更新する。全解決・validation完了前、または確認前にStoreを変更しない。
- `agent-mcp [config]`は現在のYAMLを再解決・再hashし、Applied Configuration snapshotとの完全一致とWindows preflightを検証してからMCP受付を開始する。個別の`serve`と`check`commandは持たない。
-- `agent-mcp show [config]`はdesired/resolved/appliedの権限matrixをtext表示し、StoreやACL/WFPを変更しない。管理者権限、BFE、WFP add/deleteを伴う完全なWindows preflightはServer起動時だけ実行する。
+- `agent-mcp show [config]`はdesired/resolved/appliedの権限matrixをtext表示し、StoreやACL/WFPを変更せずUACを発生させない。`apply`は通常ユーザー権限で固定Application Profileを作成または確認してApplied Configurationを保存する。Server起動時は固定SIDの導出、BFE open、helper整合性のread-only preflightだけを行う。
- languageとtransportはYAMLだけから取得し、CLI overrideを持たない。
### 10.7 Effective Sandbox Policy
@@ -607,9 +610,13 @@ WFP実装は複雑な汎用Firewallにしない。設計上の変換規則だけ
5. DNS解決失敗はdeny。
6. Task終了でTask固有WFP filterを削除する。
7. LoopbackもEffective Network Policyに明示されない限り許可しない。LANをlocalへ含めない。
-具体的なWFP layer、sublayer、filter condition、transaction APIは実装時にCodexがWindows SDKを確認して決定し、Security Integration Testで仕様を検証する。
+WFP mutationはTask内の初回`process_run`直前に`runas`で起動する昇格Processが行う。Task間でProcessを再利用せず、dynamic sessionをTask終了まで保持する。session終了時にBFEがdynamic objectを削除するため、filter IDをRecovery Journalへ保存しない。
+
+`local`はLPAC network capability、`NetworkIsolationSetAppContainerConfig`によるAppContainer loopback送信許可、WFPによる`127.0.0.1`/`::1`の列挙port制限を組み合わせる。同APIは既存SID集合をGetして保持し、Application Profile SIDの追加前状態をRecovery Journalへ記録・復元する。Microsoft資料の`debugging purposes`という用途制約を既知制約とし、同API自体はSecurity Boundaryとしない。WFP permit単独、MSIX、独自proxyへfallbackしない。
### 11.6 Named Pipe
-Sandbox workerとのIPCが必要な場合はtask固有Named Pipeを使用し、DACLをApplication SIDとBrokerだけに限定する。TCP localhostを内部IPCに使わない。
+通常側がTask固有Named Pipe serverを明示DACL付きで作成し、昇格Processだけがclient接続する。DACLはlogon SIDとAdministratorsへ必要最小権限を与え、NETWORKをdenyし、default DACLを使用しない。通常側は`ShellExecuteEx/runas`相当で得たProcess IDと`GetNamedPipeClientProcessId`を照合し、昇格側もparent PIDと`GetNamedPipeServerProcessId`を照合する。
+
+protocolはversion、Task ID、固定Application SID、Network Access Mode、解決済みIP/port、loopback復元状態を持つ長さ上限付きmessageに限定する。任意Executable、command、path、Security Descriptor、Registry、WFP layer/sublayer/action、Configuration/Policyを表現できるfieldを持たない。TCP localhost、独自RPC、汎用Network proxyへ拡張しない。
---
## 12. ACL / Resource Transaction設計
### 12.1 ACIDから借用する性質
@@ -623,7 +630,7 @@ Sandbox workerとのIPCが必要な場合はtask固有Named Pipeを使用し、D
```text
CLEAN
-> PREPARING journal create
- -> APPLIED ACL/WFP/Job ready
+ -> APPLIED 初回process_run直前にACL/WFP/Job ready
-> RUNNING sandbox process start
-> CLEANING process stopped / task terminal
-> CLEAN all task resources removed
@@ -638,12 +645,13 @@ JournalはTaskごとのJSONとし、操作を実行する**前**にundoに必要
"task_id": "...",
"state": "APPLIED",
"acl_changes": [{"path":"...","change_id":"..."}],
- "wfp_filter_ids": [123],
+ "network_loopback_before": false,
"temp_paths": ["..."],
"created_at": "..."
}
```
起動時にjournalが存在する場合、MCP transport開始前にRecovery Managerが逆順でcleanupし、全項目の不存在/復元を検査してからjournalを削除する。
+ACL/file/tempだけなら通常権限で復旧する。persistentなloopback entryがあれば起動時だけ昇格Processを起動して復旧し、UAC拒否時はMCP受付前にfatal終了する。WFP dynamic entryの旧Journalはupgrade互換のno-opとしてclean化する。
---
## 13. File Transaction設計
### 13.1 基本フロー
@@ -699,7 +707,7 @@ Auditはappend-only JSONLを採用する。1 event = 1 line。
{"ts":"...","event":"file.write","task_id":"...","path":"...","before_sha256":"...","after_sha256":"..."}
{"ts":"...","event":"policy.deny","task_id":"...","kind":"network","target":"example.com:443","reason":"not_allowlisted"}
```
-最低event集合: `task.start`, `task.end`, `tool.call`, `process.start`, `process.exit`, `file.write`, `file.delete`, `policy.deny`, `network.rule.apply`, `network.rule.remove`, `recovery.start`, `recovery.end`。各eventは可能な限りsession ID、task ID、内部error codeを持つ。
+最低event集合: `task.start`, `task.end`, `tool.call`, `process.start`, `process.exit`, `file.write`, `file.delete`, `policy.deny`, `network.rule.apply`, `network.rule.remove`, `recovery.start`, `recovery.end`, `sandbox.elevation.request`, `sandbox.elevation.success`, `sandbox.elevation.deny`, `sandbox.ipc.reject`。各eventは可能な限りsession ID、task ID、内部error codeを持つ。pipe名、IPC payload全文、UAC credentialは記録しない。
---
## 16. Recovery・終了設計
### 16.1 graceful stop
@@ -790,6 +798,11 @@ closed Sessionは再利用しない。プロセス再起動後に以前のSessio
| ST-25 | Entry (`PowerShell`/Python/.NET/`cmd`) × Descendant (`cmd`/PowerShell/Python/.NET/System32 utility) | 個別Approvalなしで起動し、Descendantが同じLPAC SID/Jobに残る。cmd内からはPATH解決名またはWorkspace相対pathを使用する |
| ST-26 | protected DACL root/descendantと通常DACL rootのread/write/execute | protected bitを解除せず、許可ケースだけ成功。適用不能ケースは拒否し、cleanup後Security Descriptorが完全一致 |
| ST-27 | baseline/Network capabilityの追加前後 | 必要な正方向ケースに加えFilesystem、Registry write、COM、Policy外Network、Job breakawayの負方向集合をすべて検証 |
+| ST-28 | 通常tokenでのstdio/HTTP、show/apply、file-only Task | ServerとTaskが成功しUACが発生しない |
+| ST-29 | Taskごとの初回/後続process_runとUAC拒否 | 初回だけ昇格し、同一Task内でhelperを再利用する。拒否は当該Taskだけfailed |
+| ST-30 | helper crash、main crash、startup Recovery | WFP残留0、loopbackを元状態へ復元、Recovery UAC拒否はbind前fatal |
+| ST-31 | Named Pipeのremote/別PID/別session/version/size/reconnect/double-apply | すべて拒否し、固定network操作以外をschemaで表現不能 |
+| ST-32 | main/helper manifest、bundle path/version、native call graph | asInvoker/requireAdministrator、固定admin配置、WFP/loopback mutationがhelper側だけに存在 |
---
## 20. エラー分類
| Category | 例 | Task結果 | Retry |
@@ -818,8 +831,9 @@ errorは内部codeとlocalized messageを分離し、ログ/auditにはcode、MC
| 10 | Release/Operational E2E | self-contained Bundle単独起動、stdio/HTTP実利用 |
### 21.1 Release設計
-- `dotnet publish -c Release -r win-x64 --self-contained true` のfolder publishを配布元とする。
+- mainと昇格hostを同じversion/RIDで`dotnet publish -c Release -r win-x64 --self-contained true`し、mainをBundle root、昇格hostを固定`admin/` subdirectoryへ配置する。
- Bundleはversion付きZIP、展開済みdirectory、file manifest、SHA-256 checksumから成る。
+- main manifestは`asInvoker`、`admin/agent-mcp-admin.exe` manifestは`requireAdministrator`かつ`uiAccess=false`とする。mainは`AppContext.BaseDirectory/admin/agent-mcp-admin.exe`だけを参照し、PATH検索やConfigurationによる差替えを許さない。
- 起動時の相対pathは実行ファイルdirectoryを基準に解決し、ソースツリーを参照しない。
- 現行Operational E2Eは配布既定の`deepseek-v4-flash:cloud`を使用する。rate limit、接続失敗、model unavailableをapplication PASSとして扱わない。
---
diff --git a/doc/Specifications.md b/doc/Specifications.md
index fb1de12..dcc2425 100644
--- a/doc/Specifications.md
+++ b/doc/Specifications.md
@@ -188,7 +188,7 @@ command省略時はYAMLの`mcp.transport`と`application.language`を使用しã�
`apply`はbase/local merge後のYAML全体、Workspace、Mount、Execution Entry、Network、Resourceを解決し、ExecutableのResolved PathとSHA-256を含む権限差分を一度だけ表示する。全検証成功後、利用者が承認した場合だけconfig別Applied Configuration Storeをatomic replaceする。途中失敗時は以前の適用状態を維持する。`--yes`は非対話適用だけに使用でき、Auditへ記録する。
-`show`はread-onlyとし、desired/resolved/applied/effectiveの状態とFilesystem/Execution/Network/Resource権限マトリックスを一つのtext表示で返す。WFP filter追加削除を伴う完全なPlatform preflightは起動時に必ず実施する。MCP ClientおよびLLMから`apply`を呼び出せない。
+`show`はread-onlyとし、desired/resolved/applied/effectiveの状態とFilesystem/Execution/Network/Resource権限マトリックスを一つのtext表示で返す。`show`と`apply`はUACを発生させない。MCP ClientおよびLLMから`apply`を呼び出せない。
旧`serve`、`check`、`executable *`、`sandbox *`、`--config`、`--lang`、`--transport`、`--path`、`--runtime-root`、`--no-runtime`、`--format`は受け付けず、schema version 2の移行診断を返す。
@@ -206,7 +206,8 @@ command省略時はYAMLの`mcp.transport`と`application.language`を使用しã�
### 5.8 起動・HTTP観測性
-- command省略のServer起動はbind前に管理者権限、BFE、WFP transaction、filter add/deleteを検査し、不足時は具体的なerrorと対処をstderrへ出してexit code 2で終了しなければならない。
+- `agent-mcp.exe`は`asInvoker`で通常ユーザー権限のまま起動し、MCP Clientに管理者権限を要求しない。
+- command省略のServer起動はbind前にOS、Configuration、Applied Configuration、Effective Sandbox Policy、Application Profile、BFE、昇格用Executableの存在・互換version、Recovery Journalをread-only検査する。WFPを書き換えるprobeを起動時に行わない。
- ready messageは実際のtransport開始後だけ出力し、HTTPではendpoint/protocol/stateless/PID/log path、stdioではprotocol/PID/log pathを含める。
- HTTP request logは実socketのremote/local endpoint、method、path、status、duration、標準MCP routing headerを記録可能とする。
- `Authorization`、`Cookie`、query、body、prompt、画像、Base64をrequest logへ記録してはならず、`X-Forwarded-For`を接続元として信用してはならない。
@@ -444,6 +445,9 @@ Resource Profileは`constrained = 1024 MiB/4 Process/300秒`、`normal = 4096 Mi
- Resolved `%SystemRoot%/System32`をOS Runtime RootとしてSandbox Process Treeへread/execute公開する。Brokerからの直接Entry起動は別途Executable Approvalを要求する。
- Task終了時にApplication Profileを削除しない。
- Task固有ACL、WFP filter、Job Object、一時ファイル等はTask Resourceとして管理する。
+- LPAC Process Treeに必要なTask ResourceはTask内の初回`process_run`直前に適用する。Processを使用しないTaskはUACを発生させない。
+- WFP書込と現在昇格して行うsystem-wide loopback設定だけをTask単位で昇格し、ACL、LPAC Process生成、Job Object、Executable Approvalは通常権限で処理する。
+- Task時のUAC拒否または昇格用Executable起動失敗では当該Taskだけをfailedとし、部分適用ResourceをrollbackしてServerを継続する。
- Task Resourceは正常終了・失敗・cancelのいずれでも残留させない。
- crashで残留可能性がある変更はRecovery Journalにより次回起動時に回収する。
- MCP受付開始前にRecoveryを完了し、clean stateを確認しなければならない。
@@ -490,7 +494,7 @@ Resource Profileは`constrained = 1024 MiB/4 Process/300秒`、`normal = 4096 Mi
| --- | --- |
| Application Log | stderrに出力可能。stdio時stdoutへログを出してはならない。ファイルにも保存する。 |
| LLM Log | promptとresponseを記録する。call、Session、Task、Planner Task、phase、iteration、replan、model、token usageを相関できなければならない。secretを継承しない前提でも、ログ出力先は保護する。 |
-| Audit Log | 通常ログと分離する。Task lifecycle、Internal Tool Call、Sandbox Process、秘密情報を除いたargument metadata、exit code、file write、delete、denied access、network rule、recoveryをSession/Taskと相関して記録する。argument本文、画像、Base64、credentialは記録しない。 |
+| Audit Log | 通常ログと分離する。Task lifecycle、Internal Tool Call、Sandbox Process、秘密情報を除いたargument metadata、exit code、file write、delete、denied access、network rule、昇格要求・結果、IPC拒否、recoveryをSession/Taskと相関して記録する。argument本文、画像、Base64、credential、pipe認証情報、IPC payload全文は記録しない。 |
| Token Metrics | Task/Call単位のinput/output/total tokenを記録する。 |
---
@@ -506,6 +510,8 @@ Resource Profileは`constrained = 1024 MiB/4 Process/300秒`、`normal = 4096 Mi
| REC-05 | Streamable HTTP server停止/明示cancel | 対象Taskを安全停止する。stateless HTTPのrequest完了やsocket切断はAgent Session終了とみなさない。 |
| REC-06 | crash後起動 | Recovery Journalに基づき残留Task Resourceをcleanにしてからserveする。 |
| REC-07 | cleanup失敗 | serveを開始せずfatal errorとする。 |
+| REC-08 | Task時UAC拒否 | 当該Taskをfailedとし、rollback後もMCP Serverを継続する。 |
+| REC-09 | 起動時RecoveryのUAC拒否 | Recovery未完了としてMCP受付前にfatal終了する。 |
---
@@ -526,6 +532,10 @@ Resource Profileは`constrained = 1024 MiB/4 Process/300秒`、`normal = 4096 Mi
| SEC-INV-11 | Recovery未完了状態でMCP受付を開始しない。 |
| SEC-INV-12 | stdio stdoutにはMCP protocol以外を書かない。 |
| SEC-INV-13 | Sandbox Process TreeのどのProcessもEffective Sandbox Policy外のresourceまたはcapabilityを取得できない。 |
+| SEC-INV-14 | MCP Server本体は管理者tokenを必要とせず、LLM、MCP Client、Internal Toolは昇格用Executableへ直接要求できない。 |
+| SEC-INV-15 | 昇格側は任意Executable、command line、Filesystem path、Security Descriptor、Registry、User Sandbox Configuration、Effective Sandbox Policyを操作できない。 |
+| SEC-INV-16 | 昇格側のnetwork変更は固定Application Profileと確定済みEffective Network Policyから導出されるものに限定する。 |
+| SEC-INV-17 | 未許可ProcessはTask固有Named Pipeを利用できず、昇格Process異常終了後にWFP dynamic objectを残さない。 |
---
@@ -571,6 +581,11 @@ Resource Profileは`constrained = 1024 MiB/4 Process/300秒`、`normal = 4096 Mi
| AT-18 | ja/en切替がCLI、MCP応答、LLM回答へ反映される。 |
| AT-19 | 追加localeがコード変更なしでロードされる。 |
| AT-20 | 未知locale keyまたは壊れたJSONで起動/checkが失敗する。 |
+| AT-23 | `agent-mcp.exe`とstdio/HTTP MCP Clientを通常tokenで起動でき、`show`、`apply`、Processを使わないTaskではUACが発生しない。 |
+| AT-24 | 初回`process_run`直前だけTask専用の昇格用Executableが起動し、同一Taskでは再利用され、次Taskへは再利用されない。UAC拒否またはhelper失敗は当該Taskだけをfailedにする。 |
+| AT-25 | mainは`asInvoker`、昇格用Executableは`requireAdministrator`かつ`uiAccess=false`であり、Release Bundleの固定`admin/`配置以外を起動しない。 |
+| AT-26 | Named Pipeのremote接続、peer PID不一致、protocol/version不一致、過大message、再接続、二重network適用を拒否する。 |
+| AT-27 | helper異常終了後にdynamic WFP objectが残らず、persistent loopback変更はRecovery Journalから復元される。Recovery時UAC拒否はMCP受付前fatalとなる。 |
### 20.1 Operational E2E