Capability-based security kernel for AI agents operating in large tool ecosystems
Project description
agent-kernel
Least-privilege, revocable, principal-scoped authorization for agent tool calls — with a tamper-evident audit of everything that ran.
A capability-based security kernel for AI agents operating in large tool ecosystems (MCP, A2A, 1000+ tools).
Every tool call gets a capability token (HMAC-signed, time-bounded, scoped to one principal and one capability) and a tamper-evident audit trace (ActionTrace) recording who invoked what, under which policy decision, with what result. That authorization + audit layer is agent-kernel's unique contribution to the Weaver stack — neither contextweaver nor AgentFence provides it.
Why agent-kernel and not contextweaver or AgentFence?
contextweaverdecides what context the LLM sees.agent-kerneldecides what the agent is allowed to run, and proves what it ran.AgentFenceis an external proxy that gates tool calls at the process boundary.agent-kernelis the in-process runtime that mints the capability token, enforces policy, firewalls the result, and writes the audit trace — compiled into your agent host.- They compose: author policy once and enforce it both embedded (
agent-kernel) and at the edge (AgentFence); produce aFrameinagent-kerneland letcontextweaverdo budgeted selection over it. See the boundary notes below.
30-second pitch
Modern AI agents face three hard problems when given access to hundreds or thousands of tools:
- No authorization or audit — nothing scopes what a tool call may do, and there's no record of what ran, when, and why.
- Tool-space interference — agents accidentally invoke the wrong tool or escalate privileges.
- Context blowup — raw tool output floods the LLM context window.
agent-kernel solves all three with a thin, composable layer that sits above your tool execution layer. The first two features are its unique, non-overlapping contribution; the last two it also provides, with explicit boundaries against its siblings:
- Capability Tokens (unique to agent-kernel) — HMAC-signed, time-bounded, principal-scoped. No token → no execution.
- Audit Trail (unique to agent-kernel) — every invocation creates an
ActionTraceretrievable viakernel.explain(). - Policy Engine (boundary vs AgentFence) — READ/WRITE/DESTRUCTIVE safety classes + PII/PCI sensitivity handling, enforced in-process.
AgentFenceenforces an equivalent gate at the external boundary; the goal is to author one policy and enforce it both places (shared-policy contract — #111). - Context Firewall (boundary vs contextweaver) — raw driver output is never returned to the LLM; always a bounded
Frame.agent-kernelis the producer of the canonicalFrameat the execution boundary;contextweaveris a consumer that does budgeted selection over Frames — deliberate layering, not redundancy (canonical-Frameseam — #110).
Architecture
graph LR
LLM["LLM / Agent"] -->|goal| K["Kernel"]
K -->|search| REG["Registry"]
K -->|evaluate| POL["Policy Engine"]
K -->|sign| TOK["HMAC Token"]
K -->|route| DRV["Driver (MCP/HTTP/Memory)"]
DRV -->|RawResult| FW["Context Firewall"]
FW -->|Frame| LLM
K -->|record| AUD["Audit Trace"]
Part of the Weaver Stack
agent-kernel is the execution / authorization runtime of the Weaver
stack — a set of composable, independently usable projects for building safe
LLM-agent systems. On the request path:
contextweaver ─► ChainWeaver ─► agent-kernel ─► AgentFence
(select & (deterministic (capability tokens, (external policy
compile context) tool chains) policy, firewall, gate at the edge)
tamper-evident audit)
| Project | Role in the stack |
|---|---|
| contextweaver | Selects and compiles the context the LLM sees. |
| ChainWeaver | Orchestrates deterministic multi-step tool chains. |
| agent-kernel (this repo) | Authorizes, executes, firewalls, and audits tool calls in-process. |
| AgentFence | Enforces a policy gate at the external process boundary. |
| weaver-spec | The shared contracts (invariants; capability/token/Frame/policy) the others conform to. |
Standalone by design. agent-kernel has no hard dependency on any sibling
project — its only runtime dependencies are httpx and pydantic. Use it on
its own, or compose it with the rest of the stack; the siblings interoperate
through the shared weaver-spec
contracts, not through tight coupling. A deeper, per-project comparison —
including when not to reach for agent-kernel — is in
How this relates to neighboring projects.
Quickstart
pip install weaver-kernel
import weaver_kernel
📦 Repo ↔ package ↔ import — read this once
Where you see it Name GitHub repository dgenio/agent-kernelPyPI — what you pip installweaver-kernelPython — what you importweaver_kernelDecision (2026-06): the install name and the import name are unified on
weaver-kernel/weaver_kernel— the two names you actually type. There is noagent_kernelimport any more; useweaver_kernel. The GitHub repo keeps its historicalagent-kernelslug for now (GitHub redirects old URLs); the package is part of the Weaver stack, which is why the distribution isweaver-prefixed. See docs/architecture.md for the full rationale.
New here? docs/tutorial.md walks through register → grant → invoke → expand → explain in five minutes.
import asyncio, os
os.environ["WEAVER_KERNEL_SECRET"] = "my-secret"
from weaver_kernel import (
Capability, CapabilityRegistry,
InMemoryDriver, Kernel, Principal, SafetyClass, StaticRouter,
)
from weaver_kernel.models import CapabilityRequest
# 1. Register a capability
registry = CapabilityRegistry()
registry.register(Capability(
capability_id="tasks.list",
name="List Tasks",
description="List all tasks",
safety_class=SafetyClass.READ,
tags=["tasks", "list"],
))
# 2. Wire up a driver
driver = InMemoryDriver()
driver.register_handler("tasks.list", lambda ctx: [{"id": 1, "title": "Buy milk"}])
# 3. Build the kernel
kernel = Kernel(registry=registry, router=StaticRouter(routes={"tasks.list": ["memory"]}))
kernel.register_driver(driver)
async def main():
principal = Principal(principal_id="alice", roles=["reader"])
# 4. Discover → grant → invoke → expand → explain
token = kernel.get_token(
CapabilityRequest(capability_id="tasks.list", goal="list tasks"),
principal, justification="",
)
frame = await kernel.invoke(token, principal=principal, args={})
print(frame.facts) # ['Total rows: 1', 'Top keys: id, title', ...]
print(frame.handle) # Handle(handle_id='...', ...)
# `principal` is required: the handle is bound to the granting principal,
# so an omitted principal raises HandleConstraintViolation.
expanded = kernel.expand(
frame.handle, query={"limit": 1, "fields": ["title"]}, principal=principal
)
print(expanded.table_preview) # [{'title': 'Buy milk'}]
trace = kernel.explain(frame.action_id)
print(trace.driver_id) # 'memory'
asyncio.run(main())
This snippet is extracted and executed by CI (
tests/test_readme_quickstart.py), and a standalone runnable mirror lives atexamples/readme_quickstart.py(run bymake example). CI fails if either stops producing the documented output, so this quickstart cannot silently drift from the working API.
Where it fits
┌─────────────────────────────────────────────┐
│ LLM / Agent loop │
├─────────────────────────────────────────────┤
│ agent-kernel ← you are here │
│ (registry · policy · tokens · firewall) │
├────────────────┬────────────────────────────┤
│ contextweaver │ tool execution layer │
│ (context │ (MCP · HTTP · A2A · │
│ compilation) │ internal APIs) │
└────────────────┴────────────────────────────┘
agent-kernel sits above contextweaver (context compilation) and above raw tool execution. It provides the authorization, execution, and audit layer.
How this relates to neighboring projects
agent-kernel is the embeddable runtime layer of the Weaver ecosystem. The
projects below solve adjacent problems and are designed to compose, not to
overlap.
| Project | Role | Where it runs | Use it when… |
|---|---|---|---|
| agent-kernel (this repo) | Embeddable library/runtime: capability registry, policy, HMAC tokens, context firewall, audit trace. | In-process inside your agent host. | You need authorization, redaction, and audit between an LLM loop and a large tool ecosystem. |
| AgentFence | External CLI / local proxy that intercepts tool calls and applies a policy gate. | Out-of-process, alongside your agent. | You want a policy boundary without changing your agent code, or you need to gate a third-party agent host you can't modify. |
| contextweaver | Library that selects and compiles the context an LLM receives. | In-process, before the LLM call. | You need to assemble relevant context for a prompt. It sits under the LLM loop; agent-kernel sits between the LLM and tools. |
| ChainWeaver | Orchestrator for deterministic tool chains. | In-process or as a separate service. | You need to run a multi-step deterministic flow rather than free-form LLM tool use. |
| weaver-spec | Specification: invariants, capability/token/frame contracts, conformance suite. | Not a runtime — it's docs + a contract test suite. | You're building another Weaver-compatible implementation, or you want to verify an existing one. |
A minimal architecture using agent-kernel as the central runtime:
LLM / agent loop
│
▼
contextweaver ─► agent-kernel ─► driver ─► MCP / HTTP / A2A / internal API
│
▼
ActionTrace
When not to use this
- You only need a process-level policy gate around an existing agent host —
reach for
AgentFenceinstead. - You only need to compile context for a prompt — use
contextweaver. - You want a deterministic, scripted workflow with no LLM in the inner loop —
use
ChainWeaver. - You're writing a static analyzer or one-shot CLI scanner with no
per-invocation runtime —
agent-kernelwould be overkill.
See docs/tutorial.md for an end-to-end "secure your first MCP tool in 5 minutes" walkthrough.
Weaver Spec Compatibility: v0.1.0
agent-kernel is a compliant implementation of weaver-spec v0.1.0. The following invariants are satisfied:
| Invariant | Description | How agent-kernel satisfies it |
|---|---|---|
| I-01 | LLM never sees raw tool output by default | Context Firewall always transforms RawResult → Frame; raw driver output is not returned by default, and non-admin principals cannot obtain raw response mode |
| I-02 | Every execution is authorized and auditable | PolicyEngine authorizes at grant time; a valid CapabilityToken (HMAC-verified on every invoke()) carries the authorization decision; TraceStore records every ActionTrace |
| I-06 | CapabilityTokens are scoped | Tokens bind principal_id + capability_id + constraints with an explicit TTL; revoke(token_id) / revoke_all(principal_id) are supported |
See docs/agent-context/invariants.md for the full internal invariant list and weaver-spec INVARIANTS.md for the specification.
Security disclaimers
v0.1 is not production-hardened for real authentication.
- HMAC tokens are tamper-evident (SHA-256) but not encrypted. Do not put sensitive data in token fields.
- Set
WEAVER_KERNEL_SECRETto a strong random value in production. If unset, a random dev secret is generated per-process with a warning. - PII redaction is heuristic (regex). It is not a substitute for proper data governance.
- See docs/security.md for the full threat model.
Documentation
Development
git clone https://github.com/dgenio/agent-kernel
cd agent-kernel
pip install -e ".[dev]"
make ci # fmt-check + lint + type + test + examples
License
Apache-2.0 — see LICENSE.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file weaver_kernel-0.10.0.tar.gz.
File metadata
- Download URL: weaver_kernel-0.10.0.tar.gz
- Upload date:
- Size: 232.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f5246926ae3174031f430282904b3f3e92cd8c99574dfd537a059a2b5d3d1b14
|
|
| MD5 |
4ea42dfcc0feb9896ca15c829d66eb5a
|
|
| BLAKE2b-256 |
fb24060c3926bf94e37942da47a424894669d9d152872044752cfbb00d9744d0
|
Provenance
The following attestation bundles were made for weaver_kernel-0.10.0.tar.gz:
Publisher:
publish.yml on dgenio/agent-kernel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
weaver_kernel-0.10.0.tar.gz -
Subject digest:
f5246926ae3174031f430282904b3f3e92cd8c99574dfd537a059a2b5d3d1b14 - Sigstore transparency entry: 1743054962
- Sigstore integration time:
-
Permalink:
dgenio/agent-kernel@1c9400d0feb4ea1902792bdff0ab824041597d10 -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/dgenio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1c9400d0feb4ea1902792bdff0ab824041597d10 -
Trigger Event:
push
-
Statement type:
File details
Details for the file weaver_kernel-0.10.0-py3-none-any.whl.
File metadata
- Download URL: weaver_kernel-0.10.0-py3-none-any.whl
- Upload date:
- Size: 120.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a559e07d2d21f82f2238c0095e62d84536f5f16e1a68c02a7eea3ff65c0dd8bf
|
|
| MD5 |
df9bf4d75bf18750c225a2260766e521
|
|
| BLAKE2b-256 |
8d057b576c465b8719baa52eb2ff5eac3cbdfe289b228b2dad6265f897cc27a8
|
Provenance
The following attestation bundles were made for weaver_kernel-0.10.0-py3-none-any.whl:
Publisher:
publish.yml on dgenio/agent-kernel
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
weaver_kernel-0.10.0-py3-none-any.whl -
Subject digest:
a559e07d2d21f82f2238c0095e62d84536f5f16e1a68c02a7eea3ff65c0dd8bf - Sigstore transparency entry: 1743054994
- Sigstore integration time:
-
Permalink:
dgenio/agent-kernel@1c9400d0feb4ea1902792bdff0ab824041597d10 -
Branch / Tag:
refs/tags/v0.10.0 - Owner: https://github.com/dgenio
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@1c9400d0feb4ea1902792bdff0ab824041597d10 -
Trigger Event:
push
-
Statement type: