MCP server that fronts an OpenID AuthZEN 1.0 PDP.
Sends a subject + resource + action + context bundle to a real Policy Decision Point (OPA-AuthZEN, Topaz, your own) and returns the decision. Use it when "can alice delete this?" should be answered by policy code, not by the model's guess.
Conforms to AuthZEN 1.0 §6 (single-evaluation request/response) and §5.5 (decision entity). Batch evaluation (§7) is not yet exposed as a tool — file an issue if you need it.
go install github.com/0-draft/mcp-authzen@latestPre-built signed binaries are on the releases page.
# Point at a real PDP (or your local opa-authzen-plugin on :8181)
export AUTHZEN_PDP_URL=http://localhost:8181/access/v1/evaluation
# Optional: PDP behind auth. Bare values are auto-prefixed with "Bearer ";
# values starting with "Bearer " or "Basic " pass through verbatim.
# export AUTHZEN_PDP_TOKEN=eyJhbGciOi...
# Run the smoke test (spins up an in-process fake PDP, exercises the
# full MCP handshake, asserts the decision is forwarded correctly)
make smokeAUTHZEN_PDP_URL=http://localhost:8181/access/v1/evaluation \
claude mcp add authzen -- mcp-authzenThen in a session:
Can
alice(role=admin)deletedoc-42(owner=bob)?
The model builds the AuthZEN bundle, calls authzen_evaluate, returns the PDP's decision.
| Param | Required | Description |
|---|---|---|
subject |
yes | JSON object. AuthZEN §5.1, e.g. {"type":"user","id":"alice"}. |
resource |
yes | JSON object. AuthZEN §5.2, e.g. {"type":"doc","id":"doc-1"}. |
action |
yes | JSON object. AuthZEN §5.3, e.g. {"name":"read"}. |
context |
no | JSON object with runtime context. AuthZEN §5.4. |
pdp_url |
no | Override AUTHZEN_PDP_URL for this call. |
Returns AuthZEN's {"decision": <bool>, "context": {...}} as JSON.
kanywst/opa-authzen-plugin is a reference AuthZEN PDP built on OPA.
# In one terminal — start the PDP on :8181
git clone https://github.com/kanywst/opa-authzen-plugin
cd opa-authzen-plugin && make run
# In another — wire mcp-authzen
export AUTHZEN_PDP_URL=http://localhost:8181/access/v1/evaluation
mcp-authzenFlat by design. A single-binary MCP server with one tool does not need
cmd/, internal/, or pkg/. When batch (/access/v1/evaluations) or
the search APIs (§8) land, they get sibling files, not subpackages.
.
├── main.go # server bootstrap + tool registration
├── main_test.go # httptest-driven PDP round-trips
├── scripts/smoke.sh
├── .goreleaser.yml
└── .github/
Releases ship a cosign-signed checksum file (Sigstore keyless via GitHub OIDC) and a CycloneDX SBOM per archive.
TAG=v0.1.0
gh release download "$TAG" -R 0-draft/mcp-authzen -p '*-checksums.txt*'
cosign verify-blob \
--certificate "mcp-authzen-${TAG#v}-checksums.txt.pem" \
--signature "mcp-authzen-${TAG#v}-checksums.txt.sig" \
--certificate-identity-regexp 'https://github.com/0-draft/mcp-authzen/.github/workflows/release.yml@refs/tags/' \
--certificate-oidc-issuer 'https://token.actions.githubusercontent.com' \
"mcp-authzen-${TAG#v}-checksums.txt"MIT.
{ "mcpServers": { "authzen": { "command": "mcp-authzen", "env": { "AUTHZEN_PDP_URL": "http://localhost:8181/access/v1/evaluation" } } } }