identity for every agent · redacted logs · a database that refuses
Every agent leaves a log line. This one can't lie.
a-guard gives an MCP resource server a real OpenID Connect authorization server, redacts PII out of every record at creation, and lets Postgres itself refuse the destructive call. Below is one real round trip, replayed.
Replayed sequence: an agent presents a token minted for the REST API; the MCP endpoint rejects it with 401 and reason mcp.auth.reject; the agent re-mints for the MCP audience; a log line containing an email address and a card number is redacted character by character before it can be stored; the agent's DELETE is refused by Postgres row-level security and column grants — rows=0, nothing changed — and the attempt is recorded in the audit log.
Three guarantees, three layers of truth
One identity surface for every agent. No SDK secrets. No audit trail you can't verify.
OpenID Connect, audience-bound
The resource server verifies every token against the AS's public JWKS — it holds no signing key. A token minted for /api is refused at /mcp. That's the mcp.auth.reject you watched above.
PII never leaves the service
Every log record is redacted at creation — not at read time, not by a filter you can forget to enable. Raw identities, cards, and tokens stay inside; they never reach the agent's context window.
The database says no
Row-level security, column grants, and a separate agent pool mean an agent's delete is refused by Postgres itself. Not middleware. rows=0 — nothing changed.
Try the redactor — it's live
This button calls POST /redact on this deployment: the same engine that redacts the service's own logs, with no OAuth needed to try it.
paste anything — an access log, a support ticket, a token
what the log keeps
— run it —
rate-limited per IP · counts only — the endpoint never echoes your input into its own logs, so the playground can't become the leak it exists to prevent.
See it in one command
Both services, a real MCP client, and the audit trail where rows=0 is the agent's refused delete.
Runs the AS and the resource server, registers a client, walks the full browser flow, and replays the refused delete. Leave the services up with DEMO_KEEP=1.
rows=0 is the refusal
The agent's delete is swallowed by Postgres. The audit log records the attempt — and nothing changed.