Skip to content

Commit 1ffe9d3

Browse files
committed
Add recommended security policies for tool-level enforcement
Three YAML policy presets for use with PolicyLayer Intercept, an open-source MCP proxy that adds rate limits, daily caps, and access control on individual tool calls. Complements existing PAT/OAuth/SSO governance with per-tool enforcement — rate limiting writes, blocking destructive ops like delete_file, and capping merges and workflow triggers.
1 parent 95726ad commit 1ffe9d3

File tree

4 files changed

+486
-0
lines changed

4 files changed

+486
-0
lines changed

README.md

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ The remote GitHub MCP Server is hosted by GitHub and provides the easiest method
2626

2727
1. A compatible MCP host with remote server support (VS Code 1.101+, Claude Desktop, Cursor, Windsurf, etc.)
2828
2. Any applicable [policies enabled](https://github.com/github/github-mcp-server/blob/main/docs/policies-and-governance.md)
29+
3. (Optional) [Tool-level policies](#tool-level-policy-enforcement) configured for rate limiting and access control
2930

3031
### Install in VS Code
3132

@@ -1575,3 +1576,50 @@ The exported Go API of this module should currently be considered unstable, and
15751576
## License
15761577

15771578
This project is licensed under the terms of the MIT open source license. Please refer to [MIT](./LICENSE) for the full terms.
1579+
1580+
## Tool-level policy enforcement
1581+
1582+
The [policies and governance](docs/policies-and-governance.md) doc covers access control via PATs, OAuth, and SSO. For tool-level enforcement — rate limiting, daily caps, and blocking specific operations — you can wrap the server with [PolicyLayer Intercept](https://github.com/policylayer/intercept), an open-source MCP proxy.
1583+
1584+
Three policy presets are included in [`/policies`](/policies):
1585+
1586+
| Policy | Description |
1587+
|--------|-------------|
1588+
| `recommended.yaml` | Rate limits on writes, blocks `delete_file`, daily caps on merges and pushes |
1589+
| `strict.yaml` | Default deny — only read tools allowed unless explicitly opted in |
1590+
| `permissive.yaml` | Everything allowed, rate limits on destructive and high-risk operations |
1591+
1592+
### Usage
1593+
1594+
Local server:
1595+
1596+
```sh
1597+
npx -y @policylayer/intercept \
1598+
--policy policies/recommended.yaml \
1599+
-- docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN ghcr.io/github/github-mcp-server
1600+
```
1601+
1602+
Or in your MCP client config:
1603+
1604+
```json
1605+
{
1606+
"mcpServers": {
1607+
"github": {
1608+
"command": "npx",
1609+
"args": [
1610+
"-y", "@policylayer/intercept",
1611+
"--policy", "policies/recommended.yaml",
1612+
"--", "docker", "run", "-i", "--rm",
1613+
"-e", "GITHUB_PERSONAL_ACCESS_TOKEN",
1614+
"ghcr.io/github/github-mcp-server"
1615+
],
1616+
"env": {
1617+
"GITHUB_PERSONAL_ACCESS_TOKEN": "<your-token>"
1618+
}
1619+
}
1620+
}
1621+
}
1622+
```
1623+
1624+
Policies are YAML files you can customise. See the [Intercept docs](https://github.com/policylayer/intercept) for the full reference.
1625+

policies/permissive.yaml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
version: "1"
2+
description: "GitHub MCP — permissive policy. All tools allowed. Rate limits on destructive and high-risk operations."
3+
default: allow
4+
5+
tools:
6+
# Destructive — blocked even in permissive mode
7+
delete_file:
8+
rules:
9+
- action: deny
10+
on_deny: "File deletion blocked by policy"
11+
12+
# High-risk writes — rate limited
13+
merge_pull_request:
14+
rules:
15+
- name: "rate-limit"
16+
rate_limit: "20/hour"
17+
on_deny: "Max 20 merges per hour"
18+
19+
push_files:
20+
rules:
21+
- name: "rate-limit"
22+
rate_limit: "30/hour"
23+
on_deny: "Max 30 pushes per hour"
24+
25+
actions_run_trigger:
26+
rules:
27+
- name: "rate-limit"
28+
rate_limit: "10/hour"
29+
on_deny: "Max 10 workflow triggers per hour"
30+
31+
create_repository:
32+
rules:
33+
- name: "rate-limit"
34+
rate_limit: "10/hour"
35+
on_deny: "Max 10 repository creations per hour"
36+
37+
# Global safety net
38+
"*":
39+
rules:
40+
- name: "global-rate-limit"
41+
rate_limit: "180/minute"
42+
on_deny: "Global rate limit — max 180 tool calls per minute"

policies/recommended.yaml

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
version: "1"
2+
description: "GitHub MCP — recommended policy. Rate limits on writes, blocks destructive ops, reads allowed freely."
3+
default: allow
4+
5+
tools:
6+
# Destructive — blocked entirely
7+
delete_file:
8+
hide: true
9+
rules:
10+
- action: deny
11+
on_deny: "File deletion blocked by policy"
12+
13+
# High-risk writes — tight limits
14+
merge_pull_request:
15+
rules:
16+
- name: "burst-limit"
17+
rate_limit: "2/minute"
18+
on_deny: "Slow down — max 2 merges per minute"
19+
- name: "hourly-cap"
20+
rate_limit: "10/hour"
21+
on_deny: "Hourly merge limit (10) reached"
22+
23+
push_files:
24+
rules:
25+
- name: "burst-limit"
26+
rate_limit: "3/minute"
27+
on_deny: "Slow down — max 3 pushes per minute"
28+
- name: "hourly-cap"
29+
rate_limit: "20/hour"
30+
on_deny: "Hourly push limit (20) reached"
31+
32+
create_or_update_file:
33+
rules:
34+
- name: "rate-limit"
35+
rate_limit: "30/hour"
36+
on_deny: "Max 30 file writes per hour"
37+
38+
# Execution — rate limited
39+
actions_run_trigger:
40+
rules:
41+
- name: "rate-limit"
42+
rate_limit: "5/hour"
43+
on_deny: "Max 5 workflow triggers per hour"
44+
45+
# Repository management — moderate limits
46+
create_repository:
47+
rules:
48+
- name: "rate-limit"
49+
rate_limit: "5/hour"
50+
on_deny: "Max 5 repository creations per hour"
51+
52+
fork_repository:
53+
rules:
54+
- name: "rate-limit"
55+
rate_limit: "5/hour"
56+
on_deny: "Max 5 forks per hour"
57+
58+
# PR and issue writes — reasonable throughput
59+
create_pull_request:
60+
rules:
61+
- name: "rate-limit"
62+
rate_limit: "20/hour"
63+
on_deny: "Max 20 PR creations per hour"
64+
65+
update_pull_request:
66+
rules:
67+
- name: "rate-limit"
68+
rate_limit: "30/hour"
69+
on_deny: "Max 30 PR updates per hour"
70+
71+
update_pull_request_branch:
72+
rules:
73+
- name: "rate-limit"
74+
rate_limit: "20/hour"
75+
on_deny: "Max 20 branch updates per hour"
76+
77+
issue_write:
78+
rules:
79+
- name: "rate-limit"
80+
rate_limit: "30/hour"
81+
on_deny: "Max 30 issue writes per hour"
82+
83+
add_issue_comment:
84+
rules:
85+
- name: "rate-limit"
86+
rate_limit: "30/hour"
87+
on_deny: "Max 30 issue comments per hour"
88+
89+
# Branch creation
90+
create_branch:
91+
rules:
92+
- name: "rate-limit"
93+
rate_limit: "20/hour"
94+
on_deny: "Max 20 branch creations per hour"
95+
96+
# Copilot tools — limited
97+
assign_copilot_to_issue:
98+
rules:
99+
- name: "rate-limit"
100+
rate_limit: "10/hour"
101+
on_deny: "Max 10 Copilot assignments per hour"
102+
103+
request_copilot_review:
104+
rules:
105+
- name: "rate-limit"
106+
rate_limit: "10/hour"
107+
on_deny: "Max 10 Copilot review requests per hour"
108+
109+
create_pull_request_with_copilot:
110+
rules:
111+
- name: "rate-limit"
112+
rate_limit: "10/hour"
113+
on_deny: "Max 10 Copilot PR creations per hour"
114+
115+
# Gist writes
116+
create_gist:
117+
rules:
118+
- name: "rate-limit"
119+
rate_limit: "20/hour"
120+
on_deny: "Max 20 gist creations per hour"
121+
122+
# Global safety net
123+
"*":
124+
rules:
125+
- name: "global-rate-limit"
126+
rate_limit: "120/minute"
127+
on_deny: "Global rate limit — max 120 tool calls per minute"

0 commit comments

Comments
 (0)