summaryrefslogtreecommitdiff
path: root/doc/Design.md
diff options
context:
space:
mode:
Diffstat (limited to 'doc/Design.md')
-rw-r--r--doc/Design.md34
1 files changed, 24 insertions, 10 deletions
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として扱わない。
---