diff options
Diffstat (limited to 'doc/Design.md')
| -rw-r--r-- | doc/Design.md | 249 |
1 files changed, 152 insertions, 97 deletions
diff --git a/doc/Design.md b/doc/Design.md index 9ad4ae3..8f76ca6 100644 --- a/doc/Design.md +++ b/doc/Design.md @@ -69,21 +69,35 @@ Agent Runtime ─── Session Store (memory) ├── Prompt Composer ── Skill Selector/Loader ├── Ollama Client ───── Ollama localhost ├── Token Planner ───── TaskGraph / PERT / CPM - └── Internal Tool Dispatcher - │ - ▼ - Policy Engine + └── Internal Tool Dispatcher + │ + ▼ + User Sandbox Configuration + │ + ▼ + Sandbox Environment Resolution + ├── Workspace / Mount / Reparse Resolution + ├── Executable Alias / Runtime Resolution + ├── Executable Approval Resolution + ├── Network Resolution + └── Resource Resolution + │ + ▼ + Effective Sandbox Policy + │ + ▼ + Policy Engine │ ▼ Sandbox Broker - ├── AppContainer + ├── Less Privileged AppContainer (LPAC) ├── NTFS ACL ├── Job Object ├── WFP └── Named Pipe │ ▼ - Sandboxed Process Tree + Sandbox Process Tree Audit Writer / Recovery Manager は各副作用境界を横断して記録・復旧する。 ``` ### 3.1 信頼境界 @@ -252,14 +266,14 @@ overrideはTask objectにcopyし、global configurationを変更しない。Sess - mime_type、Base64妥当性、設定上限size/countを事前検査する。 - 既定上限は4画像、1画像10 MiB、request合計20 MiBとする。 - model capability確認でVision非対応と判定した場合はOllama呼出し前にlocalized error。能力確認不能時は呼出しを行い、Ollama errorを正規化して返す。 -### 6.5 Tool calling -Ollamaに公開する現行Internal Tool catalogは次のとおりとする。個々のOS command (`grep.exe`等) をtoolとして増殖させない。catalogの構成は設計事項であり、仕様上の固定数として扱わない。 -| Tool | 責務 | 主なoperation | +### 6.5 Internal Tool calling +Ollamaに公開する現行Internal Tool catalogは次のとおりとする。個々のOS Executable (`grep.exe`等) をInternal Toolとして増殖させない。catalogの構成は設計事項であり、仕様上の固定数として扱わない。 +| Internal Tool | 責務 | 主なoperation | | --- | --- | --- | | file_search | 検索 | glob / name / text / regex / tail相当 | | file_read | 読取 | whole / range / metadata | | file_edit | 編集 | overwrite / patch / atomic_replace / delete | -| process_run | 承認済Process実行 | exe + args + cwd + timeout | +| process_run | Entry Process実行 | Executable + args + cwd + timeout | | task_update | TaskGraph更新 | add / dependency / estimate | | dir | ディレクトリ操作 | mkdir / rmdir / list | --- @@ -278,7 +292,7 @@ Ollamaに公開する現行Internal Tool catalogは次のとおりとする。å€ ``` - wholeはsize上限を超えた場合range利用を要求する。 - whole readの既定上限は1 MiBとする。 -- read前にcanonical pathとreparse pointを検査する。 +- read前にLogical Pathをreparse resolutionし、確認済みResolved PathとEffective Filesystem Policyを検査する。 ### 7.3 file_edit ```json { @@ -290,10 +304,10 @@ Ollamaに公開する現行Internal Tool catalogは次のとおりとする。å€ "new_path":"string|null" } ``` -- overwrite/patch/atomic_replaceはwrite permissionを要求する。 -- `patch` operationの`patch` fieldは、JSON文字列化した`{"old_text":"...","new_text":"..."}`を受け取る。unified diffは受け付けない。`old_text`は対象file内で正確に1回だけ一致しなければならない。不正形式または一致数不正は再試行可能なTool failureとする。 -- deleteはdelete permissionを要求する。 -- renameはsource/destination双方にwrite permissionを要求する。destinationが既に存在する場合は拒否する(overwrite不可)。cross-volume renameは不支持でTool failureとして返す。 +- overwrite/patch/atomic_replaceはwrite Filesystem Capabilityを要求する。 +- `patch` operationの`patch` fieldは、JSON文字列化した`{"old_text":"...","new_text":"..."}`を受け取る。unified diffは受け付けない。`old_text`は対象file内で正確に1回だけ一致しなければならない。不正形式または一致数不正は再試行可能なInternal Tool failureとする。 +- deleteはdelete Filesystem Capabilityを要求する。 +- renameはsource/destination双方にwrite Filesystem Capabilityを要求する。destinationが既に存在する場合は拒否する(overwrite不可)。cross-volume renameは不支持でInternal Tool failureとして返す。 - rename transaction: PREPARE(source/destination検査+journal) → APPLY(File.Move) → VERIFY(source不存在/destination存在/hash一致) → COMMIT。crash recoveryはdestination hashがjournal記録と一致する場合のみdestinationからsourceへ戻す。 - `expected_sha256` 指定時はoptimistic concurrency guardとして利用する。 ### 7.4 process_run @@ -306,10 +320,11 @@ Ollamaに公開する現行Internal Tool catalogは次のとおりとする。å€ "stdin":"string|null" } ``` -- shell command line 1本ではなくexeとargsを分離する。 -- executableはcanonical path + SHA-256 approval必須。 -- shell category disabled時はcmd/powershell/pwshを拒否する。 -- cwdはfilesystem policy内でなければならない。 +- Shell Command 1本ではなくExecutableとargsを分離する。 +- `executable`はApproved Entry Executable/ShellのAlias、Runtime ComponentのLogical/Resolved Path、またはdevelopment Workspace ArtifactのLogical/Resolved Pathとする。Alias以外のrelative Logical Pathは`cwd`を基準に解決する。Approved Entry ExecutableのResolved PathをAliasの代用として直接指定することはできない。 +- Approved Entry Executable/ShellはResolved Path + SHA-256のExecutable Approval必須。Runtime ComponentとWorkspace Artifactは分類rootによって判定する。 +- External Unknown ExecutableをEntry Processとして直接起動しない。Descendant Processは個別分類せずLPAC/ACL/WFP/Job confinementを継承する。 +- cwdはEffective Filesystem Policy内でなければならない。 ### 7.5 task_update ```json { @@ -334,13 +349,13 @@ PlannerがDAG、不変条件、completed immutable、max_tasksを再検査して - mkdir は Write capabilityを要求し、`Directory.CreateDirectory` で親ディレクトリも含めて作成する。 - rmdir は Delete capabilityを要求し、**空ディレクトリのみ**削除する。非空の場合は `ToolValidationException` で拒否する。内容復元の複雑さとMemoryBackupLimit超過リスクを排除するため、再帰削除は行わない。 - list は Read capabilityを要求し、直下のエントリ一覧を返す。外部効果ではない。 -- 既存の PathPolicy / CanonicalPath / TaskAclManager (root継承ACE) / TaskResourceJournal / RecoveryManager 枠組みを利用する。新規作成ディレクトリは親の継承ACEを自動取得するため追加ACL操作は不要。 +- 既存の `ResolvedPath` / `PathPolicy` / `TaskAclManager`(root継承ACE)/ `TaskResourceJournal` / `RecoveryManager` 枠組みを利用する。新規作成directoryは親の継承ACEを自動取得するため追加ACL操作は不要。 - mkdir後crash → ディレクトリ削除、rmdir後crash → 空ディレクトリ再作成、でRecoveryする。 -### 7.7 Tool error表現 -既存のTool resultへ、`error_code`、`error_category`、`target_path`、`required_permission`、`retry_allowed`、`resolution`をoptional fieldとして保持する。これは独立したerror体系ではなく、既存の`SandboxPolicyException`と`ToolExecutionResult`の分類情報を失わずRuntime、Audit、localized messageへ渡す表現である。内部messageと利用者向けlocalized messageは分離し、内部Tool名は利用者向け結果へ含めない。 +### 7.7 Internal Tool error表現 +既存のInternal Tool resultへ、`error_code`、`error_category`、`target_path`、`required_permission`、`retry_allowed`、`resolution`をoptional fieldとして保持する。これは独立したerror体系ではなく、既存の`SandboxPolicyException`と`ToolExecutionResult`の分類情報を失わずRuntime、Audit、localized messageへ渡す表現である。内部messageと利用者向けlocalized messageは分離し、Internal Tool名は利用者向け結果へ含めない。 ### 7.8 ToolUseGuard -Taskには `requires_external_effect` をPlanner内部属性として持たせる。**Planning フェーズで LLM structured output により Task ごとに判定・設定される**(keyword heuristic ではない)。trueのTaskで、当該iteration中のtool callが0かつ完了証拠がない場合、LLMへ「未実行」を示すsystem-generated observationを追加して再試行する。同一失敗fingerprintが5回に達したらTaskをfailedにする。ただし、Policy EngineのdenyおよびSandbox backendの`UnauthorizedAccessException`は`RetryAllowed=false`のterminal Tool resultへ変換する。Runtimeはobserverへ結果を1回記録した後、同一Tool呼出しへ再投入せず、§8.4の条件付きreplanへ遷移する。 +Taskには `requires_external_effect` をPlanner内部属性として持たせる。**Planning フェーズで LLM structured output により Task ごとに判定・設定される**(keyword heuristic ではない)。trueのTaskで、当該iteration中のInternal Tool Callが0かつ完了証拠がない場合、LLMへ「未実行」を示すsystem-generated observationを追加して再試行する。同一失敗fingerprintが5回に達したらTaskをfailedにする。ただし、Policy EngineのdenyおよびSandbox backendの`UnauthorizedAccessException`は`RetryAllowed=false`のterminal Internal Tool resultへ変換する。Runtimeはobserverへ結果を1回記録した後、同一Internal Tool Callへ再投入せず、§8.4の条件付きreplanへ遷移する。 --- ## 8. Token Planner設計 ### 8.1 Task model @@ -360,6 +375,8 @@ Task RequiredTools: set<Internal Tool name> ``` Taskは、完了に成功証跡が必要なTool名を`RequiredTools`として持つ。Planner structured outputの`required_tools`から構築し、Runtimeは集合内の全Toolが成功した場合だけTaskの操作を検証済みとする。read/search/list Taskは副作用不要でも対応Toolを持ち、純粋な説明Taskだけが空集合となる。`RequiresExternalEffect=true`では集合内の副作用Toolから外部効果も確認する。例えば`process_run`が必要なTask中の`file_edit`成功は完了根拠にしない。current Taskの集合に含まれない副作用ToolはBackendへdispatchせず、Task scope外のTool resultとしてLLMへ返してqueued Taskの先取りを決定的に防ぐ。scope外結果はAudit/LLM相関には残すが、次Taskのactive Execution Result contextへは引き継がない。 + +codingの編集・検証・失敗修正は同一Taskへまとめ、`file_edit`と`process_run`をRequiredToolsにする。両Toolを要求する検証Taskが、別の`file_edit` Taskへ直接または間接に依存するsplit planはこの規則に反するためPlanner validationで拒否し、具体的な理由を付けて1回だけ訂正させる。 ### 8.2 PERT計算 ```text ExpectedTokens = (O + 4*M + P) / 6.0 @@ -376,7 +393,7 @@ topological sort後にforward passで各Taskの累積expected token costを計ç® - 実績がPを超過しても即失敗にはせず、remaining Taskのestimate見直しをLLMへ要求できる。 - `max_tasks=32`超過提案は拒否し、既存Taskの統合をLLMへ求める。 - Budget Classは意味的Taskを分割する唯一の理由にしない。Taskが複数独立成果物を含む場合に分割する。 -- Policy denyは同一Tool呼出しへ再投入しない。許可済み能力だけで代替できる可能性がある場合、`running -> planning -> running` と遷移してreplanを最大3回まで試行できる。 +- Effective Sandbox Policy denyは同一Internal Tool Callへ再投入しない。許可済みcapabilityだけで代替できる可能性がある場合、`running -> planning -> running` と遷移してreplanを最大3回まで試行できる。 - completed TaskのID、状態、usageを保持する。failed Taskをdependency解決済みとして扱わない。 - 同一deny fingerprintの再発、計画未変更、実行可能Taskなし、structured replan失敗は即Failedとする。全Taskがcompletedの場合だけAgent Taskをcompletedにする。 - structured planが空または不正な場合は、設定された`think`を維持したまま訂正instruction付きで1回だけ再試行し、それでも失敗した場合はplanning failureとする。外部効果要否が不明なfallback graphは作成しない。 @@ -397,7 +414,7 @@ AgentSession CreatedAt / LastAccessAt ``` ### 9.2 Context assembly -順序を次に固定する。 +実行phaseの順序を次に固定する。 1. Fixed System Prompt 2. User System Prompt 3. locale instruction @@ -410,6 +427,8 @@ AgentSession 10. current Taskの`requires_external_effect`に基づく実行要件 11. recent Conversation +Planning/replanning phaseはread-onlyのTaskGraph生成契約を最初のSystem messageとして使用し、locale、Skill catalog、Sandbox capability summary、original MCP Task requestだけを組み立てる。file調査やInternal Tool実行を指示するFixed/User System PromptはPlanning契約と矛盾するため、このphaseへ混在させない。生成後のTask実行では上記1〜11の優先順位を適用する。 + 実行要件は、現在runningのTaskだけを実行してqueued Taskを先取りしないことをSystemおよび末尾のcurrent Task user messageで指示する。末尾messageにはoriginal MCP Task requestもexact値の参照元として併記する。外部効果が必要なTaskでは文章上の宣言、計画、JSON例を実行済みと扱わず、対応するInternal Toolを直ちに呼び出すよう指示する。成功済みのread結果はExecution Resultから再利用し、不要な再読込を避けてwrite/processへ進む。外部効果が不要なTaskにはToolを強制しない。未解決のTool失敗後にToolを呼ばない応答も同一失敗として数え、既定の同一失敗上限でfailedにする。 ### 9.3 Summary policy `num_ctx`に対する利用率が設定閾値を超えたとき、古いConversation/Execution Resultを要約する。利用率 = latest `prompt_eval_count` / `num_ctx`(累積 InputTokens ではない)。既定閾値は80%とする。次は削除・曖昧化してはならない。 @@ -422,7 +441,7 @@ AgentSession - 承認/Policyそのものではなく現在利用可能なcapability summary raw chain-of-thoughtは保存・要約対象としない。 --- -## 10. SandboxPolicy YAML設計 +## 10. User Sandbox Configuration・Resolution・Effective Policy設計 ### 10.1 schema概要 ```yaml schema_version: 1 @@ -453,21 +472,21 @@ ollama: planner: max_tasks: 32 sandbox: - filesystem: - read: [] - write: [] - execute: [] - delete: [] - process: - allow_shell: true - approvals: [] - max_processes: 16 + profile: development + workspaces: [] + mounts: [] + execution: + executables: [] + shells: [] network: - mode: deny - allow: [] + access: none + local_endpoints: [] + restricted_endpoints: [] resources: - memory_mb: 4096 - process_timeout_seconds: 1800 + profile: normal + memory_mb: + process_limit: + execution_timeout_seconds: file_edit: memory_backup_limit_mb: 16 limits: @@ -484,59 +503,90 @@ logging: directory: logs ``` base YAMLと同じdirectoryに`agent.local.yaml`が存在する場合、YAML nodeを読み取ってmapを再帰mergeし、scalarとsequenceはlocal nodeで置換してからtyped configurationへdeserializeする。unknown propertyを含むvalidationはmerge後に行い、全相対pathのbaseはbase YAMLのdirectoryとする。local file、そこから参照するUser System PromptおよびSkill directoryはRelease Bundleのpublish入力に含めない。 -### 10.2 Filesystem entry -各list itemはpath文字列とする。起動時に絶対canonical pathへ正規化して保持する。file/directoryは実在時に種別を記録し、未作成write targetは最も近い既存親directoryまで検査する。 -### 10.3 Process approval entry +### 10.2 Workspace・Mount・Profile +- `workspaces`はLogical Path文字列のsequenceとする。`readonly`はreadのみ、`development`はread/write/delete/Artifact executeへcompileする。 +- `mounts`は`path`と`access: read_only|read_write|read_write_delete`を持つ。readonly Profileではread_onlyだけを許可し、Mountにexecuteを付与しない。 +- relative Logical Pathはbase YAML directory基準。実在するlocal directoryだけを許可する。 +- 同一Resolved Rootはcapabilityを統合する。親の継承capabilityより狭いnested rootは拒否する。 +### 10.3 Executable Alias・Approval Store ```yaml -approvals: - - path: C:/Program Files/Git/cmd/git.exe - sha256: "<64 hex chars>" - - path: C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe - sha256: "<64 hex chars>" +execution: + executables: [python, git] + shells: [powershell] ``` -署名はaudit metadataとして取得可能だが、v1のallow判定はpath + SHA-256を必須条件とする。 +- AliasはApprovalではない。CLIが候補を提示し、人間が選択したResolved Executable PathとSHA-256をWindows user単位Storeへ固定する。 +- Store pathは`%LOCALAPPDATA%/AgentSandboxMcp/executable-approvals.json`。user-only DACL、WriteThrough、atomic replace、schema versionを持つ。 +- recordはAlias、Approved Entry Executable/Approved Shell Executable分類、Logical Path、Resolved Path、SHA-256、optional Runtime Root、承認日時を持つ。 +- Runtime RootはCLI提案後の明示確認対象とし、その配下のRuntime Componentは個別hashなしでEntry起動できる。 +- Aliasはcase-insensitiveに一意とし、Executable/Shell双方への重複指定を拒否する。ShellのResolved file nameは`cmd.exe|powershell.exe|pwsh.exe`だけを許可する。 ### 10.4 Network entry ```yaml network: - mode: allow - allow: + access: restricted + local_endpoints: [] + restricted_endpoints: - host: github.com ports: [443] - - host: api.github.com - ports: [443] ``` -`allow` modeでもlist外はdeny。`deny`ではlistを無視して全denyする。localhostも特別扱いしない。 +`none`は全deny、`local`は列挙portを`127.0.0.1`/`::1`へ展開、`restricted`はhostをTask開始時にIP snapshot化する。mode不一致または空endpointを拒否する。 +### 10.5 Resource Profile +`constrained=1024 MiB/4/300秒`、`normal=4096 MiB/16/1800秒`、`extended=8192 MiB/32/3600秒`とする。`memory_mb`、`process_limit`、`execution_timeout_seconds`の正数overrideはpreset値を置換する。 +### 10.6 Resolution Result +- Workspace/MountのLogical→Resolved mapping、config絶対path、semantic sandbox fingerprint、確認日時を`%LOCALAPPDATA%/AgentSandboxMcp/environment-resolutions/<config-path-hash>.json`へ保存する。 +- reparse chainを最終targetまで解決しcycle、missing target、非local filesystemを拒否する。確認後のfingerprintまたはResolved Path変化はserve/checkをfail-closedにする。 +- `sandbox resolve`はpreview、`sandbox confirm`だけがStoreを更新し、`sandbox show`はEffective Sandbox Policyをtext/JSON表示する。 + +### 10.7 Effective Sandbox Policy + +確認済みResolution Resultと現在のApproval Storeをcompileし、次を由来付きで保持する。 + +- Filesystem Root: `workspace`、`mount`、`approved_entry_executable`、`approved_shell_executable`、`runtime_root`、`os_runtime_root`の由来、Resolved Path、Filesystem Capability。 +- Entry Executable: Alias、分類、Resolved Path、SHA-256、optional Runtime Root。 +- Artifact RootとRuntime Root: Entry分類およびACL生成に使用するResolved Root。 +- Network: `none|local|restricted`とTask開始時にsnapshot化するendpoint。 +- Resource: Resource Profile名、override適用後のmemory/process/timeout。 +- baseline capability: 固定された`registryRead`と`lpacInstrumentation`。 + +同じResolved RootのFilesystem Capabilityは和集合にし、由来も併記する。親rootから継承するCapabilityより狭いnested rootは表現不能としてcompileを拒否する。`sandbox show`はこのcompile結果をtextまたはJSONで表示するが、Storeや設定を変更しない。 --- ## 11. Windows強制設計 -### 11.1 AppContainer +### 11.1 Less Privileged AppContainer - Application Profileを固定名で作成/取得する。 - 起動時にprofile SIDを解決する。 - Taskごとにprofileを作り直さない。 -- AppContainer外の通常user tokenに戻るbreakawayを許可しない。 +- standard `CreateProcess`の`PROC_THREAD_ATTRIBUTE_SECURITY_CAPABILITIES`に加え、`PROC_THREAD_ATTRIBUTE_ALL_APPLICATION_PACKAGES_POLICY=PROCESS_CREATION_ALL_APPLICATION_PACKAGES_OPT_OUT`を指定してLPAC tokenを生成する。 +- Experimental CreateProcessInSandbox、AppLocker、WDACへ依存しない。LPAC生成または互換性検査失敗時に通常AppContainerへfallbackしない。 +- baseline capabilityは`registryRead`と、PowerShell Runtimeが起動時のETW provider登録に必要とする`lpacInstrumentation`とする。Registry writeと`lpacCom`は付与しない。Network capabilityはEffective Network Policyが必要な場合だけ付与する。`lpacInstrumentation`追加後もRegistry writeとCOM activationの実拒否をWindows Security suiteで検証する。 +- AppContainer外の通常user tokenに戻るbreakawayを許可しない。DescendantはLPAC tokenを継承する。 +- `CreateProcess`へBrokerのenvironment blockをそのまま継承しない。Windows/runtime起動に必要なsystem/profile path、`ComSpec`、System32だけのPATH、Task `cwd`を指すTEMP/TMPと`DOTNET_CLI_HOME`、非対話かつnetwork非依存の.NET初回起動・telemetry・workload resolver値、Process Tree外の共有MSBuild server/node reuseを無効化する値から成る明示的なUnicode environment blockを渡し、任意のtoken、password、SSH/API credential環境変数を除外する。profile path自体はFilesystem Capabilityを付与しない。 ### 11.2 NTFS ACL -- Policy Engineが許可pathから必要ACEを導出する。 -- 許可pathがdirectoryの場合、そのrootへ`ContainerInherit | ObjectInherit`付きのApplication SID ACEを1件だけtransactionalに追加し、既存およびTask中に作成されたdescendantへ継承させる。descendantごとのDACL列挙・snapshot・明示ACE追加は行わない。 +- Effective Sandbox PolicyのFilesystem RootからApplication SID ACEを導出する。 +- read-only directoryはdirectory traverse/list/readとfile readを別ACEとして付与し、fileのExecuteFileを含めない。execute rootだけがfile read/execute ACEを取得する。 +- development Workspace/Artifact Rootはread/write/delete/execute、Runtime RootとResolved `%SystemRoot%/System32`はread/execute、Mountは指定accessのみを取得する。 +- 許可pathがdirectoryの場合、rootへのinheritance ACEで既存およびTask中に作成されたdescendantを覆い、descendantごとのDACL列挙は行わない。 - 許可pathがfileの場合は、そのfileだけへ継承なしACEを追加する。異なる権限を持つnested rootは別scopeとして逆順cleanupする。 - protected DACLを持つdescendantの継承保護は解除しない。そのpathはOS拒否のままとし、Sandbox権限を暗黙に拡張しない。 - rootの元security descriptorをRecovery Journalへ1件記録する。 - Task終了で追加分を除去し、元状態との整合を検査する。 ### 11.3 Job Object - TaskごとにJob Objectを1つ作成する。 -- root sandbox processをJobへ割り当てる。descendantを同一Jobへ継承させる。 +- Entry ProcessをJobへ割り当て、全Descendantを同一Job chainへ継承させる。 - breakawayを許可しない。 - process count / memory limitをJobへ設定する。 - `KILL_ON_JOB_CLOSE`相当を利用し、application終了時にprocess treeを残さない。 -### 11.4 Process approval -Sandbox Brokerは実行直前にcanonical pathを取得し、ファイルを開いた状態でSHA-256を計算し、approvalと一致確認してから起動する。TOCTOU低減のため、検証対象と実行対象のpath解決がずれないよう実装時にWin32のfile identity確認を追加する。具体API選択は実装時に確定する。 +### 11.4 Entry Process分類・Executable Approval +- AliasはApproval StoreのApproved Entry Executable/Shellへ解決し、起動直前とsuspended生成後・resume前にResolved PathとSHA-256を再検証する。 +- Runtime Componentは確認済みRuntime Root containment、Workspace Artifactはdevelopment Artifact Root containmentで分類する。MountおよびExternal Unknown Executableからの直接Entry起動は拒否する。 +- Descendant Processは個別分類・Approvalを行わず、LPAC/ACL/WFP/Job confinementをSecurity Boundaryとする。`PROCESS_CREATION_CHILD_PROCESS_RESTRICTED`は使用しない。 ### 11.5 WFP方針 WFP実装は複雑な汎用Firewallにしない。設計上の変換規則だけを固定する。 -1. `deny`ならApplication Profile/Task processに対するoutbound blockを作成する。 -2. `allow`ならdefault blockを置き、列挙hostをTask開始時にDNS解決する。 +1. `none`ならnetwork capabilityを付与せず、Application Profile/Sandbox Process Treeへoutbound blockを作成する。 +2. `local`は列挙portをIPv4/IPv6 Loopbackへ、`restricted`は列挙hostをTask開始時にIP解決する。 3. 解決したIP集合とportの組にだけallow filterを作成する。 4. Task実行中はそのIP snapshotを使用し、複雑な動的DNS追随は行わない。 5. DNS解決失敗はdeny。 6. Task終了でTask固有WFP filterを削除する。 -7. localhostはallow-listに明示されない限り許可しない。 +7. LoopbackもEffective Network Policyに明示されない限り許可しない。LANをlocalへ含めない。 具体的なWFP layer、sublayer、filter condition、transaction APIは実装時にCodexがWindows SDKを確認して決定し、Security Integration Testで仕様を検証する。 ### 11.6 Named Pipe Sandbox workerとのIPCが必要な場合はtask固有Named Pipeを使用し、DACLをApplication SIDとBrokerだけに限定する。TCP localhostを内部IPCに使わない。 @@ -546,7 +596,7 @@ Sandbox workerとのIPCが必要な場合はtask固有Named Pipeを使用し、D | 性質 | 本システムでの意味 | | --- | --- | | Atomicity | Task Resource適用が途中失敗した場合、適用済み変更をrollbackする。 | -| Consistency | SandboxPolicyとSecurity Invariantを満たす状態だけを実行可能状態とする。 | +| Consistency | Effective Sandbox PolicyとSecurity Invariantを満たす状態だけを実行可能状態とする。 | | Isolation | Task固有ResourceをTask IDで識別し、他Task cleanupで誤削除しない。 | | Durability | Task Resource自体の永続化ではなく、cleanupに必要なjournalをcrashに耐えて保持する。 | ### 12.2 状態機械 @@ -625,7 +675,7 @@ call ID、session ID、task ID、Planner Task ID、phase、iteration、replan番 ### 15.3 Audit JSONL Auditはappend-only JSONLを採用する。1 event = 1 line。 ```json -{"ts":"...","event":"process.start","session_id":"...","task_id":"...","exe":"...","sha256":"...","args":["..."],"decision":"allow"} +{"ts":"...","event":"process.start","session_id":"...","task_id":"...","exe":"...","sha256":"...","arguments":"redacted","argument_count":2,"decision":"allow"} {"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"} ``` @@ -672,7 +722,7 @@ closed Sessionは再利用しない。プロセス再起動後に以前のSessio - locale baseline/placeholder - Ollama endpoint URI - Sandbox path canonicalization -- process approval path/hash format +- Executable Approval StoreのAlias/Logical Path/Resolved Path/hash format - network host/port syntax - resource limit range - Fixed/User prompt file state @@ -684,8 +734,8 @@ closed Sessionは再利用しない。プロセス再起動後に以前のSessio | TokenPERT | O<=M<=P<=budget、式のunit test | | TokenCPM | 既知DAGに対するcritical path unit test | | Filesystem | allow/deny/reparse point integration test | -| Process | hash mismatch、path mismatch、shell toggle | -| Network | deny loopback、allow-list host/port | +| Process | Alias不明、Approval不足、hash/Resolved Path変更、Entry分類拒否、LPAC不一致 | +| Network | noneのLoopback、local/restrictedのPolicy外address/port | | Recovery | 各transaction stateで強制crashして再起動cleanup | | MCP | stdio purity、Streamable HTTP loopback、GET 405 | | Localization | fallback、unknown key fatal、placeholder validation | @@ -693,26 +743,30 @@ closed Sessionは再利用しない。プロセス再起動後に以前のSessio ## 19. Security Test Matrix | ID | ケース | 期待 | | --- | --- | --- | -| ST-01 | read許可file | 成功 | -| ST-02 | read未許可file | ACCESS_DENIED | -| ST-03 | write許可file | 成功 | -| ST-04 | delete権限なしdelete | 拒否 | +| ST-01 | readonly Workspaceのread | 成功 | +| ST-02 | readonly Workspaceのwrite/delete/execute | すべて拒否 | +| ST-03 | development Workspaceのread/write/delete | 成功 | +| ST-04 | development Workspace ArtifactのEntry起動 | Approvalなしで成功 | | ST-05 | junctionで許可外へ脱出 | 拒否 | -| ST-06 | symlink chainで許可外へ脱出 | 拒否 | +| ST-06 | symlink chain/cycle | 許可外は拒否、cycleはfail-closed | | ST-07 | 承認exe/hash一致 | 成功 | | ST-08 | exe更新/hash不一致 | 拒否 | -| ST-09 | shell disabledでPowerShell | 拒否 | -| ST-10 | 子が未承認exe起動 | 拒否 | -| ST-11 | Job close | 全descendant終了 | -| ST-12 | network denyで127.0.0.1 | 拒否 | -| ST-13 | network allowで許可host:port | 成功 | -| ST-14 | network allowで未許可port | 拒否 | +| ST-09 | Approved Shell分類 | cmd.exe/powershell.exe/pwsh.exeだけ直接起動可 | +| ST-10 | Descendantが個別未承認Executableを起動 | 同じLPAC identity/Job内で成功 | +| ST-11 | Job close/breakaway/process/memory/timeout | breakaway不可、制限時は全Process Tree停止 | +| ST-12 | Network noneで127.0.0.1 | 拒否 | +| ST-13 | Network local/restrictedで許可address:port | 成功 | +| ST-14 | Network local/restrictedでPolicy外port | 拒否 | | ST-15 | MCPからpolicy変更試行 | schema/機能上不可能 | -| ST-16 | Ollama tool arg path脱出 | Policyで拒否 | +| ST-16 | Ollama Internal Tool CallのResolved Path脱出 | Policyで拒否 | | ST-17 | crash after ACL apply | 再起動cleanup | | ST-18 | crash after WFP apply | 再起動cleanup | -| ST-19 | malformed locale | 起動失敗 | -| ST-20 | non-loopback HTTP bind | 起動失敗 | +| ST-19 | LPAC baselineでRegistry read/writeとCOM | readのみ成功、write/COM拒否 | +| ST-20 | External Unknown/System32 Executableの直接Entry | Approvalなしでは拒否 | +| ST-21 | malformed locale | 起動失敗 | +| ST-22 | non-loopback HTTP bind | 起動失敗 | +| ST-23 | Approval/Resolution Store | user-only DACL、atomic replace、破損record拒否 | +| ST-24 | config fingerprint/Resolved Path/hash変更 | 再確認または再承認までfail-closed | --- ## 20. エラー分類 | Category | 例 | Task結果 | Retry | @@ -724,7 +778,7 @@ closed Sessionは再利用しない。プロセス再起動後に以前のSessio | tool_failure | process nonzero/patch mismatch | running→replan | 最大同一5 | | resource_limit | timeout/memory/process limit | failedまたはreplan | 原則No | | recovery_failure | ACL/WFP cleanup不能 | application fatal | No | -errorは内部codeとlocalized messageを分離し、ログ/auditにはcode、MCPにはlocalized textを返す。 +errorは内部codeとlocalized messageを分離し、ログ/auditにはcode、MCPにはlocalized textを返す。Sandbox Configuration/Resolution/Approvalの失敗は少なくとも`configuration.invalid`、`sandbox.resolution_unconfirmed`、`sandbox.resolution_changed`、`executable.approval_missing`、`executable.resolution_changed`、`executable.hash_changed`、`executable.shell_unsupported`、`process.lpac_unsupported`を既存分類へ統合し、category、対象、解決方法を保持する。 --- ## 21. 実装順序 | Phase | 実装 | 完了条件 | @@ -735,7 +789,7 @@ errorは内部codeとlocalized messageを分離し、ログ/auditにはcode、MC | 4 | Internal Tool dispatcher | tool schemaとToolUseGuard | | 5 | Filesystem/Process Sandbox | ACL/AppContainer/Job integration test | | 6 | Resource Transaction/Recovery | 強制crash recovery test | -| 7 | WFP | deny/allow-list integration test | +| 7 | WFP | none/local/restricted integration test | | 8 | Vision/Streamable HTTP | image optional、loopback HTTP | | 9 | Audit/Hardening | security matrix全PASS | | 10 | Release/Operational E2E | self-contained Bundle単独起動、stdio/HTTP実利用 | @@ -744,7 +798,7 @@ errorは内部codeとlocalized messageを分離し、ログ/auditにはcode、MC - `dotnet publish -c Release -r win-x64 --self-contained true` のfolder publishを配布元とする。 - Bundleはversion付きZIP、展開済みdirectory、file manifest、SHA-256 checksumから成る。 - 起動時の相対pathは実行ファイルdirectoryを基準に解決し、ソースツリーを参照しない。 -- 必須Gateはlocal Ollamaだけで実行し、cloud modelは任意互換試験に限定する。 +- 現行Operational E2Eは配布既定の`deepseek-v4-flash:cloud`を使用する。rate limit、接続失敗、model unavailableをapplication PASSとして扱わない。 --- ## 22. Codex実装制約 - 新規NuGet dependencyを勝手に追加しない。追加時は標準ライブラリで不能な理由を示す。 @@ -820,17 +874,18 @@ errorは内部codeとlocalized messageを分離し、ログ/auditにはcode、MC | ollama.options.* | typed runtime options | | ollama.extra_options.* | future passthrough options | | planner.max_tasks | 32 default | -| sandbox.filesystem.read | read allow-list | -| sandbox.filesystem.write | write allow-list | -| sandbox.filesystem.execute | execute path allow-list | -| sandbox.filesystem.delete | delete allow-list | -| sandbox.process.allow_shell | shell toggle | -| sandbox.process.approvals | path+sha256 approvals | -| sandbox.process.max_processes | Job process limit | -| sandbox.network.mode | deny/allow | -| sandbox.network.allow | host/port list | -| sandbox.resources.memory_mb | Job memory limit | -| sandbox.resources.process_timeout_seconds | process timeout | +| sandbox.profile | readonly/development Workspace preset | +| sandbox.workspaces | Workspace Logical Path list | +| sandbox.mounts | Mount Logical Path + semantic access | +| sandbox.execution.executables | Approved Entry Executable Alias list | +| sandbox.execution.shells | Approved Shell Executable Alias list | +| sandbox.network.access | none/local/restricted | +| sandbox.network.local_endpoints | Loopback port list | +| sandbox.network.restricted_endpoints | host/port list | +| sandbox.resources.profile | constrained/normal/extended | +| sandbox.resources.memory_mb | optional memory override | +| sandbox.resources.process_limit | optional Job process override | +| sandbox.resources.execution_timeout_seconds | optional execution timeout override | | file_edit.memory_backup_limit_mb | memory/temp threshold | | localization.directory | locale directory | | localization.fallback | en | @@ -875,7 +930,7 @@ errorは内部codeとlocalized messageを分離し、ログ/auditにはcode、MC - [ ] process hashは実行直前に再計算しているか。 - [ ] shell有効でもFilesystem/Network policyを迂回できないか。 - [ ] Job breakawayがないか。 -- [ ] Network allow-list外がdefault denyか。 +- [ ] Effective Network Policy外がdefault denyか。 - [ ] WFP/ACL変更前にjournalを書いているか。 - [ ] 起動時Recoveryがserveより前か。 - [ ] file rollback後にhash検証しているか。 |
