[codex] Add tool governance middleware#105
Conversation
🤖 Augment PR SummarySummary: This PR introduces an optional, centralized tool-governance gate for OpenClaw.NET, enforced in Changes:
Technical Notes: Sidecar calls are time-bounded via cancellation tokens; on failure, behavior is controlled by 🤖 Was this summary useful? React with 👍 or 👎 |
|
|
||
| Read("profile_read", "profile", ["profile.read"]), | ||
| Write("profile_write", "profile", ToolGovernanceRiskLevel.Medium, ["profile.write"]), | ||
| Read("todo", "productivity", ["todo.read", "todo.write"]), |
There was a problem hiding this comment.
todo is registered via Read(...) (which sets ReadOnly=true and RiskLevel=Low) even though the tool supports mutating actions (add/update/complete/remove/clear); this can incorrectly treat it as “low-risk read-only” for fail-open behavior when the sidecar is unavailable. Other locations where this applies: src/OpenClaw.Core/Governance/ToolGovernanceDescriptorCatalog.cs:82, src/OpenClaw.Core/Governance/ToolGovernanceDescriptorCatalog.cs:95.
Severity: high
Other Locations
src/OpenClaw.Core/Governance/ToolGovernanceDescriptorCatalog.cs:82src/OpenClaw.Core/Governance/ToolGovernanceDescriptorCatalog.cs:95
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
| deniedByGovernance, | ||
| callId: callId, | ||
| resultStatus: ToolResultStatuses.Blocked, | ||
| failureCode: ToolFailureCodes.GovernanceDenied, |
There was a problem hiding this comment.
This path uses ToolFailureCodes.GovernanceDenied even when the underlying reason is sidecar timeout/unavailability (from BuildUnavailableDecision), which makes outages indistinguishable from policy denials. It looks like ToolFailureCodes.GovernanceUnavailable was added for this distinction but isn’t used here.
Severity: medium
🤖 Was this useful? React with 👍 or 👎, or 🚀 if it prevented an incident/outage.
There was a problem hiding this comment.
Pull request overview
Adds an optional, centralized tool-governance gate to OpenClaw.NET by introducing IToolGovernanceService and wiring it through gateway composition and both native/MAF runtime factories so governance decisions can allow/deny/require-approval/redact/audit tool calls from within OpenClawToolExecutor (including audit/trace enrichment).
Changes:
- Introduces governance config + models, a built-in tool descriptor catalog, and two governance service implementations (noop + HTTP sidecar).
- Wires governance through gateway composition and agent runtime factory creation (native + Microsoft Agent Framework).
- Enriches tool invocations/audit entries with governance metadata; adds docs + K8s sidecar deployment example and unit tests.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| src/OpenClaw.Tests/ToolGovernanceTests.cs | Adds unit tests covering allow/deny/require-approval, timeout fail-closed/fail-open, and descriptor catalog coverage. |
| src/OpenClaw.MicrosoftAgentFrameworkAdapter/MafAgentRuntimeFactory.cs | Passes governance service through delegated and direct MAF runtime factory context/config. |
| src/OpenClaw.MicrosoftAgentFrameworkAdapter/MafAgentRuntime.cs | Wires governance into the runtime construction path. |
| src/OpenClaw.Gateway/Composition/RuntimeInitializationExtensions.RuntimeFactories.cs | Resolves IToolGovernanceService from DI and supplies it to agent runtimes. |
| src/OpenClaw.Gateway/Composition/CoreServicesExtensions.cs | Registers governance config and chooses/noops the governance provider; constructs HTTP sidecar adapter. |
| src/OpenClaw.Core/Observability/ToolAuditLog.cs | Extends audit entry schema with governance decision fields. |
| src/OpenClaw.Core/Models/ToolGovernanceModels.cs | Adds governance config, decision models, descriptors, and sidecar request/response payload types. |
| src/OpenClaw.Core/Models/Session.cs | Persists governance metadata on ToolInvocation and adds JSON source-gen registrations for new models. |
| src/OpenClaw.Core/Models/OperatorGovernanceModels.cs | Adds governance-related tool failure codes. |
| src/OpenClaw.Core/Models/GatewayConfig.cs | Adds GatewayConfig.Governance config section. |
| src/OpenClaw.Core/Governance/ToolGovernanceDescriptorCatalog.cs | Provides built-in tool descriptors and fallback descriptors for dynamic/plugin tools. |
| src/OpenClaw.Core/Governance/NoopToolGovernanceService.cs | Implements a default “allow” governance service when disabled/unconfigured. |
| src/OpenClaw.Core/Governance/HttpSidecarToolGovernanceService.cs | Implements AOT-safe HTTP sidecar decision + optional result-audit adapter. |
| src/OpenClaw.Core/Abstractions/IToolGovernanceService.cs | Introduces the governance boundary interface used by the runtime executor. |
| src/OpenClaw.Agent/OpenClawToolExecutor.cs | Executes governance checks centrally (pre-approval/sandbox/exec), applies decisions, and records governance audit/trace metadata. |
| src/OpenClaw.Agent/NativeAgentRuntimeFactory.cs | Passes governance service into the native runtime creation path. |
| src/OpenClaw.Agent/IAgentRuntimeFactory.cs | Extends factory context to carry an optional governance service instance. |
| src/OpenClaw.Agent/AgentRuntime.cs | Wires governance service into the tool executor used by the agent runtime. |
| docs/SITE_MAP.md | Adds docs entries for the new governance documentation pages. |
| docs/README.md | Links governance docs from the main documentation index. |
| docs/governance/sidecar-pattern.md | Documents sidecar flow, configuration, supported actions, and audit fields. |
| docs/governance/microsoft-agent-governance.md | Documents Microsoft Agent Governance integration approach and deployment cautions. |
| deploy/kubernetes/governance-sidecar/service.yaml | Adds example service manifest for the governance sidecar deployment pattern. |
| deploy/kubernetes/governance-sidecar/README.md | Adds deployment instructions and cautions for the sidecar example. |
| deploy/kubernetes/governance-sidecar/deployment.yaml | Adds example pod spec running OpenClaw.NET with a governance sidecar container. |
| deploy/kubernetes/governance-sidecar/configmap-policy.yaml | Adds an example policy ConfigMap for the governance sidecar. |
| var allowed = action == GovernanceAction.RequireApproval | ||
| ? true | ||
| : sidecar.Allowed ?? action is GovernanceAction.Allow or GovernanceAction.AuditOnly or GovernanceAction.Redact; |
|
|
||
| if (!Uri.TryCreate(config.SidecarBaseUrl, UriKind.Absolute, out var baseUri)) | ||
| throw new InvalidOperationException("OpenClaw:Governance:SidecarBaseUrl must be an absolute URL when governance is enabled."); | ||
|
|
|
|
||
| if (!string.IsNullOrWhiteSpace(governanceDecision.RedactedArgumentsJson)) | ||
| { | ||
| persistedArgsJson = _redaction.Redact(governanceDecision.RedactedArgumentsJson); |
| callId: callId, | ||
| resultStatus: ToolResultStatuses.Blocked, | ||
| failureCode: ToolFailureCodes.GovernanceDenied, | ||
| failureMessage: deniedByGovernance, | ||
| nextStep: "Adjust the request or governance policy before retrying.", |
Summary
Adds an optional central tool-execution governance gate to OpenClaw.NET. Governance is enforced in the runtime tool executor instead of individual tools, with OpenClaw-owned abstractions and an AOT-safe HTTP sidecar adapter.
Changes
Validation
AOT publish emitted macOS linker/module-cache warnings only; the published gateway doctor found no failed checks.