Skip to content

feat: add GovernanceEventSink SPI — AGT as event producer for SIEM/XDR integration#1987

Open
Copilot wants to merge 4 commits into
mainfrom
copilot/feature-os-level-enforcement
Open

feat: add GovernanceEventSink SPI — AGT as event producer for SIEM/XDR integration#1987
Copilot wants to merge 4 commits into
mainfrom
copilot/feature-os-level-enforcement

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 11, 2026

Description

Addresses the governance enforcement gap raised in the OS-level enforcement issue by implementing the provider-interface approach outlined by @Ricky-G: AGT becomes a structured event producer; enforcement backends (Defender, Falco, Tetragon, Sentinel, Splunk) act as sinks. No kernel code, no competing with EDR tools.

Core primitives (all four SDKs)

  • GovernanceEventCategory — 6 categories aligned with CloudEvents + OTEL conventions: policy.decision, policy.breach, identity.assertion, tool.invocation, sandbox.event, audit.chain
  • SignedGovernanceEvent — CloudEvents 1.0 envelope with HMAC-SHA256 tamper-evidence signature ("{type}\n{source}\n{time}\n{id}\n{data_json}")
  • GovernanceEventSink — single-method async interface/protocol; mirrors the existing SandboxProvider shape

Reference sinks

  • OtlpEventSink — routes to any OTLP-compatible backend (Defender for Cloud, Sentinel, Splunk, Datadog, Honeycomb, Dynatrace, Grafana). No new deps: Python uses existing optional opentelemetry-sdk; .NET uses built-in ActivitySource; TypeScript uses node:http; Rust writes OTLP JSON to a Write target.
  • StdoutEventSink — JSON lines to stdout; suitable for dev/CI and container log aggregators

.NET kernel wiring

GovernanceOptions gains EventSink and EventSigningKey. When set, the kernel bridges every AuditEmitter event to the sink as a signed SignedGovernanceEvent. Sink errors surface via Trace.TraceError (observable, non-blocking).

var kernel = new GovernanceKernel(new GovernanceOptions {
    EventSink = new OtlpEventSink(),
    EventSigningKey = Encoding.UTF8.GetBytes(signingKey),
});
// Every EvaluateToolCall() now emits a signed CloudEvents envelope to OTLP
sink = OtlpEventSink()  # or StdoutEventSink() for dev
event = SignedGovernanceEvent.build(
    GovernanceEventCategory.POLICY_DECISION,
    source="did:agentmesh:agent-1",
    subject="tool:file_write",
    data={"decision": "deny"},
    signing_key=key,
)
await sink.emit(event)
assert event.verify_signature(key)

Threat model coverage

Ask Status
Cryptographically verifiable audit trail ✅ HMAC-SHA256 signed CloudEvents
External enforcement/visibility ✅ Falco/Tetragon/Defender become OTLP sinks
Bypass-resistant telemetry ⚠️ In-process; SIEM silence-as-signal pattern applies
eBPF/WFP/kernel drivers ❌ Out of scope — delegated to backend EDR tooling

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Maintenance (dependency updates, CI/CD, refactoring)
  • Security fix

Package(s) Affected

  • agent-os-kernel
  • agent-mesh
  • agent-runtime
  • agent-sre
  • agent-governance
  • docs / root

Checklist

  • My code follows the project style guidelines (ruff check)
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass (pytest)
  • I have updated documentation as needed
  • I have signed the Microsoft CLA

Attribution & Prior Art

  • This contribution does not contain code copied or derived from other projects without attribution
  • Any external projects that inspired this design are credited in code comments or documentation
  • If this PR implements functionality similar to an existing open-source project, I have listed it below

Prior art / related projects (if any):

AI Assistance

  • I can explain every meaningful change in this PR: what it does, why, and what tradeoffs were considered
  • I have run tests and verification appropriate for this change
  • No part of this PR was autonomously submitted by an AI agent without my review
  • I have not used AI to generate review comments on others' PRs

