Bouncer
Carrier integration for GitHub Issues that allows only posting comments to an issue. It uses an isolated process with a hard-coded allowlist for POST /repos/{owner}/{repo}/issues/{issue_number}/comments and rejects non-comment issue modifications.
Read-only integration for reading Notion content, tasks, and comments, plus a constrained carrier integration for inserting human-approved comments only. It is designed to prevent property updates such as owner, due date, or status changes at the credential level.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Bouncerreport the open tasks in Notion"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Bouncer: Permission-Bounded MCP Server & Agent Registry
A permission-bounded Model Context Protocol (MCP) server and agent registry where the forbidden write has no code path, proven by automated credential audits and prompt-injection red-team tests.
1. Core Security Thesis & Objective
Build agent governance that is enforced by structure, not by instructions in a prompt.
The Rule: An agent may read and report, may carry a human-authored update into a system of record after a human consents, but may never autonomously write a commitment (an owner, a due date, a status) into a shared work system.
Bouncer makes that last part impossible: The tool does not exist, and the credential behind it cannot do it either.
"Prompt injection cannot produce a forbidden write, because no tool and no credential in the agent's grant can perform it. I can show you the audit that proves it."Related MCP server: enterprise-agent-lab
2. Architecture Overview
flowchart TD
subgraph Untrusted_Zone ["Untrusted LLM Agent"]
Agent["Agent (LLM Loop)\n- Susceptible to Prompt Injection\n- Per-Agent Bearer Token"]
end
subgraph Human_Zone ["Human Review Gate"]
Human["Human Reviewer\nCLI: bouncer issue-consent"]
Token["Signed Consent Token\nsha256(text) + target + nonce + 10m TTL"]
Human -->|Issues| Token
end
subgraph Bouncer_Core ["Bouncer Governance MCP Server"]
Gate["1. Identify Agent from Bearer Token"]
Filter["2. list_tools(): Dynamic Tool Surface\n(Only granted tools returned; forbidden tools hidden)"]
Authz["3. authorize(agent, tool, args)\nEnforces Tier Policy"]
Audit["4. Append-Only Decision Audit Log\n(SQL Triggers + Hash Chained prev_hash)"]
Gate --> Filter --> Authz --> Audit
end
subgraph Execution_Boundary ["Structural Execution Boundary"]
ReadTool["Read Tools (read_tasks, read_task, read_comments)"]
CarryTool["Carry Tool (post_human_authored_comment)\n- Verifies sha256(text)\n- Verifies Agent & Target Match\n- Atomically Consumes Nonce\n- Zero params for owner/date/status"]
end
subgraph Work_Systems ["System of Record"]
NotionRO["Notion Read-Only Integration\n(Capability: Read Content ONLY -> Proven 403 on update)"]
NotionCarrier["Notion Carrier Integration\n(Capability: Insert Comments ONLY)"]
GitHubCarrier["GitHub Issues Carrier Client\n(Allowlist: POST /issues/{id}/comments ONLY)"]
end
Agent -->|Invokes MCP| Gate
Token -.->|Supplied by Agent| CarryTool
Authz -->|Allowed Read| ReadTool
Authz -->|Allowed Carry| CarryTool
ReadTool -->|Read Credential| NotionRO
CarryTool -->|Carrier Secret| NotionCarrier
CarryTool -->|Allowlisted Transport| GitHubCarrier3. Risk Tiers Enforced by Bouncer
Every agent in the registry must be explicitly categorized into one of four risk tiers. Incomplete entries fail validation immediately:
Tier | Meaning | Allowed Tools | Review & Human Evidence Required |
| Read-Only Internal |
| Registered owner; eval suite recommended; zero write tools |
| Draft Producer | Read tools + | Eval suite with safety test cases required |
| Carries Human Update | Read tools + | Cryptographic consent token on every write; eval gate green |
| External Output | Read tools, carry tool, | Human approves each action; budget limits; strict eval gate |
Hard Invariant Rule: No tier may ever include a tool from the forbidden write set (
set_owner,set_due_date,set_status,update_property,update_any_property,assign,delete_page,delete_issue). The registry validator strictly fails CI on the mere presence of such a name in any grant.
4. Threat Matrix & Structural Controls
Full details are documented in docs/threat-model.md.
# | Forbidden Outcome | Attack Path | Structural Control | Verification Proof |
1 | Agent sets owner, due date, or status | Prompt injection in task text, model error, tool misuse | No such tool exists; credential has no update capability; audit proves 403 | Automated credential audit ( |
2 | Agent posts text a human never approved | Model edits text after human approval | Consent token cryptographically binds |
|
3 | Consent token reused (Replay attack) | Replay of intercepted token | Single-use nonce atomically stored in database, 10-minute short expiry |
|
4 | Agent uses another agent's powers | Stolen or guessed token | Per-agent bearer credentials, tool list filtered dynamically by identity, |
|
5 | Unregistered agent runs | Unreviewed agent launched informally | Server strictly refuses unknown identities; CI fails on incomplete registry entries |
|
6 | Silent policy change | Edit permissions without review | Registry stored in YAML under version control, |
|
7 | Audit log tampering | Rogue agent or operator deletes rows | Append-only database triggers (prohibiting UPDATE/DELETE), cryptographic hash chaining ( |
|
5. Automated Credential Audit Results
To prove that governance is enforced at the credential layer, Bouncer runs an automated credential audit script (scripts/audit_credentials.py) that attempts every forbidden operation across every registered agent:
======================================================================
BOUNCER CREDENTIAL AUDIT ENGINE: TESTING STRUCTURAL RESTRICTIONS
======================================================================
Total Registered Agents Audited: 4
Forbidden Operations Tested per Agent: 5
Total Forbidden Attempts: 20
Total Blocked at Work System API: 20
Protection Rate: 100.0% (Structurally Impossible)
======================================================================Agent ID | Tier | Credential Ref | Forbidden Operations Tested | Blocked | Enforced Result |
| T0 |
| 5 | 5 | PASS (100% Blocked - 403) |
| T1 |
| 5 | 5 | PASS (100% Blocked - 403) |
| T2 |
| 5 | 5 | PASS (100% Blocked - 403) |
| T3 |
| 5 | 5 | PASS (100% Blocked - 403) |
Full report committed at audit/credential-audit.md.
6. Notion vs. GitHub Carrier Pattern Comparison
A critical design consideration when building Bouncer was the disparity in permission models between work systems:
Notion (Credential-Level Restriction):
Notion separates Read content, Insert comments, and Update content into discrete integration capabilities. A Notion token granted Read + Comment capabilities structurally receives a403 RestrictedObjectErrorwhenever attempting a property update.GitHub Issues (Code-Level Carrier Wrapper):
GitHub's fine-grained permission needed to comment on an issue (Issues: write) also permits changing assignees, milestones, labels, and state. Because GitHub does not offer a comment-only credential, Bouncer places that credential strictly inside an Isolated Carrier Process whose HTTP transport is bounded by a hard-coded regex allowlist:POST /repos/{owner}/{repo}/issues/{issue_number}/comments
Any non-comment request (e.g.PATCH /repos/.../issues/...) is intercepted and rejected withCarrierAllowlistViolationErrorbefore touching the network.
See docs/adr/0001-why-notion-primary.md and docs/adr/0002-carrier-pattern-for-github.md.
7. Quickstart & CLI Commands
1. Installation
git clone https://github.com/Harsh-karn/Bouncer-permission-bounded-MCP-server-and-agent-registry-.git
cd Bouncer-permission-bounded-MCP-server-and-agent-registry-
uv venv
source .venv/bin/activate # Or on Windows: .venv\Scripts\activate
uv pip install -e ".[dev]"2. Validate Agent Registry
Validate agent definitions against tier rules and ensure no forbidden tools are granted:
bouncer validate --path registry/agents.yaml3. Human Review Gate: Issue Consent Token
Interactively inspect proposed text, calculate its cryptographic hash, and sign a single-use token:
bouncer issue-consent --agent status-reporter --target task-101 --text "Deployment verified on production."4. Query Append-Only Decision Audit Log
Inspect decisions and verify cryptographic hash chain integrity:
bouncer audit --agent weekly-digest --since 7d --verify5. Run Full Test Suite & Red-Team Attacks
# Run all 75 unit, architecture, and invariant tests
pytest -v
# Run the 12-payload adversarial prompt-injection suite
pytest -v tests/redteam/test_injection.py
# Run live credential audit script
python scripts/audit_credentials.py8. Architecture Decision Records (ADRs)
9. Interview Talking Points & Resume Bullets
Resume Bullets
Authored an MCP governance server with risk-tiered, least-privilege tool grants, ensuring AI agents cannot write commitments (owners, due dates, statuses); verified by automated credential audits and 12 prompt-injection red-team payloads with zero successful writes.
Designed a cryptographic human review gate using signed, single-use tokens bound to a SHA-256 hash of the exact human-approved text, preventing post-approval text tampering, target confusion, and replay attacks.
Built an agent registry and validator enforcing owner, risk tier, tool grant, and human gate for every agent, backed by an append-only decision audit log with cryptographic hash chaining (
prev_hash) queryable per agent.
Key Questions & Answers
Q: Why is a prompt instruction not enough?
A: Prompt instructions fail against jailbreaks, direct injection, and indirect data poisoning. In Bouncer, governance is structural: the forbidden write tool does not exist on the protocol surface, and the agent's credentials lack write capabilities at the API layer.Q: What stops the carrier from being abused if the agent is compromised?
A: The carrier only accepts calls accompanied by an unexpired, cryptographically signed token issued by a human reviewer. The token bindssha256(text)and target ID, and its single-use nonce is atomically consumed upon first execution, preventing modification or replay.Q: How does Bouncer handle work systems without fine-grained scopes?
A: For coarse APIs like GitHub (Issues: write), Bouncer encapsulates the credential within an isolated Carrier client whose HTTP transport is constrained by a strict regex allowlist admitting onlyPOST .../issues/{id}/comments.
License
This project is licensed under the MIT License.
This server cannot be deployed
Maintenance
Related MCP Connectors
Read-only finance and operations controls for AI agents with evidence and safe next actions.
Governed memory and workspace for any AI: tasks, calendar, mail and pages, with per-action consent.
Give your agents your team's real data — read the shared graph, propose actions your team approves.
Preventive human-approval write-gate for AI agents: writes commit only after a human approves.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceProvides read-only access to Confluence, GitHub, Jira, Figma, Outlook, Teams, and browser automation for AI clients, enabling safe discovery, retrieval, and summarization of company knowledge without modifying source systems.-
- FlicenseNot gradedqualityCmaintenanceEnables controlled AI-agent access to enterprise-shaped tools with a deny-by-default gated write path, human approval, dry-run execution, and append-only audit logging.1-
- AlicenseNot gradedqualityBmaintenanceEnables AI clients to read structured project context and propose task changes that require explicit human approval, with scoped permissions, idempotency, and a full audit trail.MIT
- AlicenseBqualityCmaintenanceEnables AI agents to act on live business objects under enforceable per-call identity, per-tool grants, and mandatory human approval for irreversible actions, with connectors isolated from core logic.8MIT