Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions agent-governance-python/agent-os/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Security
- **Agent OS security & integrity hardening** ([#3247](https://github.com/microsoft/agent-governance-toolkit/pull/3247)) — five governance gaps closed so `agent_os` fails closed when gating and recording untrusted activity:
- `MCPMessageSigner` / `InMemoryNonceStore` no longer evict in-window nonces by count. The nonce store keeps every nonce for its full replay window and, when saturated with live nonces, raises `NonceStoreCapacityError` so verification fails closed instead of re-opening the replay window. (New public export: `NonceStoreCapacityError`.)
- `MemoryGuard.validate_write` now detects markup-wrapped tool poisoning — hidden-instruction tags paired with destructive shell commands (`rm -rf`, fork bombs, `dd if=`, …) or pipe-to-shell exfiltration — via a new `AlertType.TOOL_POISONING`. Bare tool tags and plain `curl` mentions stay allowed to avoid false positives on benign runbooks.
- `GovernanceEventProcessor` gained reconciling accounting: `submitted_count`, `delivered_count`, and `failed_count` (alongside `dropped_count`) so `submitted == delivered + failed + dropped`. Events sent to a failing or circuit-broken sink are counted, never silently lost; intentional sink `DROPPED` results are bucketed as dropped, not failed.
- `HealthChecker` fails closed: a checker with no components now aggregates to `UNHEALTHY`, the built-in `policy_engine`/`audit_backend` checks auto-register, and the audit check reports `DEGRADED` when no durable audit backend is configured instead of a bare `HEALTHY`.
- Governance audit events are exportable as signed CloudEvents 1.0 via `GovernanceEvent.to_cloudevent()` and a new HMAC `GovernanceEventSigner` (the signature covers the algorithm attribute). New `StdoutGovernanceSink` and `OTLPGovernanceSink` deliver signed CloudEvents; the OTLP sink reports `DROPPED` (not delivered) when OpenTelemetry is absent. (New public exports: `GovernanceEventSigner`, `StdoutGovernanceSink`, `OTLPGovernanceSink`.)
- **Broadened SSN PII regex across integration adapters** ([#2635](https://github.com/microsoft/agent-governance-toolkit/issues/2635), [#2636](https://github.com/microsoft/agent-governance-toolkit/pull/2636)) — the dashed-only `\b\d{3}-\d{2}-\d{4}\b` regex used by the LangChain, AutoGen, CrewAI, and Bedrock adapters to detect SSNs in memory writes and outbound messages was trivially bypassed by space-, dot-, or no-separator variants such as `123 45 6789`, `123.45.6789`, and `123456789`. The pattern is now `\b\d{3}[\s.-]?\d{2}[\s.-]?\d{4}\b`, matching the YAML policy pack fix from [#2594](https://github.com/microsoft/agent-governance-toolkit/pull/2594) / [#2469](https://github.com/microsoft/agent-governance-toolkit/issues/2469).
- `POST /api/v1/execute` now fails closed by default and no longer trusts
caller-asserted `agent_id` values before policy, audit, and rate-limit
Expand Down
13 changes: 10 additions & 3 deletions agent-governance-python/agent-os/docs/api-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,9 @@ Thread-safe health checker for K8s readiness/liveness probes.
```python
from agent_os.health import HealthChecker, HealthStatus, ComponentHealth

# By default the built-in policy_engine and audit_backend checks are
# auto-registered. Pass an audit_backend to make the audit check HEALTHY,
# or register_builtins=False for a bare checker.
checker = HealthChecker(version="1.3.1")
checker.register_check("database", lambda: ComponentHealth(
name="database",
Expand All @@ -591,13 +594,17 @@ report = checker.check_ready() # Readiness probe
report = checker.check_live() # Liveness probe (lightweight)

print(report.to_dict())
print(report.is_healthy()) # True
print(report.is_ready()) # True (not UNHEALTHY)
# With no audit_backend configured, audit_backend reports DEGRADED, so:
print(report.is_healthy()) # False (DEGRADED)
print(report.is_ready()) # True (DEGRADED is still ready; not UNHEALTHY)
```

A checker with **no** registered components fails closed and aggregates to
`UNHEALTHY` (an empty report never claims healthy).

| Method | Signature | Returns | Description |
|--------|-----------|---------|-------------|
| `__init__` | `(version: str = "1.0.0")` | — | Create checker |
| `__init__` | `(version: str = "1.0.0", *, register_builtins: bool = True, audit_backend: object \| None = None)` | — | Create checker; auto-registers built-in `policy_engine`/`audit_backend` checks unless `register_builtins=False` |
| `register_check` | `(name: str, check_fn: Callable)` | `None` | Register a named health check (thread-safe) |
| `check_health` | `()` | `HealthReport` | Run all checks and return full report |
| `check_ready` | `()` | `HealthReport` | Readiness probe (same as full check) |
Expand Down
8 changes: 8 additions & 0 deletions agent-governance-python/agent-os/src/agent_os/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ def check_installation() -> None:
MCPNonceStore,
MCPRateLimitStore,
MCPSessionStore,
NonceStoreCapacityError,
)
from agent_os.mcp_response_scanner import (
MCPResponseScanner,
Expand Down Expand Up @@ -297,9 +298,12 @@ def check_installation() -> None:
GovernanceEvent,
GovernanceEventKind,
GovernanceEventProcessor,
GovernanceEventSigner,
GovernanceEventSink,
GovernanceEventSinkBase,
OTLPGovernanceSink,
SinkExportResult,
StdoutGovernanceSink,
)

# ============================================================================
Expand Down Expand Up @@ -414,6 +418,7 @@ def check_installation() -> None:
"MCPAuditSink",
"InMemorySessionStore",
"InMemoryNonceStore",
"NonceStoreCapacityError",
"InMemoryRateLimitStore",
"InMemoryAuditSink",
"MCPResponseScanner",
Expand Down Expand Up @@ -459,6 +464,9 @@ def check_installation() -> None:
"GovernanceEventSink",
"GovernanceEventSinkBase",
"GovernanceEventProcessor",
"GovernanceEventSigner",
"StdoutGovernanceSink",
"OTLPGovernanceSink",
"SinkExportResult",
"AuditBackendSinkAdapter",
]
Loading
Loading