Kyvern¶
Decision provenance and accountability infrastructure for autonomous systems.
When an autonomous system makes a consequential decision — a robot stops mid-motion, a vehicle reroutes, an actuator fires — what happened is usually loggable. Why it happened, in a form a safety officer, regulator, or court can read, is almost always reconstructed after the fact, by hand.
Kyvern is the missing layer:
- Records your system's own decisions.
record_decision()signs what your robot, planner or operator decided, why, on which inputs and under which version of your policy, into a verifiable chain. Your decision logic stays yours. - Optional rule-first decision engine. Kyvern's own engine traces every action back to a human-authored policy. AI advises; rules decide.
- Cryptographically signed audit chain. Every decision is recorded with full provenance: which rule fired, which inputs triggered it, which guardrails ran, what was downgraded. Linked via Ed25519 signature.
- Guardrail-downgrade-only pattern. Safety layers can only make decisions safer, never more dangerous. Mathematically enforced.
- LLM advisor with prompt injection defense. Models suggest; they do not act. Adversarial inputs are sanitized before reaching the decision boundary.
- Air-gap deployable. Runs fully offline with local model fallback. No data leaves the deployment environment.
Status¶
Pre-1.0. Core engine and audit chain are battle-tested in a private deployment (separate codebase). This repository is the generalized, domain-neutral open-core extraction.
Active areas: recording a system's own decisions, the ROS2 safety-controller demo, the MCP server interface, EU AI Act evidence reports.
Recording your own decisions¶
Install from a clone of the repository (pip install .), then record a
decision your system made:
from kyvern import record_decision
record_decision(
"stop", # what your system did
source="safety_controller", # who decided ("operator" for a person)
reasoning="obstacle at 0.4 m, closer than 0.5 m",
inputs={"obstacle_distance_m": 0.4}, # what it was based on (up to 64 KB)
rule_id="stop-on-obstacle", # the rule in your policy that fired
policy_path="safety_policy.yaml", # binds the decision to that policy version
)
The policy is your own YAML file with a rules: list; Kyvern records the
SHA-256 of its content with each decision. The decision is signed and
appended to ~/.kyvern/chain.jsonl (or $KYVERN_CHAIN_PATH) and can then be
verified, anchored and reported on.
Verifying decisions¶
For auditors and compliance officers, the decision provenance chain can be verified offline without writing code:
kyvern-verify chain.jsonl --policy config/policies/default.yaml --pubkey ~/.kyvern/keys/signing.pub
Output:
✓ Chain integrity: VALID (3 decisions, 1 runtime events, all signed)
✓ Policy match: 5b64432b2dd0796f (default.yaml @ 2026-10-08 04:51 UTC): 3 decisions
✓ Signature verification: PASSED (Ed25519)
Anchors: none (no chain.anchors.jsonl)
Decision summary:
[0] 14:32:07 action=LOG rule_id=POL-1 guardrails=[input-single-tick]
[1] 14:32:09 action=ALERT rule_id=POL-2 guardrails=[]
[2] 14:32:12 event=sensor_anomaly source=imu_monitor
[3] 14:32:15 action=ALERT rule_id=POL-2 guardrails=[]
Audit hash: 5b64432b2dd0796f (verifiable against deployed policy)
EU AI Act evidence reports¶
Generate a PDF of checks run on a signed decision chain, mapped to the EU AI Act Articles they support: Article 12 (record-keeping) and Article 14 (human oversight):
kyvern-report chain.jsonl \
--policy config/policies/default.yaml \
--pubkey ~/.kyvern/keys/signing.pub \
--output report.pdf \
--system-id "AMR-Fleet-A" \
--operator "Operations Team"
The PDF covers chain integrity, the policy check, action and threat-level distribution, the Article 12 and 14 checks, the policy version timeline, and a fingerprint of the report content. Each check is computed from the chain (PASS/FAIL with counts) or marked NOT ASSESSED where a chain cannot show it, such as whether an operator can override the system. The report supports an assessment; it does not establish conformity. See EU AI Act.
MCP server (Claude Desktop)¶
Plug Kyvern into Claude Desktop in ~30 seconds and ask questions like "what did my autonomous system do in the last hour?":
Kyvern is not published on PyPI yet, so install from source:
git clone https://github.com/altunbulakemre75/kyvern.git
cd kyvern
pip install -e ".[mcp]"
Then add to your Claude Desktop config:
{
"mcpServers": {
"kyvern": {
"command": "kyvern-mcp",
"args": ["--chain-file", "/path/to/chain.jsonl", "--pubkey", "/path/to/signing.pub"]
}
}
}
Five read-only tools (query_events, get_event, get_stats,
verify_chain, search_events) and four resources cover signed audit
query, chain verification, and active-policy metadata. See MCP integration.
Integrations¶
ROS2 safety-controller demo: a robot's own stop / slow / continue
decisions, recorded with record_decision() from a /scan subscriber,
then verified and reported. It runs without ROS2 too. See
examples/ros2_safety_demo.
ROS2 bridge: publishes signed Decision objects to a ROS2 topic for consumption by autonomous systems. See ROS2 integration.
Architecture¶
See Architecture for the full design: components, data flow, audit chain implementation (Ed25519 + SHA-256 hash chain), the guardrail downgrade-only invariant, and integration points.
Security¶
Kyvern defends against two primary threats: insider post-hoc tampering of decision history (Ed25519 + SHA-256 hash chain) and AI-induced unsafe escalation (LLM advisory ceiling + guardrail downgrade-only invariant).
It does not defend against signing key compromise, sensor-level deception, runtime intrusion, or network attacks — those are operator responsibilities.
See Threat Model for the full threat model, including explicit non-defenses and what this means for compliance claims.
Roadmap¶
- [x] EU AI Act Article 12 & 14 evidence report (
cli/kyvern_report.py) - [x] ROS2 publisher (
services/integrations/ros2_bridge.py) - [ ] ROS2 action sink with feedback loop (planned)
- [x] MCP server interface (
kyvern/mcp/,kyvern-mcp) - [ ] IMM filter as default in TrackManager
- [ ] OpenAI provider in LLM chain
- [ ] Internationalization of in-code documentation (Turkish → English)
License¶
Apache 2.0.
Contact¶
Discussion on Open Robotics Discourse or open a GitHub issue.