Governance
Rules a laptop cannot argue with.
Decide centrally which MCP servers and which tools each team may use. The policy is signed with your key and checked on every call, so editing it locally does not widen access — it revokes it.
kosa8 mcp-policy check github list_issues allowed: allowed by rule allow_tools "list_*" kosa8 mcp-policy check github delete_repo DENIED: denied by rule deny_tools "delete_*" # edit the policy file on this laptop and: kosa8 mcp-policy check github list_issues DENIED: the installed MCP policy failed verification: signature does not match (tampered or wrong key)
How it holds
Three properties, each of which is the point.
A policy is a file you can read.
Scopes, servers, and glob rules for which tools each scope may call. mcp-policy init prints a working template to edit.
kosa8 mcp-policy init { "name": "example-corp", "default_scope": "engineering", "scopes": [{ "name": "engineering", "servers": [{ "server": "github", "allow_tools": ["list_*", "get_*", "search_*"], "deny_tools": ["*_delete", "delete_*"] }] }] }
Tamper with it and it stops working.
The active policy is verified against your organisation's public key before every decision. A local edit breaks the signature, and a broken signature denies — it does not fall back to allowing.
# a policy that verifies kosa8 mcp-policy check github list_issues allowed: allowed by rule allow_tools "list_*" # one byte changed in the installed policy kosa8 mcp-policy check github list_issues DENIED: the installed MCP policy failed verification: signature does not match (tampered or wrong key) ↑ it denies. It does not fall back to allow.
Every decision, in a format your SIEM already reads.
Each check is written to a sealed record with an event id, and exports as JSONL or CEF. The record lives on the machine, so you can recount it and nobody can quietly amend it.
SIEM export →kosa8 mcp-policy check github list_issues allowed: github/list_issues for scope engineering event: 30df5d9210b5c8967046e43c1c54f3f60e1156a2d54d0f3cc… kosa8 mcp-policy events --format cef | head -1 CEF:0|kosa8|kosa8|1|mcp.tool.allow|mcp.tool.allow|2|rt=2026-07-30T00:26:14Z suser=human act=mcp.tool.allow dst=github/list_issues outcome=allow cs1Label=scope cs1=engineering cs2Label=rule cs2=allow_tools cs4=30df5d92…
Honest about it
What this does not do.
It governs MCP, not everything
The policy covers which MCP servers and tools an assistant may call. It is not a network firewall and not a device-management product.
It is client-side enforcement
Signature checking happens on the machine. That defeats a careless edit and an assistant going off-script; it does not defeat someone with root who is determined to run a patched binary.
You hold the key
Signing uses your own ed25519 key. There is no kosa8 service in the loop, which also means there is nobody to ask if you lose it.
Write it once, sign it, ship it.
The template is one command, and it is a plain JSON file you can read.