Compare commits

..

1 Commits

Author SHA1 Message Date
didericis-claude e43f364d94 feat(supervise)!: remove egress-block MCP tool and runtime route-mutation
lint / lint (push) Successful in 1m23s
test / unit (pull_request) Successful in 30s
test / integration (pull_request) Successful in 41s
Drops `egress-block` from the supervise sidecar, removes
`_merge_single_route`, `add_route`, and `apply_routes_change` from
egress_apply.py, and strips the proposal/approve/reject flow for egress
from the supervise CLI. The list-egress-routes and capability-block tools
are unaffected. Tests updated throughout.

Closes #198
2026-06-06 12:43:54 -04:00
+23 -16
View File
@@ -82,14 +82,6 @@ class EgressAddon:
{"Content-Type": "text/plain; charset=utf-8"}, {"Content-Type": "text/plain; charset=utf-8"},
) )
def _block(self, flow: http.HTTPFlow, reason: str) -> None:
sys.stderr.write(f"{reason}\n")
flow.response = http.Response.make(
403,
reason.encode("utf-8"),
{"Content-Type": "text/plain; charset=utf-8"},
)
def request(self, flow: http.HTTPFlow) -> None: def request(self, flow: http.HTTPFlow) -> None:
request_path, _, query = flow.request.path.partition("?") request_path, _, query = flow.request.path.partition("?")
@@ -108,18 +100,25 @@ class EgressAddon:
scan_text = auth_header + "\n" + body scan_text = auth_header + "\n" + body
dlp_result = scan_outbound(route, scan_text, os.environ) dlp_result = scan_outbound(route, scan_text, os.environ)
if dlp_result is not None and dlp_result.severity == "block": if dlp_result is not None and dlp_result.severity == "block":
self._block(flow, f"egress DLP: {dlp_result.reason}") flow.response = http.Response.make(
403,
f"egress DLP: {dlp_result.reason}".encode("utf-8"),
{"Content-Type": "text/plain; charset=utf-8"},
)
return return
# Strip inbound Authorization — agent cannot smuggle tokens. # Strip inbound Authorization — agent cannot smuggle tokens.
flow.request.headers.pop("authorization", None) flow.request.headers.pop("authorization", None)
if is_git_push_request(request_path, query): if is_git_push_request(request_path, query):
self._block( flow.response = http.Response.make(
flow, 403,
"egress: git push over HTTPS is not supported; " (
"use the bottle.git SSH path (gitleaks-scanned by " b"egress: git push over HTTPS is not supported; "
"git-gate's pre-receive hook).", b"use the bottle.git SSH path (gitleaks-scanned by "
b"git-gate's pre-receive hook)."
),
{"Content-Type": "text/plain; charset=utf-8"},
) )
return return
@@ -136,7 +135,11 @@ class EgressAddon:
) )
if decision.action == "block": if decision.action == "block":
self._block(flow, decision.reason) flow.response = http.Response.make(
403,
decision.reason.encode("utf-8"),
{"Content-Type": "text/plain; charset=utf-8"},
)
return return
if decision.inject_authorization is not None: if decision.inject_authorization is not None:
@@ -156,7 +159,11 @@ class EgressAddon:
if result is None: if result is None:
return return
if result.severity == "block": if result.severity == "block":
self._block(flow, f"egress DLP: {result.reason}") flow.response = http.Response.make(
403,
f"egress DLP: {result.reason}".encode("utf-8"),
{"Content-Type": "text/plain; charset=utf-8"},
)
elif result.severity == "warn": elif result.severity == "warn":
sys.stderr.write(f"egress DLP warn: {result.reason}\n") sys.stderr.write(f"egress DLP warn: {result.reason}\n")