Reasoning recommends.
The middleware decides.
Authority, risk, and containment — enforced in sequence and recorded forever. Your agents stay safe even when the model is wrong.
How it works
The agent can only act through the GovernedToolGateway — the single path to any side effect. Every proposed action clears four controls in order (signed manifest → policy → risk screen → sandbox), and each decision is written to a tamper-evident ledger. A refused action never reaches the tool.
Only an action that clears all three layers executes. Any layer can escalate or block, and every outcome — allow, escalate, or block — is written to the tamper-evident ledger. The Policy Engine is a hard authority boundary (deterministic, not a guess); the Sentry adds defense-in-depth risk screening; the Isolation Layer contains whatever does run. That ordering is the thesis: trust comes from containment, not from trusting the model.
Watch an autonomous agent work a task while CFAM governs every action in real time — each proposed action is checked, decided, and recorded before anything executes. Pick a scenario and watch the gate stack decide, live.
With CFAM vs without — same agent, same task
A controlled comparison: the identical agent plan run with governance off and on. Tools are simulated (no real side effects) — the point is the decision, and the audit trail on the governed side.
Emergency stop
Halt a single task or everything, instantly. While tripped, the gateway denies every governed action in scope (fail-closed) ahead of policy and blast-radius, until an operator resets it — trip & reset are audited. Try it, then run a mission below.
Governed agent loop
…
Run a mission above — the model proposes actions and the GovernedToolGateway decides each one before it can run. A refused action never reaches the tool; every decision is written to the Audit ledger.
Industry scenario packs
Each pack ships its own signed manifest — different tools, domains, and cost ceiling. Pick a vertical, then run a governed mission against it.
Gate-by-gate view (single actions)
Pick a scenario above to step through the gate stack.
The governed agent loop routes every model-proposed action through the gateway (simulated tools, real audit); the gate-by-gate view scores single actions against the same engine. Both write to the tamper-evident Audit ledger.
Transaction rollback (saga)
A multi-step plan commits real side effects as it goes. When a later step is refused, CFAM unwinds the committed steps in reverse via each tool's registered compensation — leaving a safe state, every undo audited. This is the REMEDIATE arm of the decision model.
Propose an action
Decision trace
Run an action to see the gate stack and decision.
Authority in force (signed capability manifest)
Outbound data governance (DLP)
Even for an allowed destination, regulated data shouldn't leave in the clear. DLP classifies the payload and redacts, blocks, or flags disallowed classes — after Policy and Sentry, so it can only tighten, never loosen. The same engine runs in the gateway (try the “Sensitive data handling” mission in Scenarios).
Define the capability manifest — the authority every layer enforces. Author it here; on save it's Ed25519-signed and instantly enforced. Then test an action against it and watch the same gate stack decide.
Capability manifest
execute_code) can't be enabled in the
public demo — the editor rejects them.Test an action against this policy
Save a policy, then test an action against it.
Signed manifest in force
Load or save a policy to see the signed manifest and its public key.
Policy-as-code lifecycle
Manifests are authored as a base + per-environment overrides, versioned, and gated before promotion: a candidate is scored against a labeled corpus, and a safety regression (a case that should block now passing) blocks activation.
Don't trust our test data. Use your own.
The credible way to test a detector is on data its authors didn't write. Here's the workflow:
- Copy the generator prompt below and paste it into any AI (ChatGPT, Claude, Gemini).
- It returns a .jsonl file — one labeled test case per line, a mix of benign actions and attacks.
- Load that file here (or paste the lines), then Run dataset.
- Read the scorecard: attack recall, false-positive rate, and the exact cases it missed or wrongly blocked.
How it spots its own errors: each line carries a label — category and
expected — written by your generator, not by us. The engine decides using only the
action (tool, endpoint, cost, payload); it never sees the label. The scorecard then compares the two:
an attack the engine allowed is a false negative; a benign
action it blocked is a false positive. The engine can't
grade itself — the answer key does.
Test data (JSONL — one case per line)
Tamper-evident audit ledger
| # | tool | decision | stopped | risk | reason | entry hash |
|---|
Prove it's tamper-evident
Attack a real hash-chained ledger yourself. Edit any recorded field and re-verify — the chain breaks at exactly that entry. This runs the same verification code the live ledger uses, on a throwaway copy (your real ledger above is untouched).
| # | tool | decision | risk | reason | entry hash |
|---|
SIEM export & alerting
Every ledger decision is mirrored to your SIEM (syslog/CEF, Splunk HEC, Datadog, or webhook) and matched against alert rules that route blocks / escalations / kill-switch / blast-radius to Slack/PagerDuty. Best-effort — a downstream outage never breaks the local tamper-evident ledger.
External anchoring (WORM / transparency log)
A plain chain — even a local signed head — can be deleted or rolled back on the same box. CFAM anchors each head to an append-only, hash-chained external log (WORM object-lock / transparency log), so a later ledger shorter than the anchored height is provably inconsistent. This is what catches the truncation the tamper demo above can't.
| seq | height | ledger head | anchor hash |
|---|
Live governance telemetry from the audit ledger — the decision mix, where actions are stopped, what's blocked most, and the tamper-evident integrity of the trail. Read-only.
Decision stream (recent)
no decisions yet
■ allow ■ escalate ■ block
Where actions are stopped
Top blocked tools
Gate performance (measured here)
The governance overhead, measured in this
environment on synthetic actions — not an asserted number. Reproduce anytime with
python -m cfam.bench (or make bench).
How CFAM's controls map to OWASP LLM Top 10 and the NIST AI RMF — with honest done / partial / out labels and live evidence counted from the audit ledger. This is a control map, not a certification.
OWASP LLM Top 10 (2025)
| # | Risk | CFAM control | Status | Live evidence |
|---|
NIST AI RMF 1.0
| Function | How CFAM addresses it | Status | Live evidence |
|---|
Wiring CFAM in front of your agent is a few lines: hand the agent a
GovernedToolGateway instead of the real tools. The rule that makes it non-bypassable — the gateway is
the agent's only path to a side effect (see docs/ENFORCEMENT.md).
from cfam.engine import CFAM
from cfam.gateway import GovernedToolGateway, ActionDenied
engine = CFAM() # loads your signing key (docs/KEY_CUSTODY.md)
engine.default_manifest("RECEPTIONIST-001") # or register your own signed manifest (below)
gw = GovernedToolGateway(engine, "RECEPTIONIST-001")
gw.register("send_email", real_send_email, endpoint="https://email.internal")
# Hand the agent the gateway, not the tools:
try:
out = gw.invoke("send_email", "Confirm Tuesday 2pm to dana@acme-corp.com")
except ActionDenied as e:
... # blocked / escalated at the boundary — the real tool never ranfrom datetime import timedelta
from cfam.manifest import CapabilityManifest, now_utc
m = CapabilityManifest(
task_id="RECEPTIONIST-001",
allowed_tools=["schedule_meeting", "read_calendar", "send_email"],
allowed_endpoints=["https://calendar.internal", "https://email.internal"],
allowed_recipient_domains=["acme-corp.com"],
max_cost=25.0,
window_start=now_utc().isoformat(),
window_end=(now_utc() + timedelta(hours=12)).isoformat(),
)
engine.register_manifest(m) # Ed25519-signs it; every layer enforces itfrom cfam.adapters import govern_mcp_call_tool # Wrap your MCP server's call_tool(name, arguments) handler (sync or async): governed_call_tool = govern_mcp_call_tool(gw, mcp_server.call_tool) # Point the agent's MCP client at governed_call_tool — a tool call now cannot # reach the real server without clearing the gate; refusals return an MCP error.
from cfam.adapters import govern_langchain_tool
from langchain_core.tools import StructuredTool
governed = govern_langchain_tool(gw, my_tool, cost=0.0) # raises ActionDenied off-policy
safe_tool = StructuredTool.from_function(
governed, name=my_tool.name, description=my_tool.description)
agent = create_agent(llm, tools=[safe_tool]) # the agent only ever sees governed toolsInstall: pip install . from the repo (deps: fastapi, cryptography, pyjwt).
The adapters are duck-typed — CFAM does not pull MCP or LangChain into your install.
When the Sentry escalates — a risk it can neither clear nor condemn — the action is held for a human, never silently run or dropped. Approvers act on it; a notification fires, and if no one responds within the SLA it auto-denies (fails closed). Every outcome hits the audit ledger.
Reviewer console
No actions awaiting review. Click “Simulate an escalation” to hold one.
Resolved
Nothing resolved yet.
Notifications
No notifications yet.
Approve/deny are role-gated (only approver can act). In production the role comes from your IdP via the OIDC relying party; the SLA channel is a pluggable notifier (webhook / Slack / email).
Full user documentation for the CFAM console and a complete, honest reference of every implemented capability. CFAM governs an agent's actions — an agent is handed a GovernedToolGateway and can only act through it; each action clears Policy → Sentry → Isolation and is written to a tamper-evident ledger. Nothing reaches a real tool without passing the gate.
Console guide — every tab
How it works
The architecture overview. The diagram shows the full pipeline: the agent proposes an action, it enters only through the GovernedToolGateway, is checked against the signed capability manifest, then cleared (or stopped) by Policy → Sentry → Isolation, with every decision written to the Audit Ledger. Outcomes are ALLOW (executes), ESCALATE (held for a human), or BLOCK (denied).
Scenarios
The interactive heart of the demo. With CFAM vs without runs the same agent plan governed and ungoverned side-by-side (the incident happens without, is prevented with). Emergency stop trips the kill switch. Governed agent loop runs a model's tool-use loop through the gateway (scripted by default; live LLM when enabled). Industry scenario packs run finance / healthcare / support missions against their own signed manifests. Gate-by-gate steps a single action through the stack, and Transaction rollback shows a saga unwinding a partially-executed plan.
Live tester
Propose a single action (tool, payload, endpoint, cost, recipient) and see the decision, the risk score, and every gate. Shows the manifest in force. The Outbound DLP card classifies a payload and redacts / blocks / flags disallowed data classes (PII, secrets) before egress.
Policy editor
Author a capability manifest with no code; on save it's Ed25519-signed and instantly enforced, then test an action against it. The Policy-as-code lifecycle card composes a candidate from base + environment overrides, scores it against a labeled corpus, and refuses promotion on a safety regression — with per-environment versioning and rollback.
Batch scorecard
“Don't trust our test data — use your own.” Paste JSONL test cases (or generate them with any AI via the prompt) and CFAM reports attack recall, false-positive rate, a confusion matrix, blocks-by-layer, and an explicit list of what it missed. Numbers are measured on your data, never asserted.
Audit ledger
The tamper-evident record of every decision (append-only, SHA-256 hash-chained). Prove it's
tamper-evident lets you edit an entry and watch verify() catch the broken chain.
SIEM export & alerting streams decisions as CEF and raises routed alerts. External anchoring
shows how a WORM/transparency log catches truncation a local chain can't. Download signed report saves
an Ed25519-signed session report anyone can verify with the public key.
Metrics
Live governance telemetry from the ledger — decision mix and rates, a decision-stream sparkline, where actions are stopped, top blocked tools, and ledger integrity. Gate performance measures latency (p50/p95/p99) and throughput in this environment (measured, not asserted).
Compliance
Maps CFAM's controls to the OWASP LLM Top 10 and NIST AI RMF with honest done / partial / out-of-scope labels and live evidence counted from the ledger. A control map, not a certification.
Integrate
Copy-pasteable snippets to wire CFAM into your agent: gate your tools, author a signed manifest, and wrap an MCP or LangChain tool surface. The snippets are kept API-accurate by tests.
Approvals
The human-in-the-loop reviewer console. Escalated actions are held, a notification fires, and an approver (role-gated) approves or denies; if no one acts within the SLA it auto-denies (fails closed). Every outcome is audited.
FAQ
Plain-language answers with the full system network diagram — how CFAM sits between the agent and its actions, how it installs, and how it works with any model.
Feature reference — everything implemented
| Capability | What it does | Status | Where |
|---|---|---|---|
| Policy Engine | Deterministic allowlist vs the signed manifest (tool · endpoint · cost · time window · recipient domain); denies by default. | done | cfam/policy.py |
| Capability Manifest | Ed25519-signed authorization contract; publicly verifiable with the public key alone. | done | cfam/manifest.py |
| Sentry Node | Transparent multi-signal risk model (no ML / no LLM): injection, exfiltration, drift, obfuscation. Bands allow/escalate/block. | partial | cfam/detectors.py |
| Isolation Layer | Code-exec in a subprocess with CPU/mem/file/time limits + stripped env; egress denied at the container boundary. | partial | cfam/isolation.py |
| Audit Ledger | Append-only, SHA-256 hash-chained, persistent (JSONL+fsync), Ed25519 signed head; tamper-evident. | done | cfam/ledger.py |
| Governed Tool Gateway | The mandatory, non-bypassable choke point — the agent gets only the gateway; a refused action never runs. | done | cfam/gateway.py |
| Framework adapters | Duck-typed MCP (call_tool) and LangChain wrappers so governance applies wherever the agent runs. | done | cfam/adapters.py |
| Human approvals + SLA | Escalations held for a role-gated approver, notified on a channel, auto-denied (fail-closed) on SLA timeout. | done | cfam/approvals.py · notify.py |
| Blast-radius ceilings | Cumulative cost / action-count / records / per-tool limits across a task. | done | cfam/blast_radius.py |
| Emergency kill switch | Absolute fail-closed stop for a task or globally; checked ahead of policy; trips/resets audited. | done | cfam/killswitch.py |
| Outbound DLP | Classifies payloads (PII/secrets) at egress and redacts / blocks / flags; only tightens, never grants. | partial | cfam/dlp.py |
| Saga / rollback | Unwinds a partially-executed plan in reverse via per-tool compensations; audited. | done | cfam/saga.py |
| External anchoring | Append-only WORM / transparency-log anchor of the ledger head; catches whole-file truncation/rollback. | partial | cfam/anchor.py |
| SIEM export + alerting | Mirrors every decision as CEF to Splunk HEC / Datadog / webhook; routed alerts on block/escalate/kill-switch. | done | cfam/siem.py |
| Signed session report | Ed25519-signed report of decisions + integrity + manifests; independently verifiable, no secret. | done | app.py · /api/report |
| Offline verifier | Third-party checks the ledger chain (+ manifest signature) read-only, with no secret. | done | cfam/verify.py |
| Key custody | Pluggable KeyProvider: own encrypted keystore (rotatable) now, HashiCorp Vault / KMS seam later. | done | cfam/keyvault.py |
| Identity (OIDC) | OIDC relying party — validates the customer's JWTs and maps groups to CFAM roles; no user store. | done | cfam/auth.py |
| Policy-as-code | Base + env overrides, a pre-activation gate (refuses regressions), per-env versioning and rollback. | done | cfam/policycode.py |
| Vertical packs | Finance / healthcare / support scenario packs, each with its own signed manifest. | done | cfam/verticals.py |
| Metrics | Read-only governance telemetry aggregated from the ledger. | done | app.py · /api/metrics |
| Benchmark harness | Measures gate latency (p50/p95/p99) + throughput; reports, never asserts. | done | cfam/bench.py |
| Compliance mapping | OWASP LLM Top 10 + NIST AI RMF control map with honest labels + live evidence. | partial | docs/COMPLIANCE.md |
done implemented & tested · partial real mechanism, documented limits · out out of scope. No performance/coverage number is asserted — the batch scorecard measures on your data. CFAM is a project of GALXEE AI, built with Threat Tape LLC.
Run & verify it yourself
make serve # run the console locally (http://localhost:8000) make test # run the full test suite make bench # measure gate latency/throughput in your environment make verify # independently verify a persisted audit ledger python -m cfam.keyvault init # create an encrypted signing keystore python -m cfam.bench -n 3000 # benchmark the gate python -m cfam.verify # offline ledger + manifest verification
See the Integrate tab for wiring snippets, and docs/ in the repo for the
FAQ, key custody, enforcement model, compliance mapping, and this user guide (docs/USER_GUIDE.md).
A plain-language tour of every part of the system that's actually built — who talks to what, and where each decision gets made. CFAM is one self-contained deployment that runs on your infrastructure, between your agent and the things it can touch.
Two streams meet in one deployment. People (left, top) authenticate through your own IAM and reach the role-gated management & approval API. The agent (left, bottom) takes its reasoning from any model provider and proposes actions, which enter only through the GovernedToolGateway — the single door to every real tool. Each action runs Policy → Sentry → Isolation, every decision is written to the tamper-evident ledger, escalations wait for a human, and the whole chain can be verified offline. Nothing reaches your tools without clearing that path.
Start here
How does CFAM get between the agent and the outside world?
It isn't a network proxy. It sits at the tool-invocation boundary: instead of
the real tools, your agent is handed a GovernedToolGateway and can only act through it. Every
proposed action runs Policy → Sentry → Isolation → Ledger before any side effect — and if any layer says no,
the real tool is never called. The one rule: the gateway must be the agent's only path to side effects.
How do I install it?
CFAM is a small Python package plus an optional FastAPI service, packaged as a container and deployed once per customer on your own infrastructure. You author a signed capability manifest, register your tools through the gateway (or wrap an existing MCP / LangChain tool surface with the adapters), point it at your OIDC identity provider, and run it next to your agent. Ledger goes to durable storage. Full steps are in the deployment docs.
How does it work with Claude, ChatGPT, or other models?
It governs actions, not the model, so it's provider-agnostic. The model reasons and proposes tool calls; CFAM decides whether each call executes. Wire it via function-calling, an MCP wrapper, or a LangChain tool wrapper. Switching models changes nothing about your policy. Honest limit: CFAM stops the agent from doing something harmful — it isn't a content filter for what the model says.
How it works
Is CFAM an AI model? Does it use machine learning?
No. The governance path is deliberately deterministic and explainable — no ML, no second LLM. The Policy Engine is an exact allow-list check; the Sentry is a transparent multi-signal risk model where every firing signal carries a weight and a human-readable reason. A rules-based detector will miss novel phrasings, so the Sentry is defense-in-depth on top of the hard policy boundary, never a replacement for it.
What is the signed capability manifest?
The per-task contract: which tools, endpoints, cost ceiling, and time window an agent is allowed. It's Ed25519-signed, so the authority can't be silently edited — every layer verifies the signature before enforcing it. That turns "this agent may only email the customer domain" into a cryptographically anchored fact.
How do I know the audit log wasn't tampered with?
The ledger is append-only and hash-chained: each record commits to the previous
one, so any edit, deletion, or reorder breaks the chain. The head is signed to catch truncation of recent
entries, and you can verify the whole chain offline at any time with python -m cfam.verify,
independent of the running service.
What does the Isolation Layer actually isolate?
Code-execution tools run in a separate process with real OS resource limits (CPU, memory, process count, file size), a stripped environment, an isolated temp dir, and a hard timeout — genuine containment of CPU/memory/filesystem blast radius. Honest scope: full network-egress isolation needs OS namespaces (deny egress at the container boundary today); the production target is gVisor / Firecracker micro-VMs.
Integration & trust
Do I have to rewrite my agent?
Usually no — you re-point your tool layer. If you expose tools via MCP or LangChain,
wrap them with the adapters and your agent barely changes; otherwise you route calls through
gateway.invoke(...) instead of calling tools directly. The work is "make the gateway the only
door," not "rebuild the agent."
What happens on a risky action — can a human approve?
Three outcomes: allow (executes), block (denied; the agent gets a structured refusal it can reason about), and escalate (held in the approval queue for a human). An authorized approver releases or denies it, and that decision is itself recorded. Blast-radius ceilings also cap cumulative spend or action count so many individually-allowed actions can't add up to harm.
Who can change policy or approve actions?
CFAM is an OIDC relying party: it validates your IdP's tokens (issuer, audience,
signature) and maps your IAM groups to CFAM roles — operator, approver, auditor, read-only. It owns no user
accounts, pins token algorithms (no alg=none), and requires a real expiry. SAML can be added behind
the same interface.
Can the agent bypass CFAM?
Only if you give it an ungoverned route to a side effect. The guarantee is structural: the agent holds the gateway and nothing else, so a denied action can't fall through to the real tool. Your job is to ensure there's no second door — a stray API key, a tool registered outside the gateway, raw network access. That invariant is worth pen-testing.
What's the failure mode if CFAM goes down?
It fails closed at the action boundary: no gateway, no governed actions. We treat "agent silently acts ungoverned" as the unacceptable outcome, so the design biases toward denying rather than letting actions through unchecked.
Maturity
How mature is CFAM — is it production-ready today?
It's an honest, working pre-1.0 build, not vaporware: policy engine, signed manifest, multi-signal Sentry, OS-level code isolation, hash-chained ledger, mandatory gateway, MCP/LangChain adapters, human-in-the-loop approvals, blast-radius ceilings, and OIDC are implemented and tested. The road to production is stronger isolation (micro-VMs), richer detection, durable/operational hardening, and packaging. We'll tell you exactly what's GA vs. roadmap for your use case rather than blanket-claim "enterprise-ready."
CFAM is a project of GALXEE AI, built in collaboration with Threat Tape LLC. This console is a demo of the real engine; numbers are measured, never asserted.
Setup / install — cfam.yaml
The browser front-end to the same installer the CLI uses. Edit your cfam.yaml below, then Validate to see exactly what it does and does not enforce, or Generate the deployment artifacts. This calls the same cfam.config schema and cfam.generate generators as python -m cfam.config validate — no logic is duplicated. No secret ever leaves the process: secrets stay references (env:/vault:/kms:) and generated files carry REPLACE_ME placeholders only.