IP, Patents, and Licensing

  • This contribution does not implement patent-pending or patent-encumbered techniques
  • This contribution does not require an NDA or licensing agreement to understand or use
  • Any AI tools used have terms compatible with the MIT License

Related Issues

Copilot AI and others added 2 commits May 11, 2026 06:34
…d Rust

Implements the provider interface (SPI) pattern described by @Ricky-G:
- IGovernanceEventSink / GovernanceEventSink protocol (one async method)
- SignedGovernanceEvent: CloudEvents 1.0 envelope + HMAC-SHA256 signature
- GovernanceEventCategory enum (policy.decision, policy.breach,
  identity.assertion, tool.invocation, sandbox.event, audit.chain)
- OtlpEventSink: routes events to any OTLP-compatible backend
- StdoutEventSink: JSON lines to stdout (dev/CI)
- GovernanceKernel (.NET) wired to forward audit events via event sink
- Tests for all four SDKs (34 Python, 28 .NET, 23 TypeScript, 11 Rust)

Agent-Logs-Url: https://github.com/microsoft/agent-governance-toolkit/sessions/d8eaa113-2391-466d-be07-76a474899c47

Co-authored-by: imran-siddique <[email protected]>
…forget observability)

- Rust: remove hardcoded HMAC fallback key, use .expect() for clarity
- .NET: make fire-and-forget sink errors observable via System.Diagnostics.Trace

Agent-Logs-Url: https://github.com/microsoft/agent-governance-toolkit/sessions/d8eaa113-2391-466d-be07-76a474899c47

Co-authored-by: imran-siddique <[email protected]>
Copilot AI changed the title [WIP] Add OS-level enforcement in AI agent governance feat: add GovernanceEventSink SPI — AGT as event producer for SIEM/XDR integration May 11, 2026
Copilot AI requested a review from imran-siddique May 11, 2026 06:39
assert body["data"]["seq"] == 42

def test_multiple_emits(self):
for cat in GovernanceEventCategory:
Args:
event: The signed governance event to forward.
"""
...

import asyncio
import json
import sys
import asyncio
import json
import sys
from io import StringIO
Comment on lines +26 to +33
from agent_os.event_sink import (
GovernanceEventCategory,
GovernanceEventSink,
OtlpEventSink,
SignedGovernanceEvent,
StdoutEventSink,
_hmac_sha256,
)
SignedGovernanceEvent,
StdoutEventSink,
)
except ImportError:
_HAS_OTEL_LOGS = True
_LogRecord = _LR
_SeverityNumber = _SN
except ImportError:
@imran-siddique imran-siddique marked this pull request as ready for review May 13, 2026 00:01
@github-actions
Copy link
Copy Markdown

PR Review Summary

Check Status Details
🔍 Code Review ⏳ Pending Awaiting results
🛡️ Security Scan ⏳ Pending Awaiting results
🔄 Breaking Changes ⏳ Pending Awaiting results
📝 Docs Sync ⏳ Pending Awaiting results
🧪 Test Coverage ⏳ Pending Awaiting results

Verdict: ⏳ Still running

@github-actions github-actions Bot added the size/XL Extra large PR (500+ lines) label May 13, 2026
@github-actions
Copy link
Copy Markdown

This PR is quite large. Consider breaking it into smaller PRs for easier review.

@github-actions github-actions Bot added tests and removed size/XL Extra large PR (500+ lines) labels May 13, 2026
@github-actions
Copy link
Copy Markdown

Dependency Review

✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.

Scanned Files

None

@Ricky-G
Copy link
Copy Markdown
Contributor

Ricky-G commented May 13, 2026

Proposal submitted for this, want to get Elton's view on this as well and then we can re-purpose this PR with the full implementation.

#2240

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: OS-Level Enforcement in AI Agent Governance

3 participants